PR96463: Optimise svld1rq from vectors for little endian AArch64 targets.
[official-gcc.git] / gcc / config / csky / csky.md
blob6b05930a9fbaa2fa90ab4ed1c8a5cbc47aed69e0
1 ;; Machine description for C-SKY processors.
2 ;; Copyright (C) 2018-2022 Free Software Foundation, Inc.
3 ;; Contributed by C-SKY Microsystems and Mentor Graphics.
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 by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
12 ;; GCC is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 ;; General Public 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 ;; ------------------------------------------------------------------------
23 ;; Constant
24 ;; ------------------------------------------------------------------------
26 ;; Register numbering.
28 (define_constants
29   [(CSKY_NGPR_REGS                      32)
30    (CSKY_NPARM_REGS                     4)
31    (CSKY_FIRST_PARM_REGNUM              0)
32    (CSKY_FIRST_RET_REGNUM               0)
33    (CSKY_FIRST_VFP_REGNUM               52)
34    (CSKY_LAST_VFP_REGNUM                67)
35    (CSKY_FIRST_VFP3_REGNUM              71)
36    (CSKY_LAST_VFP3_REGNUM               86)
37    (CSKY_FIRST_HIGH_REGNUM              16)
38    (CSKY_LAST_HIGH_REGNUM               31)
39    (CSKY_FIRST_MINI_REGNUM              0)
40    (CSKY_LAST_MINI_REGNUM               7)
41    (CSKY_T0_REGNUM                      12)
42    (CSKY_T1_REGNUM                      13)
43    (CSKY_SP_REGNUM                      14)
44    (CSKY_CC_REGNUM                      33)
45    (CSKY_HI_REGNUM                      34)
46    (CSKY_LO_REGNUM                      35)
47    (CSKY_LR_REGNUM                      15)
48    (CSKY_LAST_HIGH_UNFIXED_REGNUM       25)
49    (CSKY_GB_REGNUM                      28)
50    (CSKY_TLS_REGNUM                     31)
51    (CSKY_FIRST_EH_RETDATA_REGNUM        0)
52    (CSKY_LAST_EH_RETDATA_REGNUM         1)
53    (CSKY_EH_STACKADJ_REGNUM             2)
54    (CSKY_STACKADJUST_REGNUM             4)
55    (CSKY_NPARM_FREGS 4)
58 ;; Supported TLS relocations.
60 (define_constants
61   [(TLS_GD32               0)
62    (TLS_LDM32              1)
63    (TLS_LDO32              2)
64    (TLS_IE32               3)
65    (TLS_LE32               4)
68 ;; Unspec constants.
70 (define_c_enum "unspec"
71   [
72    ; Push or pop multiple operation: operand 0 is the first register,
73    ; subsequent registers are in parallel (use ...) expressions.
74    UNSPEC_PUSHPOP_MULT
76    ; Represent TLS base, TLS offset, and TLS base + offset, respectively.
77    UNSPEC_TLS_BASE
78    UNSPEC_TLS_LABEL
79    UNSPEC_TLS
81    ; PIC symbol relocations.
82    UNSPEC_PIC_SYMBOL_GOTPC
83    UNSPEC_PIC_SYMBOL_GOTPC_GRS
84    UNSPEC_PIC_SYMBOL_GOTOFF
85    UNSPEC_PIC_SYMBOL_GOT
86    UNSPEC_PIC_SYMBOL_PLT
87    UNSPEC_PIC_SYMBOL_BSR
88    UNSPEC_PIC_SYMBOL_GRS
90    ; casesi dispatch table.
91    UNSPEC_CSKY_CASESI
92   ])
95 (define_c_enum "unspecv"
96   [
97    ; Used for constant pools.
98    VUNSPEC_ALIGN
99    VUNSPEC_POOL_LABEL
100    VUNSPEC_POOL_4
101    VUNSPEC_POOL_8
102    VUNSPEC_SYMBOL_REF
104    ; Support for the eh_return pattern.
105    VUNSPEC_EH_RETURN
106    VUNSPEC_BLOCKAGE
107   ])
110 ;; ------------------------------------------------------------------------
111 ;; Attributes
112 ;; ------------------------------------------------------------------------
114 ;; LENGTH of an instruction (in bytes).
116 (define_attr "length" ""
117   (if_then_else (match_test "CSKY_TARGET_ARCH (CK801)")
118     (const_int 2)
119     (const_int 4)))
121 ;; Used for ck801 to represent whether we need to use bsr for long
122 ;; distance jumps.  If set to yes, the function will save lr in the
123 ;; prologue.
125 (define_attr "far_jump" "yes,no" (const_string "no"))
127 ;; Used for insn schedule.
129 (define_attr "type"
130     "alu,load,store,cmp,branch,cbranch,addsub,alu_ix,branch_jmp,call_jsr,call"
131     (const_string "alu"))
134 ;; ------------------------------------------------------------------------
135 ;; Include files
136 ;; ------------------------------------------------------------------------
138 (include "constraints.md")
139 (include "predicates.md")
140 (include "csky_insn_fpu.md")
141 (include "csky_insn_dsp.md")
142 (include "csky_pipeline_ck801.md")
143 (include "csky_pipeline_ck802.md")
144 (include "csky_pipeline_ck803.md")
145 (include "csky_pipeline_ck810.md")
147 ;; ------------------------------------------------------------------------
148 ;; Mov insns
149 ;; ------------------------------------------------------------------------
151 (define_mode_iterator QHI [QI HI])
153 (define_expand "movsi"
154   [(set (match_operand:SI 0 "general_operand" "")
155         (match_operand:SI 1 "general_operand" ""))]
156   ""
157   "
158   {
159     rtx scratch = !can_create_pseudo_p () ? operands[0] : 0;
160     if (can_create_pseudo_p () && MEM_P (operands[0]))
161       {
162         operands[1] = force_reg (SImode, operands[1]);
163         emit_insn (gen_rtx_SET (operands[0], operands[1]));
164         DONE;
165       }
167     /* Recognize the case where operand[1] is a reference to thread-local
168        data and load its address to a register.  */
169     if (csky_tls_referenced_p (operands[1]))
170       {
171         rtx tmp = operands[1];
172         rtx addend = NULL;
174         if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
175           {
176             addend = XEXP (XEXP (tmp, 0), 1);
177             tmp = XEXP (XEXP (tmp, 0), 0);
178           }
180         gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
181         gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0);
183         tmp = csky_legitimize_tls_address (tmp, scratch);
184         if (addend)
185           {
186             tmp = gen_rtx_PLUS (SImode, tmp, addend);
187             tmp = force_operand (tmp, operands[0]);
188           }
189         operands[1] = tmp;
190       }
191     else if (flag_pic
192              && (CONSTANT_P (operands[1])
193                  || csky_symbol_mentioned_p (operands[1])
194                  || csky_label_mentioned_p (operands[1])))
195         operands[1] = csky_legitimize_pic_address (operands[1], scratch, true);
196   }"
199 ;; Note that we conservatively estimate all load and store insns as having
200 ;; a size of 4 bytes throughout even though some variants can be encoded
201 ;; as 2-byte machine instructions.  Getting more accurate instruction counts
202 ;; would be better handled by calling into a C function than encoding it
203 ;; as an RTL conditional here.
204 ;; Also note that we don't count the extra space required for constant
205 ;; pool entries here; that's handled by the constant pool entries themselves.
206 ;; In -mno-constpool cases where we're relying on the assembler to create
207 ;; the constant pool, we'll undercount branch lengths, but in that case the
208 ;; assembler also handles branch relaxation as needed.  It's only ck801 that
209 ;; requires compiler cooperation when long branches are needed.
211 (define_insn "*cskyv2_movsi"
212   [(set (match_operand:SI 0 "nonimmediate_operand"  "=b,r,r,r, r, r, r,r,  m,r,*y,*r,*v,*r,*v")
213         (match_operand:SI 1 "general_operand"       " b,r,I,Un,Uc,Uo,m,miF,r,c,*r,*y,*r,*v,*v"))]
214   "CSKY_ISA_FEATURE (E2)"
215   "* return csky_output_move (insn, operands, SImode);"
216   [(set_attr "length" "2,4,4,4,4,8,4,4,4,4,4,4,4,4,4")
217    (set_attr "type" "alu,alu,alu,alu,alu,alu,load,load,store,alu,alu,alu,alu,alu,alu")]
220 (define_insn "*ck801_movsi"
221   [(set (match_operand:SI 0 "nonimmediate_operand"   "=r,a, a,r,r,  m,r")
222         (match_operand:SI 1 "general_operand"        "r, Up,T,m,miF,r,c"))]
223   "CSKY_ISA_FEATURE (E1)"
224   "* return csky_output_ck801_move (insn, operands, SImode);"
225   [(set_attr "length" "2,2,2,4,4,4,2")
226    (set_attr "type" "alu,alu,alu,load,load,store,alu")]
229 ;; Convert negative assignments to zero minus positive numbers.
230 (define_split
231   [(set (match_operand:SI 0 "register_operand" "")
232         (match_operand:SI 1 "const_int_operand" ""))]
233     "satisfies_constraint_T (operands[1])"
234     [(set (match_dup 0) (match_dup 2))
235      (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
236     "operands[2] = const0_rtx;"
239 ;; Convert const assignments to small number of assignments and left shift.
240 (define_split
241   [(set (match_operand:SI 0 "register_operand" "")
242         (match_operand:SI 1 "const_int_operand" ""))]
243   ""
244   [(set (match_dup 0) (match_dup 1))
245    (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))]
246   "
247   {
248     unsigned int base, shift;
250     if (!csky_shifted_imm8_constant (INTVAL (operands[1]), &base, &shift))
251       FAIL;
252     if (shift == 0)
253       FAIL;
254     operands[1] = GEN_INT (base);
255     operands[2] = GEN_INT (shift);
256   }"
260 (define_expand "movhi"
261   [(set (match_operand:HI 0 "general_operand" "")
262         (match_operand:HI 1 "general_operand"  ""))]
263   ""
264   "
265   {
266     if (GET_CODE (operands[0]) == MEM)
267         operands[1] = force_reg (HImode, operands[1]);
268     else if (CONSTANT_P (operands[1])
269              && (GET_CODE (operands[1]) != CONST_INT
270                  || (! CSKY_CONST_OK_FOR_I (INTVAL (operands[1]))
271                      && ! CSKY_CONST_OK_FOR_Ub (INTVAL (operands[1]))
272                      && ! CSKY_CONST_OK_FOR_Uc (INTVAL (operands[1]))))
273              && ! reload_completed && ! reload_in_progress)
274       {
275         rtx reg = gen_reg_rtx (SImode);
276         emit_insn (gen_movsi (reg, operands[1]));
277         operands[1] = gen_lowpart (HImode, reg);
278       }
279   }"
282 (define_insn "*cskyv2_movhi"
283   [(set (match_operand:HI 0 "nonimmediate_operand"  "=b,r,r,r, r, r, r,r,  m,r,*y,*r,*v,*r,*v")
284         (match_operand:HI 1 "general_operand"       " b,r,I,Un,Uc,Uo,m,miF,r,c,*r,*y,*r,*v,*v"))]
285   "CSKY_ISA_FEATURE (E2)"
286   "* return csky_output_move (insn, operands, HImode);"
287   [(set_attr "length" "2,4,4,4,4,8,4,4,4,4,4,4,4,4,4")
288    (set_attr "type" "alu,alu,alu,alu,alu,alu,load,load,store,alu,alu,alu,alu,alu,alu")]
291 (define_insn "*ck801_movhi"
292   [(set (match_operand:HI 0 "nonimmediate_operand"   "=r,a, a,r,r,  m,r")
293         (match_operand:HI 1 "general_operand"        "r, Up,T,m,miF,r,c"))]
294   "CSKY_ISA_FEATURE (E1)"
295   "* return csky_output_ck801_move (insn, operands, HImode);"
296   [(set_attr "length" "2,2,2,4,4,4,2")
297    (set_attr "type" "alu,alu,alu,load,load,store,alu")]
301 (define_expand "movqi"
302   [(set (match_operand:QI 0 "general_operand" "")
303         (match_operand:QI 1 "general_operand"  ""))]
304   ""
305   "
306   {
307     if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM)
308         operands[1] = force_reg (QImode, operands[1]);
309     else if (CONSTANT_P (operands[1])
310              && (GET_CODE (operands[1]) != CONST_INT
311                  || (! CSKY_CONST_OK_FOR_I (INTVAL (operands[1]))
312                      && ! CSKY_CONST_OK_FOR_Ub (INTVAL (operands[1]))
313                      && ! CSKY_CONST_OK_FOR_Uc (INTVAL (operands[1]))))
314              && ! reload_completed && ! reload_in_progress)
315       {
316         rtx reg = gen_reg_rtx (SImode);
317         emit_insn (gen_movsi (reg, operands[1]));
318         operands[1] = gen_lowpart (QImode, reg);
319       }
320   }"
323 (define_insn "*cskyv2_movqi"
324   [(set (match_operand:QI 0 "nonimmediate_operand"  "=b,r,r,r, r, r, r,r,  m,r,*y,*r,*v,*r,*v")
325         (match_operand:QI 1 "general_operand"       " b,r,I,Un,Uc,Uo,m,miF,r,c,*r,*y,*r,*v,*v"))]
326   "CSKY_ISA_FEATURE (E2)"
327   "* return csky_output_move (insn, operands, QImode);"
328   [(set_attr "length" "2,4,4,4,4,8,4,4,4,4,4,4,4,4,4")
329    (set_attr "type" "alu,alu,alu,alu,alu,alu,load,load,store,alu,alu,alu,alu,alu,alu")]
332 (define_insn "*ck801_movqi"
333   [(set (match_operand:QI 0 "nonimmediate_operand"   "=r,a, a,r,r,  m,r")
334         (match_operand:QI 1 "general_operand"        "r, Up,T,m,miF,r,c"))]
335   "CSKY_ISA_FEATURE (E1)"
336   "* return csky_output_ck801_move (insn, operands, QImode);"
337   [(set_attr "length" "2,2,2,4,4,4,2")
338    (set_attr "type" "alu,alu,alu,load,load,store,alu")]
342 (define_expand "movdi"
343   [(set (match_operand:DI 0 "general_operand" "")
344         (match_operand:DI 1 "general_operand" ""))]
345   ""
346   "if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM)
347       operands[1] = force_reg (DImode, operands[1]);"
350 ;; Convert negative assignments to zero minus positive numbers.
351 (define_split
352   [(set (match_operand:QHI 0 "register_operand" "")
353         (match_operand:QHI 1 "const_int_operand" ""))]
354   "satisfies_constraint_T (operands[1])"
355   [(set (match_dup 4) (match_dup 2))
356    (set (match_dup 4) (match_dup 3))
357    (set (match_dup 0) (match_dup 5))]
358   "
359   {
360     int low;
362     if (TARGET_BIG_ENDIAN)
363       low = 4 - mode_size[GET_MODE (operands[0])];
364     else
365       low = 0;
366     operands[2] = const0_rtx;
367     if (can_create_pseudo_p ())
368       operands[4] = gen_reg_rtx (SImode);
369     else
370       operands[4] = gen_rtx_REG (SImode, REGNO (operands[0]));
371     operands[3] = gen_rtx_PLUS (SImode, operands[4], operands[1]);
372     operands[5] = gen_rtx_SUBREG (GET_MODE (operands[0]), operands[4], low);
373   }"
376 ;; Convert const assignments to small number of assignments and left shift.
377 (define_split
378   [(set (match_operand:QHI 0 "register_operand" "")
379         (match_operand:QHI 1 "const_int_operand" ""))]
380   ""
381   [(set (match_dup 3) (match_dup 1))
382    (set (match_dup 3) (ashift:SI (match_dup 3) (match_dup 2)))
383    (set (match_dup 0) (match_dup 4))]
384   "
385   {
386     unsigned int base, shift;
387     int low;
389     if (!csky_shifted_imm8_constant (INTVAL (operands[1]), &base, &shift))
390       FAIL;
391     if (shift == 0)
392       FAIL;
394     if (TARGET_BIG_ENDIAN)
395       low = 4 - mode_size[GET_MODE (operands[0])];
396     else
397       low = 0;
399     operands[1] = GEN_INT (base);
400     operands[2] = GEN_INT (shift);
401     if (can_create_pseudo_p ())
402       operands[3] = gen_reg_rtx (SImode);
403     else
404       operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
405     operands[4] = gen_rtx_SUBREG (GET_MODE (operands[0]), operands[3], low);
406   }"
410 (define_insn "*csky_movdi"
411   [(set (match_operand:DI 0 "nonimmediate_operand"  "=b,r,r, r,r,  m,*r,*y,*v,*r,*v")
412         (match_operand:DI 1 "general_operand"       " b,r,Ud,m,miF,r,*y,*r,*r,*v,*v"))]
413  "CSKY_ISA_FEATURE (E2)"
414  "* return csky_output_movedouble (operands, DImode);"
415  [(set_attr "length" "4,8,8,8,8,8,16,16,16,16,16")
416   (set_attr "type" "alu,alu,alu,load,load,store,alu,alu,alu,alu,alu")]
419 (define_insn "*ck801_movdi"
420   [(set (match_operand:DI 0 "nonimmediate_operand"  "=r,a, a,r,r,  m")
421         (match_operand:DI 1 "general_operand"       "r, Up,T,m,miF,r"))]
422   "CSKY_ISA_FEATURE (E1)"
423   "* return csky_output_ck801_movedouble (operands, DImode);"
424   [(set_attr "length" "4,4,4,8,8,8")
425    (set_attr "type" "alu,alu,alu,load,load,store")]
428 ;; The only CCmode move supported is a nop.  Without this pattern,
429 ;; CSE is unable to eliminate redundant comparisons in conditional
430 ;; execution expressions.
432 (define_insn "*movcc_nop"
433   [(set (reg:CC CSKY_CC_REGNUM) (reg:CC CSKY_CC_REGNUM))]
434   ""
435   ""
436   [(set_attr "length" "0")]
439 ;; ------------------------------------------------------------------------
440 ;; Conditional mov insns
441 ;; ------------------------------------------------------------------------
443 ;; Only handle integer comparisons because float and double require
444 ;; library calls.
446 (define_expand "movsicc"
447   [(set (match_operand 0 "register_operand" "")
448         (if_then_else:SI (match_operand    1 "comparison_operator" "")
449                          (match_operand:SI 2 "register_operand" "")
450                          (match_operand:SI 3 "register_operand" "")))]
451   "CSKY_ISA_FEATURE (E2)"
452   "
453   {
454     bool invert = csky_emit_compare (GET_CODE (operands[1]),
455                                      XEXP (operands[1], 0),
456                                      XEXP (operands[1], 1));
458     if (invert)
459       emit_insn (gen_movf (operands[0], operands[2], operands[3]));
460     else
461       emit_insn (gen_movt (operands[0], operands[2], operands[3]));
462     DONE;
463   }")
465 (define_insn "movt"
466   [(set (match_operand:SI 0 "register_operand" "=r, r")
467         (if_then_else:SI (ne (reg:CC CSKY_CC_REGNUM) (const_int 0))
468                          (match_operand:SI 1 "register_operand" "r, 0")
469                          (match_operand:SI 2 "register_operand" "0, r")))]
470   "CSKY_ISA_FEATURE (E2)"
471   "@
472     movt\t%0, %1
473     movf\t%0, %2"
474   [(set_attr "length" "4,4")]
477 (define_insn "movf"
478   [(set (match_operand:SI 0 "register_operand" "=r, r")
479         (if_then_else:SI (eq (reg:CC CSKY_CC_REGNUM) (const_int 0))
480                          (match_operand:SI 1 "register_operand" "r, 0")
481                          (match_operand:SI 2 "register_operand" "0, r")))]
482   "CSKY_ISA_FEATURE (E2)"
483   "@
484     movf\t%0, %1
485     movt\t%0, %2"
486   [(set_attr "length" "4,4")]
489 (define_expand "cstoresi4"
490   [(set (match_operand:SI 0 "register_operand" "")
491         (match_operator   1 "ordered_comparison_operator"
492           [(match_operand:SI 2 "csky_compare_operand" "")
493            (match_operand:SI 3 "nonmemory_operand" "")]))]
494   ""
495   "
496   {
497     bool invert = csky_emit_compare (GET_CODE (operands[1]),
498                                      operands[2], operands[3]);
500     if (invert)
501       emit_insn (gen_mvcv (operands[0]));
502     else if (CSKY_ISA_FEATURE (E1))
503       {
504         emit_insn (gen_movsi (operands[0], const0_rtx));
505         emit_insn (gen_ck801_addc (operands[0], operands[0], operands[0]));
506       }
507     else
508       emit_insn (gen_mvc (operands[0]));
509     DONE;
510   }"
513 (define_insn "mvc"
514   [(set (match_operand:SI 0 "register_operand" "=r")
515         (ne:SI (reg:CC CSKY_CC_REGNUM) (const_int 0)))]
516   "CSKY_ISA_FEATURE (E2)"
517   "mvc\t%0"
520 (define_insn "mvcv"
521   [(set (match_operand:SI 0 "register_operand" "=r")
522         (eq:SI (reg:CC CSKY_CC_REGNUM) (const_int 0)))]
523   ""
524   "mvcv\t%0"
527 ;; ------------------------------------------------------------------------
528 ;; Arithmetic insns
529 ;; ------------------------------------------------------------------------
531 (define_insn "abssi2"
532   [(set (match_operand:SI         0 "register_operand" "=r")
533         (abs:SI (match_operand:SI 1 "register_operand" "r")))]
534   "CSKY_ISA_FEATURE (2E3)"
535   "abs\t%0, %1"
536   [(set_attr "type" "alu")]
539 (define_insn "extvsi"
540   [(set (match_operand:SI                  0 "register_operand" "=r")
541         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
542                          (match_operand:SI 2 "const_int_operand" "")
543                          (match_operand:SI 3 "const_int_operand" "")))]
544   "CSKY_ISA_FEATURE (2E3)"
545   {
546     operands[2] = GEN_INT (INTVAL (operands[3]) + INTVAL (operands[2]) - 1);
547     return \"sext\t%0, %1, %2, %3\";
548   }
551 (define_insn "insvsi"
552   [(set (zero_extract:SI (match_operand:SI 0 "register_operand"  "+r")
553                          (match_operand:SI 1 "const_int_operand" "i")
554                          (match_operand:SI 2 "const_int_operand" "i"))
555         (match_operand:SI                  3 "register_operand"  "r"))]
556   "CSKY_ISA_FEATURE (2E3)"
557   {
558     operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1]) - 1);
559     return \"ins\t%0, %3, %1, %2\";
560   }
563 (define_expand "bseti"
564   [(set (match_operand:SI 0 "register_operand"  "")
565         (ior:SI (match_operand:SI 1 "register_operand"  "")
566                 (ashift:SI (const_int 1)
567                            (match_operand:SI 2 "csky_literal_K_operand" ""))))]
568   ""
569   "")
571 (define_insn "smart_bseti"
572   [(set (match_operand:SI 0 "register_operand"  "=r")
573         (ior:SI (match_operand:SI 1 "register_operand"  "0")
574                 (ashift:SI (const_int 1)
575                            (match_operand:SI 2 "csky_literal_K_operand" "K"))))]
576   "TARGET_MINI_REGISTERS"
577   "bseti\t%0, %2"
578   [(set_attr "length" "2")])
580 (define_insn "fast_bseti"
581   [(set (match_operand:SI 0 "register_operand"  "=a,r")
582         (ior:SI (match_operand:SI 1 "register_operand"  "0,r")
583                 (ashift:SI (const_int 1)
584                            (match_operand:SI 2 "csky_literal_K_operand" "K,K"))))]
585   "!TARGET_MINI_REGISTERS"
586   "bseti\t%0, %1, %2"
587   [(set_attr "length" "2,4")])
589 (define_expand "bclri"
590   [(set (match_operand:SI 0 "register_operand"  "")
591         (and:SI (match_operand:SI 1 "register_operand"  "")
592                 (not:SI (ashift:SI (const_int 1)
593                                    (match_operand:SI 2 "csky_literal_K_operand" "")))))]
594   ""
595   "")
597 (define_insn "smart_bclri"
598   [(set (match_operand:SI 0 "register_operand"  "=r")
599         (and:SI (match_operand:SI 1 "register_operand"  "0")
600                 (not:SI (ashift:SI (const_int 1)
601                                    (match_operand:SI 2 "csky_literal_K_operand" "K")))))]
602   "TARGET_MINI_REGISTERS"
603   "bclri\t%0, %2"
604   [(set_attr "length" "2")])
606 (define_insn "fast_bclri"
607   [(set (match_operand:SI 0 "register_operand"  "=a,r")
608         (and:SI (match_operand:SI 1 "register_operand"  "0,r")
609                 (not:SI (ashift:SI (const_int 1)
610                                    (match_operand:SI 2 "csky_literal_K_operand" "K,K")))))]
611   "!TARGET_MINI_REGISTERS"
612   "bclri\t%0, %1, %2"
613   [(set_attr "length" "2,4")])
616 ;; Shift instructions.
618 (define_expand "ashlsi3"
619   [(set (match_operand:SI            0 "register_operand"     "")
620         (ashift:SI (match_operand:SI 1 "register_operand"     "")
621                    (match_operand:SI 2 "csky_arith_K_operand" "")))]
622   ""
623   ""
626 (define_insn "*cskyv2_ashlsi3"
627   [(set (match_operand:SI            0 "register_operand"     "=b,r,a,r")
628         (ashift:SI (match_operand:SI 1 "register_operand"     "0,r,a,r")
629                    (match_operand:SI 2 "csky_arith_K_operand" "b,r,K,K")))]
630   "CSKY_ISA_FEATURE (E2)"
631   "@
632   lsl  %0, %1, %2
633   lsl  %0, %1, %2
634   lsli %0, %1, %2
635   lsli %0, %1, %2"
636   [(set_attr "length" "2,4,2,4")]
639 (define_insn "ck801_ashlsi3"
640   [(set (match_operand:SI            0 "register_operand"     "=a,r")
641         (ashift:SI (match_operand:SI 1 "register_operand"     "a,0")
642                    (match_operand:SI 2 "csky_arith_K_operand" "K,r")))]
643   "CSKY_ISA_FEATURE (E1)"
644   "@
645   lsli %0, %1, %2
646   lsl  %0, %1, %2"
650 (define_expand "ashrsi3"
651   [(set (match_operand:SI              0 "register_operand"     "")
652         (ashiftrt:SI (match_operand:SI 1 "register_operand"     "")
653                      (match_operand:SI 2 "csky_arith_K_operand" "")))]
654   ""
655   ""
658 (define_insn "*cskyv2_ashrsi3"
659   [(set (match_operand:SI              0 "register_operand"     "=b,r,a,r")
660         (ashiftrt:SI (match_operand:SI 1 "register_operand"     "0,r,a,r")
661                      (match_operand:SI 2 "csky_arith_K_operand" "b,r,K,K")))]
662   "CSKY_ISA_FEATURE (E2)"
663   "@
664   asr  %0, %1, %2
665   asr  %0, %1, %2
666   asri %0, %1, %2
667   asri %0, %1, %2"
668   [(set_attr "length" "2,4,2,4")]
671 (define_insn "*ck801_ashrsi3"
672   [(set (match_operand:SI              0 "register_operand"     "=a,r")
673         (ashiftrt:SI (match_operand:SI 1 "register_operand"     "a,0")
674                      (match_operand:SI 2 "csky_arith_K_operand" "K,r")))]
675   "CSKY_ISA_FEATURE (E1)"
676   "@
677   asri %0, %1, %2
678   asr  %0, %1, %2"
682 (define_expand "lshrsi3"
683   [(set (match_operand:SI              0 "register_operand"     "")
684         (lshiftrt:SI (match_operand:SI 1 "register_operand"     "")
685                      (match_operand:SI 2 "csky_arith_K_operand" "")))]
686   ""
687   ""
690 (define_insn "*cskyv2_lshrsi3"
691   [(set (match_operand:SI              0 "register_operand"     "=b,r,a,r")
692         (lshiftrt:SI (match_operand:SI 1 "register_operand"     "0,r,a,r")
693                      (match_operand:SI 2 "csky_arith_K_operand" "b,r,K,K")))]
694   "CSKY_ISA_FEATURE (E2)"
695   "@
696   lsr  %0, %1, %2
697   lsr  %0, %1, %2
698   lsri %0, %1, %2
699   lsri %0, %1, %2"
700   [(set_attr "length" "2,4,2,4")]
703 (define_insn "ck801_lshrsi3"
704   [(set (match_operand:SI              0 "register_operand"     "=a,r")
705         (lshiftrt:SI (match_operand:SI 1 "register_operand"     "a,0")
706                      (match_operand:SI 2 "csky_arith_K_operand" "K,r")))]
707   "CSKY_ISA_FEATURE (E1)"
708   "@
709   lsri %0, %1, %2
710   lsr  %0, %1, %2"
714 (define_expand "rotlsi3"
715   [(set (match_operand:SI            0 "register_operand"     "")
716         (rotate:SI (match_operand:SI 1 "register_operand"     "")
717                    (match_operand:SI 2 "csky_arith_K_operand" "")))]
718   ""
719   ""
722 (define_insn "*cskyv2_rotlsi3"
723   [(set (match_operand:SI            0 "register_operand"     "=b,r,r")
724         (rotate:SI (match_operand:SI 1 "register_operand"     "0,r,r")
725                    (match_operand:SI 2 "csky_arith_K_operand" "b,r,K")))]
726   "CSKY_ISA_FEATURE (E2)"
727   "@
728   rotl  %0, %1, %2
729   rotl  %0, %1, %2
730   rotli %0, %1, %2"
731   [(set_attr "length" "2,4,4")]
734 (define_insn "*ck801_rotlsi3"
735   [(set (match_operand:SI            0 "register_operand"     "=r")
736         (rotate:SI (match_operand:SI 1 "register_operand"     "0")
737                    (match_operand:SI 2 "csky_arith_K_operand" "r")))]
738   "CSKY_ISA_FEATURE (E1)"
739   "rotl %0, %1, %2"
743 ;; Add instructions.
744 ;; C-SKY addi and subi machine instructions only accept positive immediate
745 ;; values, so we have to special case immediates <= 0 in these patterns.
747 (define_expand "addsi3"
748   [(set (match_operand:SI          0 "register_operand" "")
749         (plus:SI (match_operand:SI 1 "register_operand" "")
750                  (match_operand:SI 2 "nonmemory_operand" "")))]
751   ""
752   ""
755 (define_insn "smart_addsi3"
756  [(set (match_operand:SI          0 "register_operand"  "=a,r,a,a,a,a, r,r")
757        (plus:SI (match_operand:SI 1 "register_operand"  "%a,0,0,a,0,a, r,r")
758                 (match_operand:SI 2 "nonmemory_operand" "a, r,N,L,T,Us,M,Um")))]
759  "TARGET_MINI_REGISTERS && CSKY_ISA_FEATURE (E2)
760   && operands[0] != stack_pointer_rtx
761   && operands[1] != stack_pointer_rtx"
762  "@
763      addu\t%0, %1, %2
764      addu\t%0, %1, %2
765      addi\t%0, %1, %2
766      addi\t%0, %1, %2
767      subi\t%0, %1, %M2
768      subi\t%0, %1, %M2
769      addi\t%0, %1, %2
770      subi\t%0, %1, %M2"
771   [(set_attr "length" "2,2,2,2,2,2,4,4")
772    (set_attr "type" "addsub")]
775 (define_insn_and_split "*smart_addsi3_sp"
776   [(set (match_operand:SI          0 "register_operand"  "=z,z, z,a,&a,z,a,r")
777         (plus:SI (match_operand:SI 1 "register_operand"  "0, 0, 0,z, z,a,z,r")
778                  (match_operand:SI 2 "nonmemory_operand" "P, Ug,r,Uq,i,a,a,M")))]
779   "TARGET_MINI_REGISTERS && CSKY_ISA_FEATURE (E2)
780     && (operands[0] == stack_pointer_rtx || operands[1] == stack_pointer_rtx)"
781   "@
782      addi\t%0, %1, %2
783      subi\t%0, %1, %M2
784      addu\t%0, %1, %2
785      addi\t%0, %1, %2
786      #
787      addu\t%0, %1, %2
788      addu\t%0, %1, %2
789      addi\t%0, %1, %2"
790   "(operands[0] != stack_pointer_rtx
791     && operands[1] == stack_pointer_rtx
792     && !satisfies_constraint_Uq (operands[2]))"
793   [(set (match_dup 0)
794         (plus:SI (match_dup 1) (match_dup 0)))]
795   "emit_move_insn (operands[0], operands[2]);"
796   [(set_attr "type" "addsub")]
799 (define_insn "*ck801_addsi3"
800   [(set (match_operand:SI          0 "register_operand"  "=r,a,a,a,a,a, !z,!z,!z,a")
801         (plus:SI (match_operand:SI 1 "register_operand"  "%0,a,0,a,0,a, 0, 0, 0, !z")
802                  (match_operand:SI 2 "nonmemory_operand" "r, a,N,L,T,Us,P, Ug,r, Uq")))]
803   "CSKY_ISA_FEATURE (E1)"
804   "@
805     addu\t%0, %1, %2
806     addu\t%0, %1, %2
807     addi\t%0, %1, %2
808     addi\t%0, %1, %2
809     subi\t%0, %1, %M2
810     subi\t%0, %1, %M2
811     addi\t%0, %1, %2
812     subi\t%0, %1, %M2
813     addu\t%0, %1, %2
814     addi\t%0, %1, %2"
815   [(set_attr "type" "addsub")]
818 (define_insn "fast_addsi3"
819   [(set (match_operand:SI          0 "register_operand"  "=r,r, r")
820         (plus:SI (match_operand:SI 1 "register_operand"  "%r,r, r")
821                  (match_operand:SI 2 "nonmemory_operand" "M, Um,r")))]
822   "!TARGET_MINI_REGISTERS && CSKY_ISA_FEATURE (E2)"
823   "@
824     addi\t%0, %1, %2
825     subi\t%0, %1, %M2
826     addu\t%0, %1, %2"
827   [(set_attr "type" "addsub")]
830 (define_expand "adddi3"
831   [(parallel [(set (match_operand:DI 0 "register_operand" "")
832                    (plus:DI (match_operand:DI 1 "register_operand" "")
833                             (match_operand:DI 2 "csky_arith_int1_operand" "")))
834               (clobber (reg:CC CSKY_CC_REGNUM))])]
835   ""
836   "
837   if (CSKY_ISA_FEATURE (E1) && (GET_CODE (operands[2]) != REG))
838       operands[2] = force_reg (DImode, operands[2]);
839   "
842 /* Note that the csky addc instruction both reads and writes the carry bit.
843    The purpose of the initial cmplt instruction in the expansion is to
844    clear the carry bit before adding the lo words.  */
846 (define_insn_and_split "*cskyv2_adddi3"
847   [(set (match_operand:DI          0 "register_operand" "=&b,&r")
848         (plus:DI (match_operand:DI 1 "register_operand" "%0,r")
849                  (match_operand:DI 2 "register_operand" "b, r")))
850    (clobber (reg:CC CSKY_CC_REGNUM))]
851   "CSKY_ISA_FEATURE (E2)"
852   "#"
853   "reload_completed"
854   [(const_int 0)]
855   {
856     int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD;
857     int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0;
858     rtx l0 = simplify_gen_subreg (SImode, operands[0], DImode, lo);
859     rtx h0 = simplify_gen_subreg (SImode, operands[0], DImode, hi);
860     rtx l1 = simplify_gen_subreg (SImode, operands[1], DImode, lo);
861     rtx h1 = simplify_gen_subreg (SImode, operands[1], DImode, hi);
862     rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode, lo);
863     rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode, hi);
865     emit_insn (gen_cmpltsi_r (copy_rtx (l1), copy_rtx (l1)));
866     emit_insn (gen_cskyv2_addc (l0, l1, l2));
867     emit_insn (gen_cskyv2_addc (h0, h1, h2));
868     DONE;
869   }
870   [(set_attr "length" "6,12")]
873 (define_insn_and_split "*ck801_adddi3"
874   [(set (match_operand:DI          0 "register_operand" "=r")
875         (plus:DI (match_operand:DI 1 "register_operand" "%0")
876                  (match_operand:DI 2 "register_operand" "r")))
877    (clobber (reg:CC CSKY_CC_REGNUM))]
878   "CSKY_ISA_FEATURE (E1)"
879   "#"
880   "reload_completed"
881   [(const_int 0)]
882   {
883     int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD;
884     int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0;
885     rtx l0 = simplify_gen_subreg (SImode, operands[0], DImode, lo);
886     rtx h0 = simplify_gen_subreg (SImode, operands[0], DImode, hi);
887     rtx l1 = simplify_gen_subreg (SImode, operands[1], DImode, lo);
888     rtx h1 = simplify_gen_subreg (SImode, operands[1], DImode, hi);
889     rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode, lo);
890     rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode, hi);
892     emit_insn (gen_cmpltsi_r (copy_rtx (l1), copy_rtx (l1)));
893     emit_insn (gen_ck801_addc (l0, l1, l2));
894     emit_insn (gen_ck801_addc (h0, h1, h2));
895     DONE;
896   }
897   [(set_attr "length" "6")]
900 ;; Special case for "longlong += 1".
902 (define_insn_and_split "*cskyv2_adddi1_1"
903   [(set (match_operand:DI          0 "register_operand" "=&r")
904         (plus:DI (match_operand:DI 1 "register_operand" "0")
905                  (const_int 1)))
906    (clobber (reg:CC CSKY_CC_REGNUM))]
907   "CSKY_ISA_FEATURE (E2)"
908   "#"
909   "reload_completed"
910   [(const_int 0)]
911   {
912     int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD;
913     int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0;
914     rtx l0 = simplify_gen_subreg (SImode, operands[0], DImode, lo);
915     rtx h0 = simplify_gen_subreg (SImode, operands[0], DImode, hi);
917     if (TARGET_MINI_REGISTERS)
918       {
919         emit_insn (gen_smart_addsi3 (l0, copy_rtx (l0),
920                                      gen_int_mode (1, SImode)));
921         emit_insn (gen_smart_cmpnesi_i (copy_rtx (l0),
922                                         gen_int_mode (0, SImode)));
923         emit_insn (gen_cskyv2_addcc_invert (h0, copy_rtx (h0),
924                                             gen_int_mode (1, SImode)));
925       }
926     else
927       {
928         emit_insn (gen_fast_addsi3 (l0, copy_rtx (l0),
929                                     gen_int_mode (1, SImode)));
930         emit_insn (gen_fast_cmpnesi_i (copy_rtx (l0),
931                                        gen_int_mode (0, SImode)));
932         emit_insn (gen_cskyv2_addcc_invert (h0, copy_rtx (h0),
933                                         gen_int_mode (1, SImode)));
934       }
935     DONE;
936   }
937   [(set (attr "length")
938         (if_then_else (match_test "TARGET_MINI_REGISTERS")
939                       (const_int 8)
940                       (const_int 12)))]
943 ;; sub instructions.
945 (define_expand "subsi3"
946   [(set (match_operand:SI 0 "register_operand" "")
947         (minus:SI (match_operand:SI 1 "register_operand" "")
948                   (match_operand:SI 2 "nonmemory_operand" "")))]
949   ""
950   ""
953 (define_insn "smart_subsi3"
954   [(set (match_operand:SI           0 "register_operand"    "=a,a,a,a,a,a")
955         (minus:SI (match_operand:SI 1 "register_operand"    "a, 0,0,a,0,a")
956                   (match_operand:SI 2 "nonmemory_operand"   "a, a,N,L,T,Us")))]
957   "TARGET_MINI_REGISTERS && CSKY_ISA_FEATURE (E2)
958    && operands[0] != stack_pointer_rtx
959    && operands[1] != stack_pointer_rtx"
960   "@
961     subu\t%0, %1, %2
962     subu\t%0, %1, %2
963     subi\t%0, %1, %2
964     subi\t%0, %1, %2
965     addi\t%0, %1, %M2
966     addi\t%0, %1, %M2"
967   [(set_attr "length" "2,2,2,2,2,2")
968    (set_attr "type" "addsub")]
971 (define_insn "*smart_subsi3_sp"
972   [(set (match_operand:SI           0 "register_operand"  "=z,z, z,a, a,r")
973         (minus:SI (match_operand:SI 1 "register_operand"  "0, 0, 0,z, a,r")
974                   (match_operand:SI 2 "nonmemory_operand" "P, Ug,a,Ur,a,M")))]
975   "TARGET_MINI_REGISTERS && CSKY_ISA_FEATURE (E2)
976    && (operands[0] == stack_pointer_rtx || operands[1] == stack_pointer_rtx)"
977   "@
978     subi\t%0, %1, %2
979     addi\t%0, %1, %M2
980     subu\t%0, %1, %2
981     addi\t%0, %1, %M2
982     subu\t%0, %1, %2
983     subi\t%0, %1, %2"
984   [(set_attr "length" "2,2,2,2,2,4")
985    (set_attr "type" "addsub")]
988 (define_insn "*ck801_subsi3"
989   [(set (match_operand:SI           0 "register_operand"    "=a,a,a,a,a,a")
990         (minus:SI (match_operand:SI 1 "register_operand"    "0, a,0,a,0,a")
991                   (match_operand:SI 2 "nonmemory_operand"   "a, a,N,L,T,Us")))]
992   "CSKY_ISA_FEATURE (E1)
993    && operands[0] != stack_pointer_rtx
994    && operands[1] != stack_pointer_rtx"
995   "@
996     subu\t%0, %1, %2
997     subu\t%0, %1, %2
998     subi\t%0, %1, %2
999     subi\t%0, %1, %2
1000     addi\t%0, %1, %M2
1001     addi\t%0, %1, %M2"
1002   [(set_attr "type" "addsub")]
1005 (define_insn "*ck801_subsi3_sp"
1006   [(set (match_operand:SI           0 "register_operand"  "=a,z,z, z")
1007         (minus:SI (match_operand:SI 1 "register_operand"  "z, 0,0, 0")
1008                   (match_operand:SI 2 "nonmemory_operand" "Ur,P,Ug,r")))]
1009   "CSKY_ISA_FEATURE (E1)
1010    && (operands[0] == stack_pointer_rtx || operands[1] == stack_pointer_rtx)"
1011   "@
1012     addi\t%0, %1, %M2
1013     subi\t%0, %1, %2
1014     addi\t%0, %1, %M2
1015     subu\t%0, %1, %2"
1016   [(set_attr "type" "addsub")]
1019 (define_insn "fast_subsi3"
1020   [(set (match_operand:SI           0 "register_operand"  "=r,r,r")
1021         (minus:SI (match_operand:SI 1 "register_operand"  "r, r,r")
1022                   (match_operand:SI 2 "nonmemory_operand" "r, M,Um")))]
1023   "!TARGET_MINI_REGISTERS && CSKY_ISA_FEATURE (E2)"
1024   "@
1025      subu\t%0, %1, %2
1026      subi\t%0, %1, %2
1027      addi\t%0, %1, %M2"
1028   [(set_attr "type" "addsub")]
1031 (define_expand "subdi3"
1032   [(parallel [(set (match_operand:DI 0 "register_operand" "")
1033                   (minus:DI (match_operand:DI 1 "register_operand" "")
1034                             (match_operand:DI 2 "register_operand" "")))
1035               (clobber (reg:CC CSKY_CC_REGNUM))])]
1036   ""
1037   ""
1040 /* Note that the csky subc instruction both reads and writes the C bit.
1041    The purpose of the initial cmphs instruction in the expansion is to
1042    set the C bit before subtracting the lo words.  */
1044 (define_insn_and_split "*cskyv2_subdi3"
1045   [(set (match_operand:DI           0 "register_operand" "=&b,&r")
1046         (minus:DI (match_operand:DI 1 "register_operand" "0, r")
1047                   (match_operand:DI 2 "register_operand" "b, r")))
1048    (clobber (reg:CC CSKY_CC_REGNUM))]
1049   "CSKY_ISA_FEATURE (E2)"
1050   "#"
1051   "reload_completed"
1052   [(const_int 0)]
1053   {
1054     int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD;
1055     int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0;
1056     rtx l0 = simplify_gen_subreg (SImode, operands[0], DImode, lo);
1057     rtx h0 = simplify_gen_subreg (SImode, operands[0], DImode, hi);
1058     rtx l1 = simplify_gen_subreg (SImode, operands[1], DImode, lo);
1059     rtx h1 = simplify_gen_subreg (SImode, operands[1], DImode, hi);
1060     rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode, lo);
1061     rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode, hi);
1063     emit_insn (gen_cmpgeusi_r (copy_rtx (l1), copy_rtx (l1)));
1064     emit_insn (gen_cskyv2_subc (l0, l1, l2));
1065     emit_insn (gen_cskyv2_subc (h0, h1, h2));
1066     DONE;
1067   }
1068   [(set_attr "length" "6,12")]
1071 (define_insn_and_split "*ck801_subdi3"
1072   [(set (match_operand:DI           0 "register_operand" "=r")
1073         (minus:DI (match_operand:DI 1 "register_operand" "0")
1074                   (match_operand:DI 2 "register_operand" "r")))
1075    (clobber (reg:CC CSKY_CC_REGNUM))]
1076   "CSKY_ISA_FEATURE (E1)"
1077   "#"
1078   "reload_completed"
1079   [(const_int 0)]
1080   {
1081     int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD;
1082     int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0;
1083     rtx l0 = simplify_gen_subreg (SImode, operands[0], DImode, lo);
1084     rtx h0 = simplify_gen_subreg (SImode, operands[0], DImode, hi);
1085     rtx l1 = simplify_gen_subreg (SImode, operands[1], DImode, lo);
1086     rtx h1 = simplify_gen_subreg (SImode, operands[1], DImode, hi);
1087     rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode, lo);
1088     rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode, hi);
1090     emit_insn (gen_cmpgeusi_r (copy_rtx (l1), copy_rtx (l1)));
1091     emit_insn (gen_ck801_subc (l0, l1, l2));
1092     emit_insn (gen_ck801_subc (h0, h1, h2));
1093     DONE;
1094   }
1095   [(set_attr "length" "6")]
1098 ;; Special case for "longlong -= 1".
1100 (define_insn_and_split "*cskyv2_subdi1_1"
1101   [(set (match_operand:DI          0 "register_operand" "=&r")
1102         (plus:DI (match_operand:DI 1 "register_operand" "0")
1103                  (const_int -1)))
1104    (clobber (reg:CC CSKY_CC_REGNUM))]
1105   "CSKY_ISA_FEATURE (E2)"
1106   "#"
1107   "reload_completed"
1108   [(const_int 0)]
1109   {
1110     int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD;
1111     int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0;
1112     rtx l0 = simplify_gen_subreg (SImode, operands[0], DImode, lo);
1113     rtx h0 = simplify_gen_subreg (SImode, operands[0], DImode, hi);
1115     if (TARGET_MINI_REGISTERS)
1116       {
1117         emit_insn (gen_smart_cmpnesi_i (copy_rtx (l0),
1118                                         gen_int_mode (0, SImode)));
1119         emit_insn (gen_cskyv2_addcc_invert (h0, copy_rtx (h0),
1120                                             gen_int_mode (-1, SImode)));
1121         emit_insn (gen_smart_subsi3 (l0, copy_rtx (l0),
1122                                      gen_int_mode (1, SImode)));
1123       }
1124     else
1125       {
1126         emit_insn (gen_fast_cmpnesi_i (copy_rtx (l0),
1127                                        gen_int_mode (0, SImode)));
1128         emit_insn (gen_cskyv2_addcc_invert (h0, copy_rtx (h0),
1129                                             gen_int_mode (-1, SImode)));
1130         emit_insn (gen_fast_subsi3 (l0, copy_rtx (l0),
1131                                     gen_int_mode (1, SImode)));
1132       }
1133     DONE;
1134   }
1135   [(set (attr "length")
1136         (if_then_else (match_test "TARGET_MINI_REGISTERS")
1137                       (const_int 8)
1138                       (const_int 12)))]
1141 ;; Add with carry.
1143 (define_insn "cskyv2_addc"
1144   [(set (match_operand:SI                   0 "register_operand" "=r,r")
1145         (plus:SI (ne:SI (reg:CC CSKY_CC_REGNUM) (const_int 0))
1146                  (plus:SI (match_operand:SI 1 "register_operand" "%0,r")
1147                           (match_operand:SI 2 "register_operand" "r,r"))))
1148    (set (reg:CC CSKY_CC_REGNUM)
1149         (compare:CC
1150           (plus:SI (match_dup 1) (match_dup 2))
1151           (match_dup 1)))]
1152   "CSKY_ISA_FEATURE (E2)"
1153   "addc\t%0, %1, %2"
1154   [(set_attr "length" "2,4")
1155    (set_attr "type" "addsub")]
1158 (define_insn "ck801_addc"
1159   [(set (match_operand:SI                   0 "register_operand" "=r")
1160         (plus:SI (ne:SI (reg:CC CSKY_CC_REGNUM) (const_int 0))
1161                  (plus:SI (match_operand:SI 1 "register_operand" "%0")
1162                           (match_operand:SI 2 "register_operand" "r"))))
1163    (set (reg:CC CSKY_CC_REGNUM)
1164         (compare:CC
1165           (plus:SI (match_dup 1) (match_dup 2))
1166           (match_dup 1)))]
1167   "CSKY_ISA_FEATURE (E1)"
1168   "addc\t%0, %1, %2"
1169   [(set_attr "length" "2")
1170    (set_attr "type" "addsub")]
1173 ;; Subtract with borrow.
1174 ;; Note that in these insns, the sense of C bit is reversed; they subtract 1
1175 ;; if the C bit is not set, and on output the bit is set to 0 for borrow
1176 ;; and 1 for no borrow.
1178 (define_insn "cskyv2_subc"
1179   [(set (match_operand:SI                    0 "register_operand" "=r,r")
1180         (minus:SI (match_operand:SI          1 "register_operand" "0, r")
1181                   (plus:SI (match_operand:SI 2 "register_operand" "r, r")
1182                            (eq:SI (reg:CC CSKY_CC_REGNUM) (const_int 0)))))
1183    (set (reg:CC CSKY_CC_REGNUM)
1184         (not (compare:CC (match_dup 1) (match_dup 2))))]
1185   "CSKY_ISA_FEATURE (E2)"
1186   "subc\t%0, %1, %2"
1187   [(set_attr "length" "2,4")
1188    (set_attr "type" "addsub")]
1191 (define_insn "ck801_subc"
1192   [(set (match_operand:SI                    0 "register_operand" "=r")
1193         (minus:SI (match_operand:SI          1 "register_operand" "0")
1194                   (plus:SI (match_operand:SI 2 "register_operand" "r")
1195                            (eq:SI (reg:CC CSKY_CC_REGNUM) (const_int 0)))))
1196    (set (reg:CC CSKY_CC_REGNUM)
1197         (not (compare:CC (match_dup 1) (match_dup 2))))]
1198   "CSKY_ISA_FEATURE (E1)"
1199   "subc\t%0, %1, %2"
1200   [(set_attr "length" "2")
1201    (set_attr "type" "addsub")]
1204 ;; ------------------------------------------------------------------------
1205 ;; Multiplication insns
1206 ;; ------------------------------------------------------------------------
1208 (define_expand "mulsi3"
1209   [(set (match_operand:SI          0 "register_operand" "")
1210         (mult:SI (match_operand:SI 1 "register_operand" "")
1211                  (match_operand:SI 2 "register_operand" "")))]
1212   ""
1213   ""
1216 (define_insn "*cskyv2_mulsi3"
1217   [(set (match_operand:SI          0 "register_operand" "=r")
1218         (mult:SI (match_operand:SI 1 "register_operand" "%r")
1219                  (match_operand:SI 2 "register_operand" "r")))]
1220   "CSKY_ISA_FEATURE (E2)"
1221   "mult\t%0, %1, %2"
1224 (define_insn "*ck801_mulsi3"
1225   [(set (match_operand:SI          0 "register_operand" "=r")
1226         (mult:SI (match_operand:SI 1 "register_operand" "%0")
1227                  (match_operand:SI 2 "register_operand" "r")))]
1228   "CSKY_ISA_FEATURE (E1)"
1229   "mult\t%0, %1, %2"
1232 (define_insn "mulhisi3"
1233   [(set (match_operand:SI                          0 "register_operand" "=r")
1234         (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%r"))
1235                  (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
1236   "CSKY_ISA_FEATURE (2E3)"
1237   "mulsh\t%0, %1, %2"
1241 ;; ------------------------------------------------------------------------
1242 ;; Conditional add insns
1243 ;; ------------------------------------------------------------------------
1245 (define_expand "addsicc"
1246   [(match_operand:SI 0 "register_operand" "")
1247    (match_operand    1 "comparison_operator" "")
1248    (match_operand:SI 2 "register_operand" "")
1249    (match_operand:SI 3 "csky_literal_K_Uh_operand" "")]
1250   "CSKY_ISA_FEATURE (E2)"
1251   "
1252   {
1253     bool invert = csky_emit_compare (GET_CODE (operands[1]),
1254                                      XEXP (operands[1], 0),
1255                                      XEXP (operands[1], 1));
1256     if (invert)
1257       emit_insn (gen_cskyv2_addcc_invert (operands[0], operands[2],
1258                                           operands[3]));
1259     else
1260       emit_insn (gen_cskyv2_addcc (operands[0], operands[2], operands[3]));
1262     DONE;
1263   }"
1266 (define_insn_and_split "cskyv2_addcc"
1267   [(set (match_operand:SI            0 "register_operand"          "=r,r,&r,&r")
1268         (if_then_else:SI
1269           (ne (reg:CC CSKY_CC_REGNUM) (const_int 0))
1270           (plus:SI (match_operand:SI 1 "register_operand"          "0,0,r,r")
1271                    (match_operand:SI 2 "csky_literal_K_Uh_operand" "K,Uh,K,Uh"))
1272           (match_dup 1)))]
1273   "CSKY_ISA_FEATURE (E2)"
1274   "@
1275    inct\t%0, %1, %2
1276    dect\t%0, %1, %M2
1277    #
1278    #"
1279   "reload_completed && !rtx_equal_p (operands[0], operands[1])"
1280   [(set (match_dup 0)
1281         (if_then_else:SI (ne (reg:CC CSKY_CC_REGNUM) (const_int 0))
1282                          (plus:SI (match_dup 0) (match_dup 2))))]
1283   {
1284     emit_insn (gen_movf (copy_rtx (operands[0]),
1285                          copy_rtx (operands[1]),
1286                          copy_rtx (operands[0])));
1287   }
1288   [(set_attr "length" "4,4,8,8")
1289    (set_attr "type" "addsub")]
1292 (define_insn_and_split "cskyv2_addcc_invert"
1293   [(set (match_operand:SI            0 "register_operand"          "=r,r,r,r")
1294         (if_then_else:SI
1295           (eq (reg:CC CSKY_CC_REGNUM) (const_int 0))
1296           (plus:SI (match_operand:SI 1 "register_operand"          "0,0,r,r")
1297                    (match_operand:SI 2 "csky_literal_K_Uh_operand" "K,Uh,K,Uh"))
1298           (match_dup 1)))]
1299   "CSKY_ISA_FEATURE (E2)"
1300   "@
1301    incf\t%0, %1, %2
1302    decf\t%0, %1, %M2
1303    #
1304    #"
1305   "reload_completed && !rtx_equal_p (operands[0], operands[1])"
1306   [(set (match_dup 0)
1307         (if_then_else:SI (eq (reg:CC CSKY_CC_REGNUM) (const_int 0))
1308                          (plus:SI (match_dup 0) (match_dup 2))))]
1309   {
1310     emit_insn (gen_movt (copy_rtx (operands[0]),
1311                          copy_rtx (operands[1]),
1312                          copy_rtx (operands[0])));
1313   }
1314   [(set_attr "length" "4,4,8,8")
1315    (set_attr "type" "addsub")]
1319 ;; ------------------------------------------------------------------------
1320 ;; Extzv insns
1321 ;; ------------------------------------------------------------------------
1323 (define_expand "extzvsi"
1324   [(set (match_operand:SI 0 "register_operand" "")
1325         (zero_extract:SI (match_operand:SI 1 "register_operand" "")
1326                          (match_operand:SI 2 "const_int_operand" "")
1327                          (match_operand:SI 3 "const_int_operand" "")))]
1328   ""
1329   "{
1330     /* ck802 has xtrb but not zext, so we'll use xtrb if we can.  */
1331     if (CSKY_ISA_FEATURE (E2) && !CSKY_ISA_FEATURE (2E3)
1332         && (INTVAL (operands[2]) == 8)
1333         && (INTVAL (operands[3]) % 8 == 0))
1334       {
1335         rtx xtrb = gen_rtx_SET (operands[0],
1336                                 gen_rtx_ZERO_EXTRACT (SImode,
1337                                                       operands[1],
1338                                                       operands[2],
1339                                                       operands[3]));
1340         emit (gen_rtx_PARALLEL (VOIDmode,
1341                                 gen_rtvec (2, xtrb,
1342                                 gen_hard_reg_clobber (CCmode, 33))));
1343         DONE;
1344       }
1345     else if (!CSKY_ISA_FEATURE (2E3))
1346       {
1347         /* Use lsri and lsli to do extzv on targets without zext.  */
1348         rtx lshft = GEN_INT (32 - (INTVAL (operands[2])
1349                              + INTVAL (operands[3])));
1350         rtx rshft = GEN_INT (32 - INTVAL (operands[2]));
1351         rtx tmp1 = gen_reg_rtx (SImode);
1352         rtx tmp2 = gen_reg_rtx (SImode);
1354         emit_insn (gen_rtx_SET (tmp1, operands[1]));
1355         emit_insn (gen_rtx_SET (tmp2, gen_rtx_ASHIFT (SImode, tmp1, lshft)));
1356         emit_insn (gen_rtx_SET (operands[0],
1357                                 gen_rtx_LSHIFTRT (SImode, tmp2, rshft)));
1358         DONE;
1359       }
1360     else
1361       {
1362         emit_insn (gen_cskyv2_extzv (operands[0], operands[1],
1363                                      operands[2], operands[3]));
1364         DONE;
1365       }
1368 (define_insn "cskyv2_extzv"
1369   [(set (match_operand:SI                  0 "register_operand" "=r")
1370         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
1371                          (match_operand:SI 2 "csky_literal_K_operand" "K")
1372                          (match_operand:SI 3 "csky_literal_K_operand" "K")))]
1373   "CSKY_ISA_FEATURE (2E3)"
1374   {
1375     operands[2] = GEN_INT (INTVAL (operands[3]) + INTVAL (operands[2]) - 1);
1376     return \"zext\t%0, %1, %2, %3\";
1377   }
1380 (define_insn "*cskyv2_xtrb0"
1381   [(set (match_operand:SI                  0 "register_operand" "=r,r")
1382         (zero_extract:SI (match_operand:SI 1 "register_operand" "0,r")
1383                          (const_int 8)
1384                          (const_int 24)))
1385         (clobber (reg:CC CSKY_CC_REGNUM))]
1386   "CSKY_ISA_FEATURE (E2)"
1387   "@
1388     lsri\t%0, %0, 24
1389     xtrb0\t%0, %1"
1392 (define_insn "*cskyv2_xtrb1"
1393   [(set (match_operand:SI                  0 "register_operand" "=r")
1394         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
1395                          (const_int 8)
1396                          (const_int 16)))
1397         (clobber (reg:CC CSKY_CC_REGNUM))]
1398   "CSKY_ISA_FEATURE (E2)"
1399   "xtrb1\t%0, %1"
1402 (define_insn "*cskyv2_xtrb2"
1403   [(set (match_operand:SI                  0 "register_operand" "=r")
1404         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
1405                          (const_int 8)
1406                          (const_int 8)))
1407         (clobber (reg:CC CSKY_CC_REGNUM))]
1408   "CSKY_ISA_FEATURE (E2)"
1409   "xtrb2\t%0, %1"
1413 ;; -------------------------------------------------------------------------
1414 ;; Zero extension instructions
1415 ;; -------------------------------------------------------------------------
1417 (define_insn "zero_extendhisi2"
1418   [(set (match_operand:SI                 0 "register_operand" "=r")
1419         (zero_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1420   ""
1421   "zexth\t%0, %1"
1424 (define_insn "*cskyv2_zextend_ldh"
1425   [(set (match_operand:SI                 0 "register_operand" "=r")
1426         (zero_extend:SI (match_operand:HI 1 "csky_simple_mem_operand" "m")))]
1427   ""
1428   "ld.h\t%0, %1"
1429   [(set_attr "length" "4")
1430    (set_attr "type" "load")]
1433 (define_insn "zero_extendqisi2"
1434   [(set (match_operand:SI                 0 "register_operand" "=r")
1435         (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1436   ""
1437   "zextb\t%0, %1"
1440 (define_insn "*cskyv2_zextend_ldb"
1441   [(set (match_operand:SI                 0 "register_operand" "=r")
1442         (zero_extend:SI (match_operand:QI 1 "csky_simple_mem_operand" "m")))]
1443   ""
1444   "ld.b\t%0, %1"
1445   [(set_attr "length" "4")
1446    (set_attr "type" "load")]
1449 (define_insn "zero_extendqihi2"
1450   [(set (match_operand:HI                 0 "register_operand" "=r")
1451         (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1452   ""
1453   "zextb\t%0, %1"
1456 (define_insn "*cskyv2_zextend_ldbhi"
1457   [(set (match_operand:HI                 0 "register_operand"   "=r")
1458         (zero_extend:HI (match_operand:QI 1 "csky_simple_mem_operand" "m")))]
1459   ""
1460   "ld.b\t%0, %1"
1461   [(set_attr "length" "4")
1462    (set_attr "type" "load")]
1465 ;; -------------------------------------------------------------------------
1466 ;; clzm2 instructions
1467 ;; -------------------------------------------------------------------------
1469 (define_insn "clzsi2"
1470   [(set (match_operand:SI         0 "register_operand" "=r")
1471         (clz:SI (match_operand:SI 1 "register_operand" "r")))]
1472   "CSKY_ISA_FEATURE (E2)"
1473   "ff1  %0,%1"
1476 ;; -------------------------------------------------------------------------
1477 ;; one_cmplm2 instructions
1478 ;; -------------------------------------------------------------------------
1480 (define_expand "one_cmplsi2"
1481   [(set (match_operand:SI         0 "register_operand" "")
1482         (not:SI (match_operand:SI 1 "register_operand" "")))]
1483   ""
1484   ""
1487 (define_insn "cskyv2_one_cmplsi2"
1488   [(set (match_operand:SI         0 "register_operand" "=b,r")
1489         (not:SI (match_operand:SI 1 "register_operand" "0,r")))]
1490   "CSKY_ISA_FEATURE (E2)"
1491   "not %0, %1"
1492   [(set_attr "length" "2,4")
1493    (set_attr "type" "alu,alu")]
1496 (define_insn "ck801_one_cmplsi2"
1497   [(set (match_operand:SI         0 "register_operand" "=r")
1498         (not:SI (match_operand:SI 1 "register_operand" "0")))]
1499   "CSKY_ISA_FEATURE (E1)"
1500   "not %0, %1"
1501   [(set_attr "length" "2")
1502    (set_attr "type" "alu")]
1505 ;; -------------------------------------------------------------------------
1506 ;; Sign extension instructions
1507 ;; -------------------------------------------------------------------------
1509 ;; One test shows that the following code helps to
1510 ;; reduce one 'load' and two 'mov'.
1511 (define_expand "extendsidi2"
1512   [(set (match_operand:DI 0 "register_operand" "=r")
1513         (match_operand:SI 1 "register_operand" "r"))]
1514   ""
1515   "{
1516     int low, high;
1518     if (TARGET_BIG_ENDIAN)
1519       low = 4, high = 0;
1520     else
1521       low = 0, high = 4;
1523     emit_insn (gen_rtx_SET (gen_rtx_SUBREG (SImode, operands[0], low),
1524                             operands[1]));
1526     emit_insn (gen_rtx_SET (gen_rtx_SUBREG (SImode, operands[0], high),
1527                             gen_rtx_ASHIFTRT (SImode,
1528                                               gen_rtx_SUBREG (SImode,
1529                                                               operands[0],
1530                                                               low),
1531                                               GEN_INT (31))));
1532     DONE;
1533   }"
1536 ;; hi -> si
1537 (define_insn "extendhisi2"
1538   [(set (match_operand:SI                 0 "register_operand" "=r")
1539         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1540   ""
1541   "sexth  %0, %1"
1544 (define_insn "*cskyv2_sextend_ldhs"
1545   [(set (match_operand:SI                 0 "register_operand" "=r")
1546         (sign_extend:SI (match_operand:HI 1 "csky_simple_mem_operand" "m")))]
1547   "CSKY_ISA_FEATURE (E2)"
1548   "ld.hs\t%0, %1"
1549   [(set_attr "length" "4")
1550    (set_attr "type" "load")]
1553 ;; qi -> si
1554 (define_insn "extendqisi2"
1555   [(set (match_operand:SI                 0 "register_operand" "=r")
1556         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1557   ""
1558   "sextb  %0, %1"
1561 (define_insn "*cskyv2_sextend_ldbs"
1562   [(set (match_operand:SI                 0 "register_operand" "=r")
1563         (sign_extend:SI (match_operand:QI 1 "csky_simple_mem_operand" "m")))]
1564   "CSKY_ISA_FEATURE (E2)"
1565   "ld.bs\t%0, %1"
1566   [(set_attr "length" "4")
1567    (set_attr "type" "load")]
1570 ;; qi -> hi
1571 (define_insn "extendqihi2"
1572   [(set (match_operand:HI                 0 "register_operand" "=r")
1573         (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1574   ""
1575   "sextb  %0, %1"
1578 ;; -------------------------------------------------------------------------
1579 ;; And instructions
1580 ;; -------------------------------------------------------------------------
1582 (define_expand "andsi3"
1583   [(set (match_operand:SI 0 "register_operand" "")
1584         (and:SI (match_operand:SI 1 "register_operand" "")
1585                 (match_operand:SI 2 "csky_arith_any_imm_operand" "")))]
1586   ""
1587   "")
1589 (define_insn_and_split "cskyv2_andsi3"
1590   [(set (match_operand:SI         0 "register_operand"           "=b,r,r,&r")
1591         (and:SI (match_operand:SI 1 "register_operand"           "%0,r,r,r")
1592                 (match_operand:SI 2 "csky_arith_any_imm_operand" "b,r,O,i")))]
1593   "CSKY_ISA_FEATURE (E2)"
1594   "@
1595    and\t%0, %1, %2
1596    and\t%0, %1, %2
1597    andi\t%0, %1, %2
1598    #"
1599   "(CONST_INT_P (operands[2])
1600     && (operands[2] == const0_rtx
1601         || !csky_arith_O_operand (operands[2], SImode)))"
1602   [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))]
1603   {
1604     if (csky_split_and (operands))
1605       DONE;
1606   }
1607   [(set_attr "length" "2,4,4,8")
1608    (set_attr "type" "alu,alu,alu,alu")]
1611 (define_insn_and_split "ck801_andsi3"
1612   [(set (match_operand:SI         0 "register_operand"           "=r,&r")
1613         (and:SI (match_operand:SI 1 "register_operand"           "%0,r")
1614                 (match_operand:SI 2 "csky_arith_any_imm_operand" "r,i")))]
1615   "CSKY_ISA_FEATURE (E1)"
1616   "@
1617    and\t%0, %1, %2
1618    #"
1619   "CONST_INT_P (operands[2])"
1620   [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))]
1621   {
1622     if (csky_split_and (operands))
1623       DONE;
1624   }
1625   [(set_attr "length" "2,4")
1626    (set_attr "type" "alu,alu")]
1629 ;; Note that the operands for the andnsi3 patterns are reversed compared
1630 ;; to the actual machine insn: operand 1 is the inverted operand.
1632 (define_insn "cskyv2_andnsi3"
1633   [(use (and:SI (not:SI (match_operand:SI 1 "csky_arith_O_operand" "b,r,O"))
1634         (match_operand:SI                 2 "register_operand"     "0,r,r")))
1635    (set (match_operand:SI                 0 "register_operand"     "=b,r,r")
1636         (and:SI (not:SI (match_dup 1))
1637                 (match_dup 2)))]
1638   "CSKY_ISA_FEATURE (E2)"
1639   "@
1640     andn\t%0, %2, %1
1641     andn\t%0, %2, %1
1642     andni\t%0, %2, %1"
1643   [(set_attr "length" "2,4,4")
1644    (set_attr "type" "alu,alu,alu")]
1647 (define_insn "ck801_andnsi3"
1648   [(use (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
1649                 (match_operand:SI         2 "register_operand" "0")))
1650    (set (match_operand:SI                 0 "register_operand" "=r")
1651         (and:SI (not:SI (match_dup 1))
1652                 (match_dup 2)))]
1653  "CSKY_ISA_FEATURE (E1)"
1654  "andn\t%0, %2, %1"
1657 (define_expand "anddi3"
1658   [(set (match_operand:DI 0 "register_operand" "")
1659         (and:DI (match_operand:DI 1 "register_operand" "")
1660                 (match_operand:DI 2 "csky_arith_any_imm_operand" "")))]
1661   ""
1662   "
1663   {
1664     if (CONST_INT_P (operands[2]))
1665       {
1666         HOST_WIDE_INT ival = INTVAL (operands[2]);
1667         if (ival == (HOST_WIDE_INT) 0xffffffff)
1668           {
1669             emit_move_insn (gen_lowpart (SImode, operands[0]),
1670                             gen_lowpart (SImode, operands[1]));
1671             emit_move_insn (gen_highpart (SImode, operands[0]), const0_rtx);
1672             DONE;
1673           }
1674         else if (ival == (HOST_WIDE_INT) ((unsigned HOST_WIDE_INT) -1 << 32))
1675           {
1676             emit_move_insn (gen_lowpart (SImode, operands[0]), const0_rtx);
1677             emit_move_insn (gen_highpart (SImode, operands[0]),
1678                             gen_highpart (SImode, operands[1]));
1679             DONE;
1680           }
1681         else
1682            FAIL;
1683       }
1684   }")
1688 (define_insn_and_split "*cskyv2_anddi3"
1689   [(set (match_operand:DI         0 "register_operand" "=&b,&r")
1690         (and:DI (match_operand:DI 1 "register_operand" "%0,r")
1691                 (match_operand:DI 2 "register_operand" "b,r")))]
1692   "CSKY_ISA_FEATURE (E2)"
1693   "#"
1694   "reload_completed"
1695   [(const_int 0)]
1696   {
1697     int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD;
1698     int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0;
1699     rtx l0 = simplify_gen_subreg (SImode, operands[0], DImode, lo);
1700     rtx h0 = simplify_gen_subreg (SImode, operands[0], DImode, hi);
1701     rtx l1 = simplify_gen_subreg (SImode, operands[1], DImode, lo);
1702     rtx h1 = simplify_gen_subreg (SImode, operands[1], DImode, hi);
1703     rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode, lo);
1704     rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode, hi);
1706     emit_insn (gen_cskyv2_andsi3 (l0, l1, l2));
1707     emit_insn (gen_cskyv2_andsi3 (h0, h1, h2));
1708     DONE;
1709   }
1710   [(set_attr "length" "4,8")]
1713 (define_insn_and_split "*ck801_anddi3"
1714  [(set (match_operand:DI         0 "register_operand" "=&r")
1715        (and:DI (match_operand:DI 1 "register_operand" "%0")
1716                (match_operand:DI 2 "register_operand" "r")))]
1717   "CSKY_ISA_FEATURE (E1)"
1718   "#"
1719   "reload_completed"
1720   [(const_int 0)]
1721   {
1722     int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD;
1723     int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0;
1724     rtx l0 = simplify_gen_subreg (SImode, operands[0], DImode, lo);
1725     rtx h0 = simplify_gen_subreg (SImode, operands[0], DImode, hi);
1726     rtx l1 = simplify_gen_subreg (SImode, operands[1], DImode, lo);
1727     rtx h1 = simplify_gen_subreg (SImode, operands[1], DImode, hi);
1728     rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode, lo);
1729     rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode, hi);
1731     emit_insn (gen_ck801_andsi3 (l0, l1, l2));
1732     emit_insn (gen_ck801_andsi3 (h0, h1, h2));
1733     DONE;
1734   }
1735   [(set_attr "length" "4")]
1739 ;; -------------------------------------------------------------------------
1740 ;; Ior instructions
1741 ;; -------------------------------------------------------------------------
1743 (define_expand "iorsi3"
1744   [(set (match_operand:SI 0 "register_operand" "")
1745         (ior:SI (match_operand:SI 1 "register_operand" "")
1746                 (match_operand:SI 2 "csky_arith_any_imm_operand" "")))]
1747   ""
1748   "")
1750 (define_insn_and_split "cskyv2_iorsi3"
1751   [(set (match_operand:SI         0 "register_operand"           "=b,r,r,&r")
1752         (ior:SI (match_operand:SI 1 "register_operand"           "%0,r,r,r")
1753                 (match_operand:SI 2 "csky_arith_any_imm_operand" "b, r,I,i")))]
1754   "CSKY_ISA_FEATURE (E2)"
1755   "@
1756   or\t%0, %1, %2
1757   or\t%0, %1, %2
1758   ori\t%0, %1, %2
1759   #"
1760   "(CONST_INT_P (operands[2])
1761     && (operands[2] == const0_rtx
1762         || !csky_literal_I_operand (operands[2], SImode)))"
1763   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))]
1764   {
1765     if (csky_split_ior (operands))
1766       DONE;
1767   }
1768   [(set_attr "length" "2,4,4,8")
1769    (set_attr "type" "alu,alu,alu,alu")]
1772 (define_insn_and_split "ck801_iorsi3"
1773   [(set (match_operand:SI         0 "register_operand"           "=r,&r")
1774         (ior:SI (match_operand:SI 1 "register_operand"           "%0,r")
1775                 (match_operand:SI 2 "csky_arith_any_imm_operand" "r,i")))]
1776   "CSKY_ISA_FEATURE (E1)"
1777   "@
1778   or\t%0, %1, %2
1779   #"
1780   "CONST_INT_P (operands[2])"
1781   [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))]
1782   {
1783     if (csky_split_ior (operands))
1784       DONE;
1785   }
1786   [(set_attr "length" "2,4")
1787    (set_attr "type" "alu,alu")]
1790 (define_expand "iordi3"
1791   [(set (match_operand:DI         0 "register_operand" "")
1792         (ior:DI (match_operand:DI 1 "register_operand" "")
1793                 (match_operand:DI 2 "register_operand" "")))]
1794   ""
1795   ""
1798 (define_insn_and_split "*cskyv2_iordi3"
1799   [(set (match_operand:DI         0 "register_operand" "=&b,&r")
1800         (ior:DI (match_operand:DI 1 "register_operand" "%0, r")
1801                 (match_operand:DI 2 "register_operand" "b,  r")))]
1802   "CSKY_ISA_FEATURE (E2)"
1803   "#"
1804   "reload_completed"
1805   [(const_int 0)]
1806   {
1807     int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD;
1808     int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0;
1809     rtx l0 = simplify_gen_subreg (SImode, operands[0], DImode, lo);
1810     rtx h0 = simplify_gen_subreg (SImode, operands[0], DImode, hi);
1811     rtx l1 = simplify_gen_subreg (SImode, operands[1], DImode, lo);
1812     rtx h1 = simplify_gen_subreg (SImode, operands[1], DImode, hi);
1813     rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode, lo);
1814     rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode, hi);
1816     emit_insn (gen_cskyv2_iorsi3 (l0, l1, l2));
1817     emit_insn (gen_cskyv2_iorsi3 (h0, h1, h2));
1818     DONE;
1819   }
1820   [(set_attr "length" "4,8")]
1823 (define_insn_and_split "*ck801_iordi3"
1824   [(set (match_operand:DI         0 "register_operand" "=&r")
1825         (ior:DI (match_operand:DI 1 "register_operand" "%0")
1826                 (match_operand:DI 2 "register_operand" "r")))]
1827   "CSKY_ISA_FEATURE (E1)"
1828   "#"
1829   "reload_completed"
1830   [(const_int 0)]
1831   {
1832     int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD;
1833     int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0;
1834     rtx l0 = simplify_gen_subreg (SImode, operands[0], DImode, lo);
1835     rtx h0 = simplify_gen_subreg (SImode, operands[0], DImode, hi);
1836     rtx l1 = simplify_gen_subreg (SImode, operands[1], DImode, lo);
1837     rtx h1 = simplify_gen_subreg (SImode, operands[1], DImode, hi);
1838     rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode, lo);
1839     rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode, hi);
1841     emit_insn (gen_ck801_iorsi3 (l0, l1, l2));
1842     emit_insn (gen_ck801_iorsi3 (h0, h1, h2));
1843     DONE;
1844   }
1845   [(set_attr "length" "4")]
1849 ;; -------------------------------------------------------------------------
1850 ;; Xor instructions
1851 ;; -------------------------------------------------------------------------
1853 (define_expand "xorsi3"
1854   [(set (match_operand:SI 0 "register_operand" "")
1855         (xor:SI (match_operand:SI 1 "register_operand" "")
1856                 (match_operand:SI 2 "csky_arith_any_imm_operand" "")))]
1857   ""
1858   "")
1860 (define_insn_and_split "cskyv2_xorsi3"
1861   [(set (match_operand:SI         0 "register_operand"           "=b,r,r,&r")
1862         (xor:SI (match_operand:SI 1 "register_operand"           "%0,r,r,r")
1863                 (match_operand:SI 2 "csky_arith_any_imm_operand" "b, r,O,i")))]
1864   "CSKY_ISA_FEATURE (E2)"
1865   "@
1866   xor\t%0, %1, %2
1867   xor\t%0, %1, %2
1868   xori\t%0, %1, %2
1869   #"
1870   "(CONST_INT_P (operands[2])
1871     && (operands[2] == const0_rtx
1872         || !csky_arith_O_operand (operands[2], SImode)))"
1873   [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))]
1874   {
1875     if (csky_split_xor (operands))
1876       DONE;
1877   }
1878   [(set_attr "length" "2,4,4,8")
1879    (set_attr "type" "alu,alu,alu,alu")]
1882 (define_insn_and_split "ck801_xorsi3"
1883   [(set (match_operand:SI         0 "register_operand"           "=r,&r")
1884         (xor:SI (match_operand:SI 1 "register_operand"           "%0,r")
1885                 (match_operand:SI 2 "csky_arith_any_imm_operand" "r,i")))]
1886   "CSKY_ISA_FEATURE (E1)"
1887   "@
1888   xor\t%0, %1, %2
1889   #"
1890   "CONST_INT_P (operands[2])"
1891   [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))]
1892   {
1893     if (csky_split_xor (operands))
1894       DONE;
1895   }
1896   [(set_attr "length" "2,4")
1897    (set_attr "type" "alu,alu")]
1900 (define_expand "xordi3"
1901   [(set (match_operand:DI         0 "register_operand" "")
1902         (xor:DI (match_operand:DI 1 "register_operand" "")
1903                 (match_operand:DI 2 "register_operand" "")))]
1904   ""
1905   ""
1908 (define_insn_and_split "*cskyv2_xordi3"
1909   [(set (match_operand:DI         0 "register_operand" "=&b,&r")
1910         (xor:DI (match_operand:DI 1 "register_operand" "%0, r")
1911                 (match_operand:DI 2 "register_operand" "b,  r")))]
1912   "CSKY_ISA_FEATURE (E2)"
1913   "#"
1914   "reload_completed"
1915   [(const_int 0)]
1916   {
1917     int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD;
1918     int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0;
1919     rtx l0 = simplify_gen_subreg (SImode, operands[0], DImode, lo);
1920     rtx h0 = simplify_gen_subreg (SImode, operands[0], DImode, hi);
1921     rtx l1 = simplify_gen_subreg (SImode, operands[1], DImode, lo);
1922     rtx h1 = simplify_gen_subreg (SImode, operands[1], DImode, hi);
1923     rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode, lo);
1924     rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode, hi);
1926     emit_insn (gen_cskyv2_xorsi3 (l0, l1, l2));
1927     emit_insn (gen_cskyv2_xorsi3 (h0, h1, h2));
1928     DONE;
1929   }
1930   [(set_attr "length" "4,8")]
1933 (define_insn_and_split "*ck801_xordi3"
1934   [(set (match_operand:DI         0 "register_operand" "=&r")
1935         (xor:DI (match_operand:DI 1 "register_operand" "%0")
1936                 (match_operand:DI 2 "register_operand" "r")))]
1937   "CSKY_ISA_FEATURE (E1)"
1938   "#"
1939   "reload_completed"
1940   [(const_int 0)]
1941   {
1942     int hi = TARGET_BIG_ENDIAN ? 0 : UNITS_PER_WORD;
1943     int lo = TARGET_BIG_ENDIAN ? UNITS_PER_WORD : 0;
1944     rtx l0 = simplify_gen_subreg (SImode, operands[0], DImode, lo);
1945     rtx h0 = simplify_gen_subreg (SImode, operands[0], DImode, hi);
1946     rtx l1 = simplify_gen_subreg (SImode, operands[1], DImode, lo);
1947     rtx h1 = simplify_gen_subreg (SImode, operands[1], DImode, hi);
1948     rtx l2 = simplify_gen_subreg (SImode, operands[2], DImode, lo);
1949     rtx h2 = simplify_gen_subreg (SImode, operands[2], DImode, hi);
1951     emit_insn (gen_ck801_xorsi3 (l0, l1, l2));
1952     emit_insn (gen_ck801_xorsi3 (h0, h1, h2));
1953     DONE;
1954   }
1955   [(set_attr "length" "4")]
1958 ;; -------------------------------------------------------------------------
1959 ;; Div instructions
1960 ;; -------------------------------------------------------------------------
1962 (define_insn "divsi3"
1963   [(set (match_operand:SI         0 "register_operand" "=r")
1964         (div:SI (match_operand:SI 1 "register_operand" "r")
1965                 (match_operand:SI 2 "register_operand" "r")))]
1966   "TARGET_DIV"
1967   "divs\t%0, %1, %2"
1970 (define_insn "udivsi3"
1971   [(set (match_operand:SI          0 "register_operand" "=r")
1972         (udiv:SI (match_operand:SI 1 "register_operand" "r")
1973                  (match_operand:SI 2 "register_operand" "r")))]
1974   "TARGET_DIV"
1975   "divu\t%0, %1, %2"
1979 ;; -----------------------------------------------------------------
1980 ;; Multiple load and store insns
1981 ;; -----------------------------------------------------------------
1983 (define_expand "load_multiple"
1984   [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
1985                           (match_operand:SI 1 "" ""))
1986                      (use (match_operand:SI 2 "" ""))])]
1987   "TARGET_MULTIPLE_STLD"
1988   "{
1989     int regno, count, i;
1990     rtx base,src;
1992     if (GET_CODE (operands[2]) != CONST_INT
1993         || INTVAL (operands[2]) < 2
1994         || INTVAL (operands[2]) > CSKY_MAX_MULTIPLE_STLD
1995         || GET_CODE (operands[1]) != MEM
1996         || !REG_P (XEXP (operands[1], 0))
1997         || XEXP (operands[1], 0) != stack_pointer_rtx
1998         || GET_CODE (operands[0]) != REG
1999         || (REGNO (XEXP (operands[1], 0)) > REGNO (operands[0])
2000             && (REGNO (XEXP (operands[1], 0))
2001                 < REGNO (operands[0]) + INTVAL (operands[2]))))
2002       FAIL;
2004     count = INTVAL (operands[2]);
2005     regno = REGNO (operands[0]);
2007     operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2009     base = force_reg (SImode, XEXP (operands[1], 0));
2010     src = replace_equiv_address (operands[1], base);
2012     for (i = 0; i < count; i++)
2013       XVECEXP (operands[3], 0, i)
2014         = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
2015                        adjust_address_nv (src, SImode, i * 4));
2016   }"
2019 (define_expand "store_multiple"
2020   [(match_par_dup 3 [(set (match_operand:SI 0 "")
2021                           (match_operand:SI 1 ""))
2022                      (use (match_operand:SI 2 ""))])]
2023   "TARGET_MULTIPLE_STLD"
2024   "{
2025     int regno, count, i;
2026     rtx base, dest;
2028     /* Support only storing a constant number of registers to memory and
2029        only if at least two registers. */
2030     if (GET_CODE (operands[2]) != CONST_INT
2031         || INTVAL (operands[2]) < 2
2032         || INTVAL (operands[2]) > CSKY_MAX_MULTIPLE_STLD
2033         || GET_CODE (operands[0]) != MEM
2034         || !REG_P (XEXP (operands[0], 0))
2035         || XEXP (operands[0], 0) != stack_pointer_rtx
2036         || GET_CODE (operands[1]) != REG
2037         || (REGNO (XEXP (operands[0], 0)) >= REGNO (operands[1])
2038             && (REGNO (XEXP (operands[0], 0))
2039                 < REGNO (operands[1]) + INTVAL (operands[2]))))
2040       FAIL;
2042     count = INTVAL (operands[2]);
2043     regno = REGNO (operands[1]);
2045     operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2047     base = force_reg (SImode, XEXP (operands[0], 0));
2048     dest = replace_equiv_address (operands[0], base);
2050     for (i = 0; i < count; i++)
2051       XVECEXP (operands[3], 0, i)
2052         = gen_rtx_SET (adjust_address_nv (dest, SImode, i * 4),
2053                        gen_rtx_REG (SImode, regno + i));
2054   }"
2058 (define_insn "*csky_ldmsi12"
2059   [(match_parallel          0 "csky_load_multiple_operation"
2060     [(set (match_operand:SI 1 "register_operand" "=r")
2061           (mem:SI (match_operand:SI   2 "register_operand" "r")))
2062      (set (match_operand:SI 3 "register_operand" "=r")
2063           (mem:SI (plus:SI (match_dup 2) (const_int 4))))
2064      (set (match_operand:SI 4 "register_operand" "=r")
2065           (mem:SI (plus:SI (match_dup 2) (const_int 8))))
2066      (set (match_operand:SI 5 "register_operand" "=r")
2067           (mem:SI (plus:SI (match_dup 2) (const_int 12))))
2068      (set (match_operand:SI 6 "register_operand" "=r")
2069           (mem:SI (plus:SI (match_dup 2) (const_int 16))))
2070      (set (match_operand:SI 7 "register_operand" "=r")
2071           (mem:SI (plus:SI (match_dup 2) (const_int 20))))
2072      (set (match_operand:SI 8 "register_operand" "=r")
2073           (mem:SI (plus:SI (match_dup 2) (const_int 24))))
2074      (set (match_operand:SI 9 "register_operand" "=r")
2075           (mem:SI (plus:SI (match_dup 2) (const_int 28))))
2076      (set (match_operand:SI 10 "register_operand" "=r")
2077           (mem:SI (plus:SI (match_dup 2) (const_int 32))))
2078      (set (match_operand:SI 11 "register_operand" "=r")
2079           (mem:SI (plus:SI (match_dup 2) (const_int 36))))
2080      (set (match_operand:SI 12 "register_operand" "=r")
2081           (mem:SI (plus:SI (match_dup 2) (const_int 40))))
2082      (set (match_operand:SI 13 "register_operand" "=r")
2083           (mem:SI (plus:SI (match_dup 2) (const_int 44))))
2084     ])]
2085   "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 12"
2086   {
2087     static char load_op[256] = {0};
2088     int count = REGNO (operands[1]) + XVECLEN (operands[0], 0) - 1;
2089     const char *reg_rz = reg_names[count];
2090     sprintf (load_op, \"ldm\t%%1 - %s, (%%2)\", reg_rz);
2091     return load_op;
2092   }
2095 (define_insn "*csky_ldmsi11"
2096   [(match_parallel          0 "csky_load_multiple_operation"
2097     [(set (match_operand:SI 1 "register_operand" "=r")
2098           (mem:SI (match_operand:SI   2 "register_operand" "r")))
2099      (set (match_operand:SI 3 "register_operand" "=r")
2100           (mem:SI (plus:SI (match_dup 2) (const_int 4))))
2101      (set (match_operand:SI 4 "register_operand" "=r")
2102           (mem:SI (plus:SI (match_dup 2) (const_int 8))))
2103      (set (match_operand:SI 5 "register_operand" "=r")
2104           (mem:SI (plus:SI (match_dup 2) (const_int 12))))
2105      (set (match_operand:SI 6 "register_operand" "=r")
2106           (mem:SI (plus:SI (match_dup 2) (const_int 16))))
2107      (set (match_operand:SI 7 "register_operand" "=r")
2108           (mem:SI (plus:SI (match_dup 2) (const_int 20))))
2109      (set (match_operand:SI 8 "register_operand" "=r")
2110           (mem:SI (plus:SI (match_dup 2) (const_int 24))))
2111      (set (match_operand:SI 9 "register_operand" "=r")
2112           (mem:SI (plus:SI (match_dup 2) (const_int 28))))
2113      (set (match_operand:SI 10 "register_operand" "=r")
2114           (mem:SI (plus:SI (match_dup 2) (const_int 32))))
2115      (set (match_operand:SI 11 "register_operand" "=r")
2116           (mem:SI (plus:SI (match_dup 2) (const_int 36))))
2117      (set (match_operand:SI 12 "register_operand" "=r")
2118           (mem:SI (plus:SI (match_dup 2) (const_int 40))))
2119     ])]
2120   "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 11"
2121   {
2122     static char load_op[256] = {0};
2123     int count = REGNO (operands[1]) + XVECLEN (operands[0], 0) - 1;
2124     const char *reg_rz = reg_names[count];
2125     sprintf (load_op, \"ldm\t%%1 - %s, (%%2)\", reg_rz);
2126     return load_op;
2127   }
2130 (define_insn "*csky_ldmsi10"
2131   [(match_parallel          0 "csky_load_multiple_operation"
2132     [(set (match_operand:SI 1 "register_operand" "=r")
2133           (mem:SI (match_operand:SI   2 "register_operand" "r")))
2134      (set (match_operand:SI 3 "register_operand" "=r")
2135           (mem:SI (plus:SI (match_dup 2) (const_int 4))))
2136      (set (match_operand:SI 4 "register_operand" "=r")
2137           (mem:SI (plus:SI (match_dup 2) (const_int 8))))
2138      (set (match_operand:SI 5 "register_operand" "=r")
2139           (mem:SI (plus:SI (match_dup 2) (const_int 12))))
2140      (set (match_operand:SI 6 "register_operand" "=r")
2141           (mem:SI (plus:SI (match_dup 2) (const_int 16))))
2142      (set (match_operand:SI 7 "register_operand" "=r")
2143           (mem:SI (plus:SI (match_dup 2) (const_int 20))))
2144      (set (match_operand:SI 8 "register_operand" "=r")
2145           (mem:SI (plus:SI (match_dup 2) (const_int 24))))
2146      (set (match_operand:SI 9 "register_operand" "=r")
2147           (mem:SI (plus:SI (match_dup 2) (const_int 28))))
2148      (set (match_operand:SI 10 "register_operand" "=r")
2149           (mem:SI (plus:SI (match_dup 2) (const_int 32))))
2150      (set (match_operand:SI 11 "register_operand" "=r")
2151           (mem:SI (plus:SI (match_dup 2) (const_int 36))))
2152     ])]
2153   "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 10"
2154   {
2155     static char load_op[256] = {0};
2156     int count = REGNO (operands[1]) + XVECLEN (operands[0], 0) - 1;
2157     const char *reg_rz = reg_names[count];
2158     sprintf (load_op, \"ldm\t%%1 - %s, (%%2)\", reg_rz);
2159     return load_op;
2160   }
2163 (define_insn "*csky_ldmsi9"
2164   [(match_parallel          0 "csky_load_multiple_operation"
2165     [(set (match_operand:SI 1 "register_operand" "=r")
2166           (mem:SI (match_operand:SI   2 "register_operand" "r")))
2167      (set (match_operand:SI 3 "register_operand" "=r")
2168           (mem:SI (plus:SI (match_dup 2) (const_int 4))))
2169      (set (match_operand:SI 4 "register_operand" "=r")
2170           (mem:SI (plus:SI (match_dup 2) (const_int 8))))
2171      (set (match_operand:SI 5 "register_operand" "=r")
2172           (mem:SI (plus:SI (match_dup 2) (const_int 12))))
2173      (set (match_operand:SI 6 "register_operand" "=r")
2174           (mem:SI (plus:SI (match_dup 2) (const_int 16))))
2175      (set (match_operand:SI 7 "register_operand" "=r")
2176           (mem:SI (plus:SI (match_dup 2) (const_int 20))))
2177      (set (match_operand:SI 8 "register_operand" "=r")
2178           (mem:SI (plus:SI (match_dup 2) (const_int 24))))
2179      (set (match_operand:SI 9 "register_operand" "=r")
2180           (mem:SI (plus:SI (match_dup 2) (const_int 28))))
2181      (set (match_operand:SI 10 "register_operand" "=r")
2182           (mem:SI (plus:SI (match_dup 2) (const_int 32))))
2183     ])]
2184   "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 9"
2185   {
2186     static char load_op[256] = {0};
2187     int count = REGNO (operands[1]) + XVECLEN (operands[0], 0) - 1;
2188     const char *reg_rz = reg_names[count];
2189     sprintf (load_op, \"ldm\t%%1 - %s, (%%2)\", reg_rz);
2190     return load_op;
2191   }
2194 (define_insn "*csky_ldmsi8"
2195   [(match_parallel          0 "csky_load_multiple_operation"
2196     [(set (match_operand:SI 1 "register_operand" "=r")
2197           (mem:SI (match_operand:SI   2 "register_operand" "r")))
2198      (set (match_operand:SI 3 "register_operand" "=r")
2199           (mem:SI (plus:SI (match_dup 2) (const_int 4))))
2200      (set (match_operand:SI 4 "register_operand" "=r")
2201           (mem:SI (plus:SI (match_dup 2) (const_int 8))))
2202      (set (match_operand:SI 5 "register_operand" "=r")
2203           (mem:SI (plus:SI (match_dup 2) (const_int 12))))
2204      (set (match_operand:SI 6 "register_operand" "=r")
2205           (mem:SI (plus:SI (match_dup 2) (const_int 16))))
2206      (set (match_operand:SI 7 "register_operand" "=r")
2207           (mem:SI (plus:SI (match_dup 2) (const_int 20))))
2208      (set (match_operand:SI 8 "register_operand" "=r")
2209           (mem:SI (plus:SI (match_dup 2) (const_int 24))))
2210      (set (match_operand:SI 9 "register_operand" "=r")
2211           (mem:SI (plus:SI (match_dup 2) (const_int 28))))
2212     ])]
2213   "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 8"
2214   {
2215     static char load_op[256] = {0};
2216     int count = REGNO (operands[1]) + XVECLEN (operands[0], 0) - 1;
2217     const char *reg_rz = reg_names[count];
2218     sprintf (load_op, \"ldm\t%%1 - %s, (%%2)\", reg_rz);
2219     return load_op;
2220   }
2223 (define_insn "*csky_ldmsi7"
2224   [(match_parallel          0 "csky_load_multiple_operation"
2225     [(set (match_operand:SI 1 "register_operand" "=r")
2226           (mem:SI (match_operand:SI   2 "register_operand" "r")))
2227      (set (match_operand:SI 3 "register_operand" "=r")
2228           (mem:SI (plus:SI (match_dup 2) (const_int 4))))
2229      (set (match_operand:SI 4 "register_operand" "=r")
2230           (mem:SI (plus:SI (match_dup 2) (const_int 8))))
2231      (set (match_operand:SI 5 "register_operand" "=r")
2232           (mem:SI (plus:SI (match_dup 2) (const_int 12))))
2233      (set (match_operand:SI 6 "register_operand" "=r")
2234           (mem:SI (plus:SI (match_dup 2) (const_int 16))))
2235      (set (match_operand:SI 7 "register_operand" "=r")
2236           (mem:SI (plus:SI (match_dup 2) (const_int 20))))
2237      (set (match_operand:SI 8 "register_operand" "=r")
2238           (mem:SI (plus:SI (match_dup 2) (const_int 24))))
2239     ])]
2240   "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 7"
2241   {
2242     static char load_op[256] = {0};
2243     int count = REGNO (operands[1]) + XVECLEN (operands[0], 0) - 1;
2244     const char *reg_rz = reg_names[count];
2245     sprintf (load_op, \"ldm\t%%1 - %s, (%%2)\", reg_rz);
2246     return load_op;
2247   }
2250 (define_insn "*csky_ldmsi6"
2251   [(match_parallel          0 "csky_load_multiple_operation"
2252     [(set (match_operand:SI 1 "register_operand" "=r")
2253           (mem:SI (match_operand:SI   2 "register_operand" "r")))
2254      (set (match_operand:SI 3 "register_operand" "=r")
2255           (mem:SI (plus:SI (match_dup 2) (const_int 4))))
2256      (set (match_operand:SI 4 "register_operand" "=r")
2257           (mem:SI (plus:SI (match_dup 2) (const_int 8))))
2258      (set (match_operand:SI 5 "register_operand" "=r")
2259           (mem:SI (plus:SI (match_dup 2) (const_int 12))))
2260      (set (match_operand:SI 6 "register_operand" "=r")
2261           (mem:SI (plus:SI (match_dup 2) (const_int 16))))
2262      (set (match_operand:SI 7 "register_operand" "=r")
2263           (mem:SI (plus:SI (match_dup 2) (const_int 20))))
2264     ])]
2265   "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 6"
2266   {
2267     static char load_op[256] = {0};
2268     int count = REGNO (operands[1]) + XVECLEN (operands[0], 0) - 1;
2269     const char *reg_rz = reg_names[count];
2270     sprintf (load_op, \"ldm\t%%1 - %s, (%%2)\", reg_rz);
2271     return load_op;
2272   }
2276 (define_insn "*csky_ldmsi5"
2277   [(match_parallel          0 "csky_load_multiple_operation"
2278     [(set (match_operand:SI 1 "register_operand" "=r")
2279           (mem:SI (match_operand:SI   2 "register_operand" "r")))
2280      (set (match_operand:SI 3 "register_operand" "=r")
2281           (mem:SI (plus:SI (match_dup 2) (const_int 4))))
2282      (set (match_operand:SI 4 "register_operand" "=r")
2283           (mem:SI (plus:SI (match_dup 2) (const_int 8))))
2284      (set (match_operand:SI 5 "register_operand" "=r")
2285           (mem:SI (plus:SI (match_dup 2) (const_int 12))))
2286      (set (match_operand:SI 6 "register_operand" "=r")
2287           (mem:SI (plus:SI (match_dup 2) (const_int 16))))
2288     ])]
2289   "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 5"
2290   {
2291     static char load_op[256] = {0};
2292     int count = REGNO (operands[1]) + XVECLEN (operands[0], 0) - 1;
2293     const char *reg_rz = reg_names[count];
2294     sprintf (load_op, \"ldm\t%%1 - %s, (%%2)\", reg_rz);
2295     return load_op;
2296   }
2300 (define_insn "*csky_ldmsi4"
2301   [(match_parallel          0 "csky_load_multiple_operation"
2302     [(set (match_operand:SI 1 "register_operand" "=r")
2303           (mem:SI (match_operand:SI   2 "register_operand" "r")))
2304      (set (match_operand:SI 3 "register_operand" "=r")
2305           (mem:SI (plus:SI (match_dup 2) (const_int 4))))
2306      (set (match_operand:SI 4 "register_operand" "=r")
2307           (mem:SI (plus:SI (match_dup 2) (const_int 8))))
2308      (set (match_operand:SI 5 "register_operand" "=r")
2309           (mem:SI (plus:SI (match_dup 2) (const_int 12))))
2310     ])]
2311   "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 4"
2312   {
2313     static char load_op[256] = {0};
2314     int count = REGNO (operands[1]) + XVECLEN (operands[0], 0) - 1;
2315     const char *reg_rz = reg_names[count];
2316     sprintf (load_op, \"ldm\t%%1 - %s, (%%2)\", reg_rz);
2317     return load_op;
2318   }
2322 (define_insn "*csky_ldmsi3"
2323   [(match_parallel          0 "csky_load_multiple_operation"
2324     [(set (match_operand:SI 1 "register_operand" "=r")
2325           (mem:SI (match_operand:SI   2 "register_operand" "r")))
2326      (set (match_operand:SI 3 "register_operand" "=r")
2327           (mem:SI (plus:SI (match_dup 2) (const_int 4))))
2328      (set (match_operand:SI 4 "register_operand" "=r")
2329           (mem:SI (plus:SI (match_dup 2) (const_int 8))))
2330     ])]
2331   "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 3"
2332   {
2333     static char load_op[256] = {0};
2334     int count = REGNO (operands[1]) + XVECLEN (operands[0], 0) - 1;
2335     const char *reg_rz = reg_names[count];
2336     sprintf (load_op, \"ldm\t%%1 - %s, (%%2)\", reg_rz);
2337     return load_op;
2338   }
2342 (define_insn "*csky_ldmsi2"
2343   [(match_parallel          0 "csky_load_multiple_operation"
2344     [(set (match_operand:SI 1 "register_operand" "=r")
2345           (mem:SI (match_operand:SI   2 "register_operand" "r")))
2346      (set (match_operand:SI 3 "register_operand" "=r")
2347           (mem:SI (plus:SI (match_dup 2) (const_int 4))))
2348     ])]
2349   "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 2"
2350   {
2351     static char load_op[256] = {0};
2352     int count = REGNO (operands[1]) + XVECLEN (operands[0], 0) - 1;
2353     const char *reg_rz = reg_names[count];
2354     sprintf (load_op, \"ldm\t%%1 - %s, (%%2)\", reg_rz);
2355     return load_op;
2356   }
2359 (define_insn "*csky_stmsi12"
2360   [(match_parallel          0 "csky_store_multiple_operation"
2361     [(set (mem:SI (match_operand:SI   1 "register_operand" "r"))
2362           (match_operand:SI 2 "register_operand" "r"))
2363      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
2364           (match_operand:SI 3 "register_operand" "r"))
2365      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
2366           (match_operand:SI 4 "register_operand" "r"))
2367      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
2368           (match_operand:SI 5 "register_operand" "r"))
2369      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
2370           (match_operand:SI 6 "register_operand" "r"))
2371      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
2372           (match_operand:SI 7 "register_operand" "r"))
2373      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
2374           (match_operand:SI 8 "register_operand" "r"))
2375      (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
2376           (match_operand:SI 9 "register_operand" "r"))
2377      (set (mem:SI (plus:SI (match_dup 1) (const_int 32)))
2378           (match_operand:SI 10 "register_operand" "r"))
2379      (set (mem:SI (plus:SI (match_dup 1) (const_int 36)))
2380           (match_operand:SI 11 "register_operand" "r"))
2381      (set (mem:SI (plus:SI (match_dup 1) (const_int 40)))
2382           (match_operand:SI 12 "register_operand" "r"))
2383      (set (mem:SI (plus:SI (match_dup 1) (const_int 44)))
2384           (match_operand:SI 13 "register_operand" "r"))
2385     ])]
2386   "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 12"
2387   {
2388     static char load_op[256] = {0};
2389     int end = REGNO (operands[2]) + XVECLEN (operands[0], 0) - 1;
2390     const char *reg_rz = reg_names[end];
2391     sprintf (load_op, \"stm\t%%2 - %s, (%%1)\", reg_rz);
2392     return load_op;
2393   }
2397 (define_insn "*csky_stmsi11"
2398   [(match_parallel          0 "csky_store_multiple_operation"
2399     [(set (mem:SI (match_operand:SI   1 "register_operand" "r"))
2400           (match_operand:SI 2 "register_operand" "r"))
2401      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
2402           (match_operand:SI 3 "register_operand" "r"))
2403      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
2404           (match_operand:SI 4 "register_operand" "r"))
2405      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
2406           (match_operand:SI 5 "register_operand" "r"))
2407      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
2408           (match_operand:SI 6 "register_operand" "r"))
2409      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
2410           (match_operand:SI 7 "register_operand" "r"))
2411      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
2412           (match_operand:SI 8 "register_operand" "r"))
2413      (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
2414           (match_operand:SI 9 "register_operand" "r"))
2415      (set (mem:SI (plus:SI (match_dup 1) (const_int 32)))
2416           (match_operand:SI 10 "register_operand" "r"))
2417      (set (mem:SI (plus:SI (match_dup 1) (const_int 36)))
2418           (match_operand:SI 11 "register_operand" "r"))
2419      (set (mem:SI (plus:SI (match_dup 1) (const_int 40)))
2420           (match_operand:SI 12 "register_operand" "r"))
2421     ])]
2422   "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 11"
2423   {
2424     static char load_op[256] = {0};
2425     int end = REGNO (operands[2]) + XVECLEN (operands[0], 0) - 1;
2426     const char *reg_rz = reg_names[end];
2427     sprintf (load_op, \"stm\t%%2 - %s, (%%1)\", reg_rz);
2428     return load_op;
2429   }
2433 (define_insn "*csky_stmsi10"
2434   [(match_parallel          0 "csky_store_multiple_operation"
2435     [(set (mem:SI (match_operand:SI   1 "register_operand" "r"))
2436           (match_operand:SI 2 "register_operand" "r"))
2437      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
2438           (match_operand:SI 3 "register_operand" "r"))
2439      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
2440           (match_operand:SI 4 "register_operand" "r"))
2441      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
2442           (match_operand:SI 5 "register_operand" "r"))
2443      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
2444           (match_operand:SI 6 "register_operand" "r"))
2445      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
2446           (match_operand:SI 7 "register_operand" "r"))
2447      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
2448           (match_operand:SI 8 "register_operand" "r"))
2449      (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
2450           (match_operand:SI 9 "register_operand" "r"))
2451      (set (mem:SI (plus:SI (match_dup 1) (const_int 32)))
2452           (match_operand:SI 10 "register_operand" "r"))
2453      (set (mem:SI (plus:SI (match_dup 1) (const_int 36)))
2454           (match_operand:SI 11 "register_operand" "r"))
2455     ])]
2456   "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 10"
2457   {
2458     static char load_op[256] = {0};
2459     int end = REGNO (operands[2]) + XVECLEN (operands[0], 0) - 1;
2460     const char *reg_rz = reg_names[end];
2461     sprintf (load_op, \"stm\t%%2 - %s, (%%1)\", reg_rz);
2462     return load_op;
2463   }
2467 (define_insn "*csky_stmsi9"
2468   [(match_parallel          0 "csky_store_multiple_operation"
2469     [(set (mem:SI (match_operand:SI   1 "register_operand" "r"))
2470           (match_operand:SI 2 "register_operand" "r"))
2471      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
2472           (match_operand:SI 3 "register_operand" "r"))
2473      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
2474           (match_operand:SI 4 "register_operand" "r"))
2475      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
2476           (match_operand:SI 5 "register_operand" "r"))
2477      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
2478           (match_operand:SI 6 "register_operand" "r"))
2479      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
2480           (match_operand:SI 7 "register_operand" "r"))
2481      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
2482           (match_operand:SI 8 "register_operand" "r"))
2483      (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
2484           (match_operand:SI 9 "register_operand" "r"))
2485      (set (mem:SI (plus:SI (match_dup 1) (const_int 32)))
2486           (match_operand:SI 10 "register_operand" "r"))
2487     ])]
2488   "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 9"
2489   {
2490     static char load_op[256] = {0};
2491     int end = REGNO (operands[2]) + XVECLEN (operands[0], 0) - 1;
2492     const char *reg_rz = reg_names[end];
2493     sprintf (load_op, \"stm\t%%2 - %s, (%%1)\", reg_rz);
2494     return load_op;
2495   }
2499 (define_insn "*csky_stmsi8"
2500   [(match_parallel          0 "csky_store_multiple_operation"
2501     [(set (mem:SI (match_operand:SI   1 "register_operand" "r"))
2502           (match_operand:SI 2 "register_operand" "r"))
2503      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
2504           (match_operand:SI 3 "register_operand" "r"))
2505      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
2506           (match_operand:SI 4 "register_operand" "r"))
2507      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
2508           (match_operand:SI 5 "register_operand" "r"))
2509      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
2510           (match_operand:SI 6 "register_operand" "r"))
2511      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
2512           (match_operand:SI 7 "register_operand" "r"))
2513      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
2514           (match_operand:SI 8 "register_operand" "r"))
2515      (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
2516           (match_operand:SI 9 "register_operand" "r"))
2517     ])]
2518   "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 8"
2519   {
2520     static char load_op[256] = {0};
2521     int end = REGNO (operands[2]) + XVECLEN (operands[0], 0) - 1;
2522     const char *reg_rz = reg_names[end];
2523     sprintf (load_op, \"stm\t%%2 - %s, (%%1)\", reg_rz);
2524     return load_op;
2525   }
2529 (define_insn "*csky_stmsi7"
2530   [(match_parallel          0 "csky_store_multiple_operation"
2531     [(set (mem:SI (match_operand:SI   1 "register_operand" "r"))
2532           (match_operand:SI 2 "register_operand" "r"))
2533      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
2534           (match_operand:SI 3 "register_operand" "r"))
2535      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
2536           (match_operand:SI 4 "register_operand" "r"))
2537      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
2538           (match_operand:SI 5 "register_operand" "r"))
2539      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
2540           (match_operand:SI 6 "register_operand" "r"))
2541      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
2542           (match_operand:SI 7 "register_operand" "r"))
2543      (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
2544           (match_operand:SI 8 "register_operand" "r"))
2545     ])]
2546   "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 7"
2547   {
2548     static char load_op[256] = {0};
2549     int end = REGNO (operands[2]) + XVECLEN (operands[0], 0) - 1;
2550     const char *reg_rz = reg_names[end];
2551     sprintf (load_op, \"stm\t%%2 - %s, (%%1)\", reg_rz);
2552     return load_op;
2553   }
2557 (define_insn "*csky_stmsi6"
2558   [(match_parallel          0 "csky_store_multiple_operation"
2559     [(set (mem:SI (match_operand:SI   1 "register_operand" "r"))
2560           (match_operand:SI 2 "register_operand" "r"))
2561      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
2562           (match_operand:SI 3 "register_operand" "r"))
2563      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
2564           (match_operand:SI 4 "register_operand" "r"))
2565      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
2566           (match_operand:SI 5 "register_operand" "r"))
2567      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
2568           (match_operand:SI 6 "register_operand" "r"))
2569      (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
2570           (match_operand:SI 7 "register_operand" "r"))
2571     ])]
2572   "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 6"
2573   {
2574     static char load_op[256] = {0};
2575     int end = REGNO (operands[2]) + XVECLEN (operands[0], 0) - 1;
2576     const char *reg_rz = reg_names[end];
2577     sprintf (load_op, \"stm\t%%2 - %s, (%%1)\", reg_rz);
2578     return load_op;
2579   }
2582 (define_insn "*csky_stmsi5"
2583   [(match_parallel          0 "csky_store_multiple_operation"
2584     [(set (mem:SI (match_operand:SI   1 "register_operand" "r"))
2585           (match_operand:SI 2 "register_operand" "r"))
2586      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
2587           (match_operand:SI 3 "register_operand" "r"))
2588      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
2589           (match_operand:SI 4 "register_operand" "r"))
2590      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
2591           (match_operand:SI 5 "register_operand" "r"))
2592      (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
2593           (match_operand:SI 6 "register_operand" "r"))
2594     ])]
2595   "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 5"
2596   {
2597     static char load_op[256] = {0};
2598     int end = REGNO (operands[2]) + XVECLEN (operands[0], 0) - 1;
2599     const char *reg_rz = reg_names[end];
2600     sprintf (load_op, \"stm\t%%2 - %s, (%%1)\", reg_rz);
2601     return load_op;
2602   }
2606 (define_insn "*csky_stmsi4"
2607   [(match_parallel          0 "csky_store_multiple_operation"
2608     [(set (mem:SI (match_operand:SI   1 "register_operand" "r"))
2609           (match_operand:SI 2 "register_operand" "r"))
2610      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
2611           (match_operand:SI 3 "register_operand" "r"))
2612      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
2613           (match_operand:SI 4 "register_operand" "r"))
2614      (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
2615           (match_operand:SI 5 "register_operand" "r"))
2616     ])]
2617   "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 4"
2618   {
2619     static char load_op[256] = {0};
2620     int end = REGNO (operands[2]) + XVECLEN (operands[0], 0) - 1;
2621     const char *reg_rz = reg_names[end];
2622     sprintf (load_op, \"stm\t%%2 - %s, (%%1)\", reg_rz);
2623     return load_op;
2624   }
2628 (define_insn "*csky_stmsi3"
2629   [(match_parallel          0 "csky_store_multiple_operation"
2630     [(set (mem:SI (match_operand:SI   1 "register_operand" "r"))
2631           (match_operand:SI 2 "register_operand" "r"))
2632      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
2633           (match_operand:SI 3 "register_operand" "r"))
2634      (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
2635           (match_operand:SI 4 "register_operand" "r"))
2636     ])]
2637   "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 3"
2638   {
2639     static char load_op[256] = {0};
2640     int end = REGNO (operands[2]) + XVECLEN (operands[0], 0) - 1;
2641     const char *reg_rz = reg_names[end];
2642     sprintf (load_op, \"stm\t%%2 - %s, (%%1)\", reg_rz);
2643     return load_op;
2644   }
2648 (define_insn "*csky_stmsi2"
2649   [(match_parallel          0 "csky_store_multiple_operation"
2650     [(set (mem:SI (match_operand:SI   1 "register_operand" "r"))
2651           (match_operand:SI 2 "register_operand" "r"))
2652      (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
2653           (match_operand:SI 3 "register_operand" "r"))
2654     ])]
2655   "TARGET_MULTIPLE_STLD && XVECLEN (operands[0], 0) == 2"
2656   {
2657     static char load_op[256] = {0};
2658     int end = REGNO (operands[2]) + XVECLEN (operands[0], 0) - 1;
2659     const char *reg_rz = reg_names[end];
2660     sprintf (load_op, \"stm\t%%2 - %s, (%%1)\", reg_rz);
2661     return load_op;
2662   }
2666 ;; ------------------------------------------------------------------------
2667 ;; Jump and linkage insns
2668 ;; ------------------------------------------------------------------------
2670 (define_expand "tablejump"
2671   [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "r"))
2672               (use (label_ref (match_operand 1 "" "")))])]
2673   ""
2674   "
2675   if (flag_pic)
2676     operands[0] = expand_simple_binop (Pmode, PLUS, operands[0],
2677                                        pic_offset_table_rtx, NULL_RTX,
2678                                        1, OPTAB_DIRECT);
2679   "
2682 (define_insn "*tablejump"
2683   [(set (pc) (match_operand:SI    0 "register_operand" "r"))
2684    (use (label_ref (match_operand 1 ""                 "")))]
2685   ""
2686   "jmp  %0"
2687   [(set_attr "type" "branch_jmp")]
2690 (define_expand "jump"
2691   [(set (pc) (label_ref (match_operand 0 "" "")))]
2692   ""
2693   ""
2696 (define_insn "*csky_jump"
2697   [(set (pc) (label_ref (match_operand 0 "" "")))]
2698   "CSKY_ISA_FEATURE (E2)"
2699   "jbr  %l0"
2700   [(set_attr "type" "branch")]
2703 ;; The length of bsr is not really 5; it's used to distinguish from br32.
2704 ;; Since the length attribute is treated specially it doesn't seem possible
2705 ;; to compute the far_jump attribute directly and use that.
2707 (define_insn "*ck801_ck802_jump"
2708   [(set (pc) (label_ref (match_operand 0 "" "")))]
2709   "CSKY_ISA_FEATURE (E1) || CSKY_ISA_FEATURE (E2)"
2710   "*{
2711     if (get_attr_length (insn) != 5)
2712       return \"jbr\\t%l0\";
2713     else
2714       return \"bsr\\t%l0\\t//far jump\";
2715   }"
2716   [(set_attr "type" "branch")
2717    (set (attr "far_jump")
2718         (if_then_else
2719           (eq_attr "length" "5")
2720           (const_string "yes")
2721           (const_string "no")))
2722    (set (attr "length")
2723         (if_then_else
2724           (and (ge (minus (match_dup 0) (pc)) (const_int -1024))
2725                (le (minus (match_dup 0) (pc)) (const_int 1022)))
2726           (const_int 2)
2727           (if_then_else
2728             (and (ge (minus (match_dup 0) (pc)) (const_int -65536))
2729                  (le (minus (match_dup 0) (pc)) (const_int 65534)))
2730             (const_int 4)
2731             (const_int 5))))]
2734 (define_insn "indirect_jump"
2735   [(set (pc) (match_operand:SI 0 "register_operand" "b,r"))]
2736   ""
2737   "@
2738     jmp\t%0
2739     jmp\t%0"
2740   [(set_attr "length" "2,4")
2741    (set_attr "type" "branch_jmp")]
2745 ;; ------------------------------------------------------------------------
2746 ;; Conditional jump insns
2747 ;; ------------------------------------------------------------------------
2749 (define_expand "cbranchsi4"
2750   [(set (pc)
2751         (if_then_else (match_operator 0 "ordered_comparison_operator"
2752                         [(match_operand:SI 1 "csky_compare_operand")
2753                          (match_operand:SI 2 "nonmemory_operand")])
2754                       (label_ref (match_operand 3 ""))
2755                       (pc)))]
2756   ""
2757   "{
2758     enum rtx_code code = GET_CODE (operands[0]);
2760      if (CSKY_ISA_FEATURE (2E3)
2761          && (code == LE || code == LT || code == GT
2762              || code == GE || code == EQ || code == NE)
2763          && operands[2] == const0_rtx)
2764        {
2765          /* These cases match the jbez, jbnez, etc insns below.
2766             TODO: Handling this in the expander is suboptimal since it
2767             fails to detect cases where the constant 0 would fall out
2768             from subsequent forward propagation or loop optimizers; maybe
2769             it would be better to have a splitter here, but when to split?  */
2770        }
2771      else
2772        {
2773          bool invert = csky_emit_compare (code, operands[1], operands[2]);
2775          if (invert)
2776            emit_jump_insn (gen_csky_jbf (operands[3]));
2777          else
2778            emit_jump_insn (gen_csky_jbt (operands[3]));
2779          DONE;
2780      }
2781   }"
2784 (define_insn "csky_jbt"
2785   [(set (pc)
2786         (if_then_else (ne (reg:CC CSKY_CC_REGNUM) (const_int 0))
2787                       (label_ref (match_operand 0 "" ""))
2788                       (pc)))]
2789   "CSKY_ISA_FEATURE (2E3)"
2790   "jbt\t%l0"
2791   [(set_attr "type" "cbranch")]
2794 (define_insn "csky_jbf"
2795   [(set (pc)
2796         (if_then_else (eq (reg:CC CSKY_CC_REGNUM) (const_int 0))
2797                       (label_ref (match_operand 0 "" ""))
2798                       (pc)))]
2799   "CSKY_ISA_FEATURE (2E3)"
2800   "jbf\t%l0"
2801   [(set_attr "type" "cbranch")]
2805 ;;; CK802 has 32-bit jbt/jbf instructions, but no insn other
2806 ;;; than bsr for far jumps.
2808 (define_insn "ck802_jbt"
2809   [(set (pc) (if_then_else (ne (reg:CC CSKY_CC_REGNUM) (const_int 0))
2810                            (label_ref (match_operand 0 "" ""))
2811                            (pc)))]
2812   "CSKY_ISA_FEATURE (E2)"
2813   {
2814     if (get_attr_length (insn) == 6)
2815       return \"jbf\\t.LCB%=\;bsr\\t%l0\\t//far jump\\n.LCB%=:\";
2816     else
2817       return \"jbt\\t%l0\";
2818    }
2819   [(set_attr "type" "cbranch")
2820    (set (attr "far_jump")
2821         (if_then_else
2822           (eq_attr "length" "6")
2823           (const_string "yes")
2824           (const_string "no")))
2825    (set (attr "length")
2826         (if_then_else
2827           (and (ge (minus (match_dup 0) (pc)) (const_int -1024))
2828                (le (minus (match_dup 0) (pc)) (const_int 1022)))
2829           (const_int 2)
2830           (if_then_else
2831             (and (ge (minus (match_dup 0) (pc)) (const_int -65534))
2832                  (le (minus (match_dup 0) (pc)) (const_int 65534)))
2833             (const_int 4)
2834             (const_int 6))))]
2837 (define_insn "ck802_jbf"
2838   [(set (pc) (if_then_else (eq (reg:CC CSKY_CC_REGNUM) (const_int 0))
2839                            (label_ref (match_operand 0 "" ""))
2840                            (pc)))]
2841   "CSKY_ISA_FEATURE (E2)"
2842   {
2843     if (get_attr_length (insn) == 6)
2844       return \"jbt\\t.LCB%=\;bsr\\t%l0\\t//far jump\\n.LCB%=:\";
2845     else
2846       return \"jbf\\t%l0\";
2847    }
2848   [(set_attr "type" "cbranch")
2849    (set (attr "far_jump")
2850         (if_then_else
2851           (eq_attr "length" "6")
2852           (const_string "yes")
2853           (const_string "no")))
2854    (set (attr "length")
2855         (if_then_else
2856           (and (ge (minus (match_dup 0) (pc)) (const_int -1024))
2857                (le (minus (match_dup 0) (pc)) (const_int 1022)))
2858           (const_int 2)
2859           (if_then_else
2860             (and (ge (minus (match_dup 0) (pc)) (const_int -65534))
2861                  (le (minus (match_dup 0) (pc)) (const_int 65534)))
2862             (const_int 4)
2863             (const_int 6))))]
2866 ;; The length of the bsr case is not really 7; it's used to distinguish
2867 ;; from br32.
2868 ;; Note that we have to adjust the backward range of the jbr case to
2869 ;; account for the jbf in front of it.
2870 (define_insn "ck801_jbt"
2871   [(set (pc) (if_then_else (ne (reg:CC CSKY_CC_REGNUM) (const_int 0))
2872                            (label_ref (match_operand 0 "" ""))
2873                            (pc)))]
2874   "CSKY_ISA_FEATURE (E1)"
2875   {
2876     if (get_attr_length (insn) == 6)
2877       return \"jbf\\t.LCB%=\;jbr\\t%l0\\n.LCB%=:\";
2878     else if (get_attr_length (insn) == 7)
2879       return \"jbf\\t.LCB%=\;bsr\\t%l0\\t//far jump\\n.LCB%=:\";
2880     else
2881       return \"jbt\\t%l0\";
2882    }
2883   [(set_attr "type" "cbranch")
2884    (set (attr "far_jump")
2885         (if_then_else
2886           (eq_attr "length" "7")
2887           (const_string "yes")
2888           (const_string "no")))
2889    (set (attr "length")
2890         (if_then_else
2891           (and (ge (minus (match_dup 0) (pc)) (const_int -1024))
2892                (le (minus (match_dup 0) (pc)) (const_int 1022)))
2893           (const_int 2)
2894           (if_then_else
2895             (and (ge (minus (match_dup 0) (pc)) (const_int -65534))
2896                  (le (minus (match_dup 0) (pc)) (const_int 65534)))
2897             (const_int 6)
2898             (const_int 7))))]
2901 (define_insn "ck801_jbf"
2902   [(set (pc)
2903         (if_then_else (eq (reg:CC CSKY_CC_REGNUM) (const_int 0))
2904                       (label_ref (match_operand 0 "" ""))
2905                       (pc)))]
2906   "CSKY_ISA_FEATURE (E1)"
2907   {
2908     if (get_attr_length (insn) == 6)
2909       return \"jbt\\t.LCB%=\;jbr\\t%l0\\n.LCB%=:\";
2910     else if (get_attr_length (insn) == 7)
2911       return \"jbt\\t.LCB%=\;bsr\\t%l0\\t//far jump\\n.LCB%=:\";
2912     else
2913       return \"jbf\\t%l0\";
2914   }
2915   [(set_attr "type" "cbranch")
2916    (set (attr "far_jump")
2917         (if_then_else
2918           (eq_attr "length" "7")
2919           (const_string "yes")
2920           (const_string "no")))
2921    (set (attr "length")
2922         (if_then_else
2923           (and (ge (minus (match_dup 0) (pc)) (const_int -1024))
2924                (le (minus (match_dup 0) (pc)) (const_int 1022)))
2925           (const_int 2)
2926           (if_then_else
2927             (and (ge (minus (match_dup 0) (pc)) (const_int -65534))
2928                  (le (minus (match_dup 0) (pc)) (const_int 65534)))
2929             (const_int 6)
2930             (const_int 7))))]
2933 (define_code_iterator zero_cond [lt le gt ge eq ne])
2935 (define_code_attr inst [(lt "jblz") (le "jblsz") (gt "jbhz") (ge "jbhsz") (eq "jbez") (ne "jbnez")])
2937 (define_insn "*<inst>"
2938   [(set (pc)
2939         (if_then_else (zero_cond (match_operand:SI 0 "register_operand" "r")
2940                                  (const_int 0))
2941                       (label_ref (match_operand 1 "" ""))
2942                       (pc)))]
2943   "CSKY_ISA_FEATURE (2E3)"
2944   "<inst>\t%0, %l1"
2945   [(set_attr "type" "cbranch")]
2948 ;; ------------------------------------------------------------------------
2949 ;; return insns
2950 ;; ------------------------------------------------------------------------
2952 (define_insn "simple_return"
2953   [(simple_return)]
2954   "reload_completed"
2955   "*
2956     return csky_output_return_instruction ();
2957   "
2960 (define_expand "eh_return"
2961   [(use (match_operand 0 "general_operand" ""))]
2962   ""
2963   "{
2964     emit_insn (gen_csky_eh_return (operands[0]));
2965     DONE;
2966   }"
2969 ;; We can't expand this before we know where the link register is stored.
2970 (define_insn_and_split "csky_eh_return"
2971   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
2972                     VUNSPEC_EH_RETURN)
2973    (clobber (match_scratch:SI 1 "=&r"))]
2974   ""
2975   "#"
2976   "reload_completed"
2977   [(const_int 0)]
2978   "{
2979     csky_set_eh_return_address (operands[0], operands[1]);
2980     DONE;
2981   }"
2984 ;; -------------------------------------------------------------------------
2985 ;; SImode signed integer comparisons
2986 ;; -------------------------------------------------------------------------
2988 (define_insn "*cmpnesi_r"
2989   [(set (reg:CC CSKY_CC_REGNUM)
2990         (ne:CC (match_operand:SI 0 "register_operand" "b,r")
2991                (match_operand:SI 1 "register_operand" "b,r")))]
2992   ""
2993   "@
2994     cmpne\t%0, %1
2995     cmpne\t%0, %1"
2996   [(set_attr "length" "2,4")
2997    (set_attr "type" "cmp")]
3000 ;; cmpnei range is 0-31 for Smart mode.
3001 (define_insn "smart_cmpnesi_i"
3002   [(set (reg:CC CSKY_CC_REGNUM)
3003         (ne:CC (match_operand:SI 0 "register_operand"       "a")
3004                (match_operand:SI 1 "csky_literal_K_operand" "K")))]
3005   "TARGET_MINI_REGISTERS"
3006   "cmpnei\t%0, %1"
3007   [(set_attr "type" "cmp")]
3010 ;; cmpnei range is 0 - 65536 for Fast mode.
3011 (define_insn "fast_cmpnesi_i"
3012   [(set (reg:CC CSKY_CC_REGNUM)
3013         (ne:CC (match_operand:SI 0 "register_operand"       "r")
3014                (match_operand:SI 1 "csky_literal_I_operand" "I")))]
3015   "!TARGET_MINI_REGISTERS && CSKY_ISA_FEATURE (E2)"
3016   "cmpnei\t%0, %1"
3017   [(set_attr "type" "cmp")]
3020 (define_insn "*cmpgtsi"
3021   [(set (reg:CC CSKY_CC_REGNUM)
3022         (gt:CC (match_operand:SI 0 "register_operand" "b,r")
3023                (match_operand:SI 1 "register_operand" "b,r")))]
3024   ""
3025   "cmplt\t%1, %0"
3026   [(set_attr "length" "2,4")
3027    (set_attr "type" "cmp")]
3030 (define_insn "cmpltsi_r"
3031   [(set (reg:CC CSKY_CC_REGNUM)
3032         (lt:CC (match_operand:SI 0 "register_operand" "b,r")
3033                (match_operand:SI 1 "register_operand" "b,r")))]
3034   ""
3035   "cmplt\t%0, %1"
3036   [(set_attr "length" "2,4")
3037    (set_attr "type" "cmp")]
3040 ;; cmplti range is 1-32 for Smart mode.
3041 (define_insn "*smart_cmpltsi_i"
3042   [(set (reg:CC CSKY_CC_REGNUM)
3043         (lt:CC (match_operand:SI 0 "register_operand"       "a")
3044                (match_operand:SI 1 "csky_literal_J_operand" "J")))]
3045   "TARGET_MINI_REGISTERS"
3046   "cmplti\t%0, %1"
3047   [(set_attr "length" "2")
3048    (set_attr "type" "cmp")]
3052 ;; cmplti range is 1-65536 for Fast mode.
3053 (define_insn "*fast_cmpltsi_i"
3054   [(set (reg:CC CSKY_CC_REGNUM)
3055         (lt:CC (match_operand:SI 0 "register_operand"        "a,r")
3056                (match_operand:SI 1 "csky_literal_Uk_operand" "J,Uk")))]
3057   "!TARGET_MINI_REGISTERS && CSKY_ISA_FEATURE (E2)"
3058   "cmplti\t%0, %1"
3059   [(set_attr "length" "2,4")
3060    (set_attr "type" "cmp")]
3063 ; Covers cmplti x,0.
3064 (define_insn "*cskyv2_cmpltsi_0"
3065   [(set (reg:CC CSKY_CC_REGNUM)
3066         (lt:CC (match_operand:SI 0 "register_operand" "a,r")
3067                (const_int 0)))]
3068   "CSKY_ISA_FEATURE (E2)"
3069   "btsti\t%0, 31"
3070   [(set_attr "length" "2,4")
3071    (set_attr "type" "cmp")]
3074 (define_insn "*ck801_cmpltsi_0"
3075   [(set (reg:CC CSKY_CC_REGNUM)
3076         (lt:CC (match_operand:SI 0 "register_operand" "a")
3077                (const_int 0)))]
3078   "CSKY_ISA_FEATURE (E1)"
3079   "btsti\t%0, 31"
3080   [(set_attr "type" "cmp")]
3083 ;; Decrement and test instructions.
3084 ;; In theory decne could be used in conjunction with jbt to implement
3085 ;; doloop_end, but that seems to encourage the loop optimizer to introduce
3086 ;; an additional induction variable and doesn't actually result in tighter
3087 ;; loop code for that reason.
3089 (define_insn "*cskyv2_declt"
3090   [(set (match_operand:SI 0 "register_operand" "=r")
3091         (plus:SI (match_operand:SI 1 "register_operand" "r")
3092                  (match_operand:SI 2 "const_int_operand" "Uh")))
3093    (set (reg:CC CSKY_CC_REGNUM)
3094         (lt:CC (plus:SI (match_dup 1) (match_dup 2))
3095                (const_int 0)))]
3096   "CSKY_ISA_FEATURE (2E3)"
3097   "declt\t%0, %1, %M2"
3100 (define_insn "*cskyv2_decgt"
3101   [(set (match_operand:SI 0 "register_operand" "=r")
3102         (plus:SI (match_operand:SI 1 "register_operand" "r")
3103                  (match_operand:SI 2 "const_int_operand" "Uh")))
3104    (set (reg:CC CSKY_CC_REGNUM)
3105         (gt:CC (plus:SI (match_dup 1) (match_dup 2))
3106                (const_int 0)))]
3107   "CSKY_ISA_FEATURE (2E3)"
3108   "decgt\t%0, %1, %M2"
3111 (define_insn "*cskyv2_decne"
3112   [(set (match_operand:SI 0 "register_operand" "=r")
3113         (plus:SI (match_operand:SI 1 "register_operand" "r")
3114                  (match_operand:SI 2 "const_int_operand" "Uh")))
3115    (set (reg:CC CSKY_CC_REGNUM)
3116         (ne:CC (plus:SI (match_dup 1) (match_dup 2))
3117                (const_int 0)))]
3118   "CSKY_ISA_FEATURE (2E3)"
3119   "decne\t%0, %1, %M2"
3122 ;; -------------------------------------------------------------------------
3123 ;; SImode unsigned integer comparisons
3124 ;; -------------------------------------------------------------------------
3126 (define_insn "cmpgeusi_r"
3127   [(set (reg:CC CSKY_CC_REGNUM)
3128         (geu:CC (match_operand:SI 0 "register_operand" "b,r")
3129                 (match_operand:SI 1 "register_operand" "b,r")))]
3130   ""
3131   "cmphs\t%0, %1"
3132   [(set_attr "length" "2,4")
3133    (set_attr "type" "cmp")]
3136 (define_insn "*smart_cmpgeusi_i"
3137   [(set (reg:CC CSKY_CC_REGNUM)
3138         (geu:CC (match_operand:SI 0 "register_operand"       "a")
3139                 (match_operand:SI 1 "csky_literal_J_operand" "J")))]
3140   "TARGET_MINI_REGISTERS"
3141   "cmphsi\t%0, %1"
3142   [(set_attr "length" "2")
3143    (set_attr "type" "cmp")]
3146 (define_insn "*fast_cmpgeusi_i"
3147   [(set (reg:CC CSKY_CC_REGNUM)
3148         (geu:CC (match_operand:SI 0 "register_operand"        "a,r")
3149                 (match_operand:SI 1 "csky_literal_Uk_operand" "J,Uk")))]
3150   "!TARGET_MINI_REGISTERS && CSKY_ISA_FEATURE (E2)"
3151   "cmphsi\t%0, %1"
3152   [(set_attr "length" "2,4")
3153    (set_attr "type" "cmp")]
3156 (define_insn "*cmpleusi"
3157   [(set (reg:CC CSKY_CC_REGNUM)
3158         (leu:CC (match_operand:SI 0 "register_operand" "b,r")
3159                 (match_operand:SI 1 "register_operand" "b,r")))]
3160   ""
3161   "cmphs\t%1, %0"
3162   [(set_attr "length" "2,4")
3163    (set_attr "type" "cmp")]
3166 ;; -------------------------------------------------------------------------
3167 ;; Function call insns
3168 ;; -------------------------------------------------------------------------
3170 (define_expand "call"
3171   [(parallel [(call (match_operand:SI 0 "" "") (match_operand 1 "" ""))
3172               (clobber (reg:SI CSKY_LR_REGNUM))])]
3173   ""
3174   "
3175   {
3176     rtx pic_ref;
3177     rtx addr_ref = XEXP (operands[0], 0);
3179     if (flag_pic
3180         && (CONSTANT_P (addr_ref)
3181             || csky_symbol_mentioned_p (addr_ref)
3182             || csky_label_mentioned_p (addr_ref)))
3183       {
3184         pic_ref = csky_legitimize_pic_address (addr_ref, 0, false);
3185         operands[0] = gen_rtx_MEM (GET_MODE (pic_ref), pic_ref);
3186       }
3188      if (GET_CODE (operands[0]) == MEM
3189          && ! register_operand (XEXP (operands[0], 0), SImode)
3190          && ! csky_symbolic_address_p (XEXP (operands[0], 0))
3191          && ! (flag_pic
3192                && csky_unspec_operand (XEXP (operands[0], 0), SImode)))
3193        operands[0] = gen_rtx_MEM (GET_MODE (operands[0]),
3194                                   force_reg (Pmode, XEXP (operands[0], 0)));
3195   }"
3199 (define_insn "*call_internal"
3200   [(call (mem:SI (match_operand:SI 0 "csky_call_address_operand" "b,r,S"))
3201          (match_operand 1 "" ""))
3202    (clobber (reg:SI CSKY_LR_REGNUM))]
3203   ""
3204   "@
3205     jsr\t%0
3206     jsr\t%0
3207     jbsr\t%0"
3208   [(set_attr "length" "2,4,4")
3209    (set_attr "type"   "call_jsr,call_jsr,call")]
3212 (define_insn "*call_internal_pic"
3213   [(call (mem:SI (match_operand:SI 0 "csky_unspec_operand" "X"))
3214          (match_operand            1 "" ""))
3215   (clobber (reg:SI CSKY_LR_REGNUM))]
3216   "flag_pic"
3217   "* return csky_output_call (operands, 0);"
3218   [(set_attr "length" "4")]
3221 (define_expand "call_value"
3222   [(parallel [(set (match_operand 0 "register_operand" "")
3223                    (call (match_operand:SI 1 "" "") (match_operand 2 "" "")))
3224               (clobber (reg:SI CSKY_LR_REGNUM))])]
3225   ""
3226   "{
3227     rtx pic_ref;
3228     rtx addr_ref = XEXP (operands[1], 0);
3230     if (flag_pic
3231         && (CONSTANT_P (addr_ref)
3232             || csky_symbol_mentioned_p (addr_ref)
3233             || csky_label_mentioned_p (addr_ref)))
3234       {
3235         pic_ref = csky_legitimize_pic_address (addr_ref, 0, false);
3236         operands[1] = gen_rtx_MEM (GET_MODE (pic_ref), pic_ref);
3237       }
3239      if (GET_CODE (operands[1]) == MEM
3240          && ! register_operand (XEXP (operands[1], 0), SImode)
3241          && ! csky_symbolic_address_p (XEXP (operands[1], 0))
3242          && ! (flag_pic
3243                && csky_unspec_operand (XEXP (operands[1], 0), SImode)))
3244       operands[1] = gen_rtx_MEM (GET_MODE (operands[1]),
3245                                  force_reg (Pmode, XEXP (operands[1], 0)));
3246   }")
3248 ;; Call subroutine returning any type.
3250 (define_expand "untyped_call"
3251   [(parallel [(call (match_operand 0 "" "")
3252         (const_int 0))
3253         (match_operand 1 "" "")
3254         (match_operand 2 "" "")])]
3255   ""
3257   int i;
3259   emit_call_insn (gen_call (operands[0], const0_rtx));
3261   for (int i = 0; i < XVECLEN (operands[2], 0); i++)
3262     emit_clobber (SET_SRC (XVECEXP (operands[2], 0, i)));
3263   emit_insn (gen_blockage ());
3265   for (i = 0; i < XVECLEN (operands[2], 0); i++)
3266     {
3267       rtx set = XVECEXP (operands[2], 0, i);
3268       emit_move_insn (SET_DEST (set), SET_SRC (set));
3269     }
3271   /* The optimizer does not know that the call sets the function value
3272      registers we stored in the result block.  We avoid problems by
3273      claiming that all hard registers are used and clobbered at this
3274      point.  */
3275   emit_insn (gen_blockage ());
3277   DONE;
3280 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3281 ;; all of memory.  This blocks insns from being moved across this point.
3283 (define_insn "blockage"
3284   [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
3285   ""
3286   ""
3287   [(set_attr "length" "0")])
3289 (define_insn "*call_value_internal_vh"
3290   [(set (match_operand:HF               0 "register_operand"          "=v,v,v")
3291         (call (mem:SI (match_operand:SI 1 "csky_call_address_operand" "b, r,S"))
3292               (match_operand 2 "" "")))
3293    (clobber (reg:SI CSKY_LR_REGNUM))]
3294   "TARGET_HARD_FLOAT_ABI && CSKY_ISA_FEATURE (fpv3_hf)"
3295   "@
3296     jsr\t%1
3297     jsr\t%1
3298     jbsr\t%1"
3299   [(set_attr "length" "2,4,4")
3300    (set_attr "type"   "call_jsr,call_jsr,call")]
3303 (define_insn "*call_value_internal_vs"
3304   [(set (match_operand:SF              0 "register_operand"       "=v,v,v")
3305         (call (mem:SI (match_operand:SI 1 "csky_call_address_operand" "b, r,S"))
3306               (match_operand 2 "" "")))
3307    (clobber (reg:SI CSKY_LR_REGNUM))]
3308   "TARGET_HARD_FLOAT_ABI"
3309   "@
3310     jsr\t%1
3311     jsr\t%1
3312     jbsr\t%1"
3313   [(set_attr "length" "2,4,4")
3314    (set_attr "type"   "call_jsr,call_jsr,call")]
3317 (define_insn "*call_value_internal_vd"
3318   [(set (match_operand:DF              0 "register_operand"       "=v,v,v")
3319         (call (mem:SI (match_operand:SI 1 "csky_call_address_operand" "b, r,S"))
3320               (match_operand 2 "" "")))
3321    (clobber (reg:SI CSKY_LR_REGNUM))]
3322   "TARGET_HARD_FLOAT_ABI && TARGET_DOUBLE_FPU"
3323   "@
3324     jsr\t%1
3325     jsr\t%1
3326     jbsr\t%1"
3327   [(set_attr "length" "2,4,4")
3328    (set_attr "type"   "call_jsr,call_jsr,call")]
3331 (define_insn "*call_value_internal_pic_vs"
3332   [(set (match_operand:SF              0 "register_operand"    "=v")
3333         (call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X"))
3334                       (match_operand    2 "" "")))
3335    (clobber (reg:SI CSKY_LR_REGNUM))]
3336   "flag_pic && TARGET_HARD_FLOAT_ABI"
3337   "* return csky_output_call (operands, 1);"
3340 (define_insn "*call_value_internal_pic_vd"
3341   [(set (match_operand:DF              0 "register_operand"    "=v")
3342         (call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X"))
3343                       (match_operand    2 "" "")))
3344    (clobber (reg:SI CSKY_LR_REGNUM))]
3345   "flag_pic && TARGET_HARD_FLOAT_ABI && TARGET_DOUBLE_FPU"
3346   "* return csky_output_call (operands, 1);"
3349 (define_insn "*call_value_internal"
3350   [(set (match_operand                  0 "register_operand"          "=r,r,r")
3351         (call (mem:SI (match_operand:SI 1 "csky_call_address_operand" "b, r,S"))
3352               (match_operand 2 "" "")))
3353    (clobber (reg:SI CSKY_LR_REGNUM))]
3354   ""
3355   "@
3356     jsr\t%1
3357     jsr\t%1
3358     jbsr\t%1"
3359   [(set_attr "length" "2,4,4")
3360    (set_attr "type"   "call_jsr,call_jsr,call")]
3363 (define_insn "*call_value_internal_pic"
3364   [(set (match_operand                  0 "register_operand"    "=r")
3365         (call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X"))
3366                       (match_operand    2 "" "")))
3367    (clobber (reg:SI CSKY_LR_REGNUM))]
3368   "flag_pic"
3369   "* return csky_output_call (operands, 1);"
3372 (define_insn "*call_value_struct"
3373   [(set (match_parallel 0 ""
3374           [(expr_list (match_operand 3 "register_operand" "")
3375                       (match_operand 4 "immediate_operand" ""))
3376            (expr_list (match_operand 5 "register_operand" "")
3377                       (match_operand 6 "immediate_operand" ""))])
3378         (call (mem:SI (match_operand:SI 1 "csky_call_address_operand" "b,r,S"))
3379               (match_operand 2 "" "")))
3380         (clobber (reg:SI CSKY_LR_REGNUM))]
3381   ""
3382   "@
3383     jsr\t%1
3384     jsr\t%1
3385     jbsr\t%1"
3386   [(set_attr "length" "2,4,4")
3387    (set_attr "type"   "call_jsr,call_jsr,call")]
3390 (define_insn "*call_value_struct_pic"
3391   [(set (match_parallel 0 ""
3392           [(expr_list (match_operand 3 "register_operand"  "")
3393                       (match_operand 4 "immediate_operand" ""))
3394            (expr_list (match_operand 5 "register_operand"  "")
3395                       (match_operand 6 "immediate_operand" ""))])
3396         (call (mem:SI (match_operand:SI 1 "csky_unspec_operand" "X"))
3397                       (match_operand    2 "" "")))
3398    (clobber (reg:SI CSKY_LR_REGNUM))]
3399   "flag_pic"
3400   "* return csky_output_call (operands, 1);"
3404 ;; -------------------------------------------------------------
3405 ;; prologue & epilogue
3406 ;; -------------------------------------------------------------
3408 (define_expand "prologue"
3409   [(clobber (const_int 0))]
3410   ""
3411   "
3412   {
3413     csky_expand_prologue ();
3414     DONE;
3415   }"
3418 (define_expand "epilogue"
3419   [(clobber (const_int 0))]
3420   ""
3421   "
3422   {
3423     csky_expand_epilogue ();
3424     DONE;
3425   }"
3428 /* TODO: pushpop */
3429 ;; Push multiple registers to the stack.  Registers are in parallel (use ...)
3430 ;; expressions.  For simplicity, the first register is also in the unspec
3431 ;; part.
3432 (define_insn "*push_multi"
3433   [(match_parallel 2 "registers_push"
3434     [(set (match_operand:BLK 0 "push_memory_operand" "")
3435           (unspec:BLK [(match_operand:SI 1 "register_operand" "")]
3436             UNSPEC_PUSHPOP_MULT))])]
3437   ""
3438   {
3439     int num_saves = XVECLEN (operands[2], 0);
3440     int i;
3441     char pattern[100];
3443     strcpy (pattern, \"push\\t%1\");
3445     for (i = 1; i < num_saves; i++)
3446       {
3447         strcat (pattern, \", \");
3448         strcat (pattern,
3449                 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
3450       }
3452     output_asm_insn (pattern, operands);
3454     return \"\";
3455   }
3456   [(set (attr "length")
3457         (symbol_ref "csky_compute_pushpop_length (operands)"))]
3460 ;; Pop (as used in epilogue RTL)
3462 (define_insn "*pop_multi"
3463   [(match_parallel 2 "registers_pop"
3464     [(return)
3465      (set (match_operand:SI 1 "register_operand" "")
3466           (unspec:SI [(match_operand:SI 0 "pop_memory_operand" "")]
3467             UNSPEC_PUSHPOP_MULT))])]
3468   ""
3469   {
3470     int num_saves = XVECLEN (operands[2], 0);
3471     int i;
3472     char pattern[100];
3474     strcpy (pattern, \"pop\\t%1\");
3476     for (i = 2; i < num_saves; i++)
3477       {
3478         strcat (pattern, \", \");
3479         strcat (pattern,
3480             reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]);
3481       }
3483     output_asm_insn (pattern, operands);
3485     return \"\";
3486   }
3487   [(set (attr "length")
3488         (symbol_ref "csky_compute_pushpop_length (operands)"))]
3492 ;; -------------------------------------------------------------------------
3493 ;; PIC related insns
3494 ;; -------------------------------------------------------------------------
3496 (define_insn "prologue_get_pc"
3497   [(set (reg:SI 28)
3498         (match_operand:SI 0 "" "X"))]
3499   "(GET_CODE (operands[0]) == UNSPEC)
3500    && (XINT (operands[0], 1) == UNSPEC_PIC_SYMBOL_GOTPC_GRS)"
3501   {
3502     operands[0] = XVECEXP (operands[0], 0, 0);
3503     output_asm_insn (\"grs\tgb, %0\", operands);
3504     default_internal_label (asm_out_file, \"L\",
3505                             CODE_LABEL_NUMBER (XEXP (operands[0], 0)));
3506     return \"\";
3507   }
3510 (define_insn "*pic_got_pc"
3511   [(set (match_operand:SI             0 "register_operand" "=r")
3512         (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC_SYMBOL_GOTPC))]
3513   "flag_pic"
3514   "lrw\t%0, %1@GOTPC"
3517 (define_insn "*pic_symbol_gotoff"
3518   [(set (match_operand:SI             0 "register_operand" "=r")
3519         (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC_SYMBOL_GOTOFF))]
3520   "flag_pic"
3521   "lrw\t%0, %1@GOTOFF"
3524 (define_insn "*pic_symbol_got"
3525   [(set (match_operand:SI             0 "register_operand" "=r")
3526         (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC_SYMBOL_GOT))]
3527   "flag_pic"
3528   "lrw\t%0, %1@GOT"
3531 (define_insn "*pic_symbol_plt"
3532   [(set (match_operand:SI             0 "register_operand" "=r")
3533         (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC_SYMBOL_PLT))]
3534   "flag_pic"
3535   "lrw\t%0, %1@PLT"
3538 (define_insn "*pic_symbol_grs"
3539   [(set (match_operand:SI             0 "register_operand" "=r")
3540         (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC_SYMBOL_GRS))]
3541   "flag_pic"
3542   "grs\t%0, %1"
3545 (define_expand "builtin_setjmp_receiver"
3546   [(label_ref (match_operand 0 "" ""))]
3547   "flag_pic"
3548   "{
3549     rtx l1 = gen_label_rtx();
3550     rtx grs_label = gen_rtx_LABEL_REF (SImode, l1);
3551     rtx reg_gb = gen_rtx_REG (SImode, PIC_OFFSET_TABLE_REGNUM);
3552     rtx reg_temp = gen_rtx_REG (SImode, 12);
3554     rtx tmp0_unspec = gen_rtx_UNSPEC (Pmode,
3555                                       gen_rtvec (1, grs_label),
3556                                       UNSPEC_PIC_SYMBOL_GOTPC_GRS);
3557     rtx tmp1_unspec = gen_rtx_UNSPEC (Pmode,
3558                                       gen_rtvec (1, grs_label),
3559                                       UNSPEC_PIC_SYMBOL_GOTPC);
3561     emit_insn (gen_prologue_get_pc (tmp0_unspec));
3562     emit_move_insn (reg_temp, tmp1_unspec);
3563     emit_insn (gen_addsi3 (reg_gb, reg_gb, reg_temp));
3564     emit_use (reg_gb);
3566     DONE;
3567   }"
3570 ;; -------------------------------------------------------------------------
3571 ;; TLS related insns
3572 ;; -------------------------------------------------------------------------
3575 ;; UNSPEC_TLS can take either 2 or 3 operands.  Operand 0 is the symbol_ref,
3576 ;; operand 1 is a CONST_INT identifying the TLS model, and the optional
3577 ;; operand 3 is an UNSPEC_TLS_LABEL.
3578 ;; The 3-operand case is for TLS_GD32, TLS_LDM32, and TLS_IE32.
3579 ;; The 2-operand case is for TLS_LE32 and TLS_LDO32.
3581 ;; Move PC-relative TLS label to reg.  This is used for the TLS_GD32
3582 ;; and TLS_GD32 models (when setting up a call to tls_get_addr) and
3583 ;; also TLS_IE32.
3585 (define_insn "*tls_pcrel_label"
3586   [(set (match_operand:SI             0 "register_operand" "=r")
3587         (unspec:SI [(match_operand:SI 1 "const_int_operand" "")]
3588                    UNSPEC_TLS_LABEL))]
3589   "TARGET_TLS"
3590   "grs\t%0, .LTLS%1"
3591   [(set_attr "length" "4")]
3594 ;; This pattern is used to load the TLS base for the same models as above.
3595 ;; The embedded UNSPEC_TLS_LABEL only identifies the label to emit and
3596 ;; doesn't generate a reference to it; that's handled by the *tls_pcrel_label
3597 ;; pattern above.  The label offset needs to be added to the result stored
3598 ;; in operand 0 by this insn.
3600 (define_insn "*tls_get_symbol_1"
3601   [(set (match_operand:SI                      0 "register_operand" "=r")
3602         (unspec:SI [(match_operand             1 "" "")
3603                     (match_operand             2 "" "")
3604                     (unspec:SI [(match_operand 3 "" "")] UNSPEC_TLS_LABEL)]
3605                    UNSPEC_TLS))]
3606   "TARGET_TLS"
3607   {
3608     default_internal_label (asm_out_file, \"LTLS\", INTVAL (operands[3]));
3609     switch (INTVAL (operands[2]))
3610       {
3611       case TLS_GD32:
3612         return \"lrw\t%0, %1@TLSGD32\";
3613       case TLS_LDM32:
3614         return \"lrw\t%0, %1@TLSLDM32\";
3615       case TLS_IE32:
3616         return \"lrw\t%0, %1@GOTTPOFF\";
3617       default:
3618         return \"\";
3619       }
3620   }
3623 ;; This pattern matches the two-operand form of UNSPEC_TLS.
3625 (define_insn "*tls_get_symbol_2"
3626   [(set (match_operand:SI          0 "register_operand" "=r")
3627         (unspec:SI [(match_operand 1 "" "")
3628                     (match_operand 2 "" "")]
3629                    UNSPEC_TLS))]
3630   "TARGET_TLS"
3631   {
3632     switch (INTVAL (operands[2]))
3633       {
3634       case TLS_LE32:
3635         return \"lrw\t%0, %1@TPOFF\";
3636       case TLS_LDO32:
3637         return \"lrw\t%0, %1@TLSLDO32\";
3638       default:
3639         return \"\";
3640       }
3641   }
3645 ;; -------------------------------------------------------------
3646 ;; Misc insns
3647 ;; -------------------------------------------------------------
3649 (define_insn "nop"
3650   [(const_int 0)]
3651   ""
3652   "nop"
3653   [(set_attr "length" "2")]
3656 (define_insn "trap"
3657   [(trap_if (const_int 1) (const_int 0))]
3658   ""
3659   "bkpt"
3660   [(set (attr "length") (const_int 2))
3661    (set_attr "type" "alu")]
3665 ;; -------------------------------------------------------------
3666 ;; Special patterns for dealing with the constant pool
3667 ;; -------------------------------------------------------------
3669 (define_insn "align_4"
3670   [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
3671   ""
3672   {
3673     assemble_align(32);
3674     return \"\";
3675   }
3676   [(set_attr "length" "0")]
3679 (define_insn "csky_constpool_label"
3680   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_LABEL)]
3681   ""
3682   {
3683     char tmp_label[15];
3684     ASM_GENERATE_INTERNAL_LABEL (tmp_label, \"LCP\", INTVAL (operands[0]));
3685     assemble_label (asm_out_file, tmp_label);
3686     return \"\";
3687   }
3688   [(set_attr "length" "0")]
3691 (define_insn "consttable_4"
3692   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
3693   ""
3694   {
3695     if (CONST_DOUBLE_P (operands[0]))
3696       assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
3697                      SFmode, BITS_PER_WORD);
3698     else
3699       {
3700         assemble_integer (operands[0], 4, BITS_PER_WORD, 1);
3701         mark_symbol_refs_as_used (operands[0]);
3702       }
3703     return \"\";
3704   }
3705   [(set_attr "length" "4")]
3708 (define_insn "consttable_8"
3709   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
3710   ""
3711   {
3712     if (CONST_DOUBLE_P (operands[0]))
3713       assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]),
3714                      DFmode, BITS_PER_WORD);
3715     else
3716       assemble_integer (operands[0], 8, BITS_PER_WORD, 1);
3717     return \"\";
3718   }
3719   [(set_attr "length" "8")]
3722 ;;FIXME record the deferred symbol_ref information with use insn
3723 (define_insn "*cskyv2_use_symbol_ref"
3724   [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_SYMBOL_REF)]
3725   ""
3726   ""
3727   [(set_attr "length" "0")]
3731 ;; ------------------------------------------------------------
3732 ;; switch case optimize
3733 ;; ------------------------------------------------------------
3735 (define_expand "casesi"
3736   [(match_operand:SI 0 "register_operand" "")   ; index to jump on
3737    (match_operand:SI 1 "const_int_operand" "")  ; lower bound
3738    (match_operand:SI 2 "const_int_operand" "")  ; total range (max - min)
3739    (match_operand:SI 3 "" "")                   ; table label
3740    (match_operand:SI 4 "" "")]                  ; Out of range label (default:)
3741   "TARGET_CASESI"
3742   "
3743   {
3744     enum insn_code code;
3745     if (operands[1] != const0_rtx)
3746       {
3747         rtx reg = gen_reg_rtx (SImode);
3748         emit_insn (gen_subsi3 (reg,
3749                                operands[0],
3750                                GEN_INT (INTVAL (operands[1]))));
3751         operands[0] = reg;
3752       }
3754     code = CODE_FOR_csky_casesi_internal;
3756     if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode))
3757       operands[2] = force_reg (SImode,operands[2]);
3759     emit_jump_insn (GEN_FCN ((int) code) (operands[0],operands[2],
3760                     operands[3],operands[4]));
3761     DONE;
3762   }"
3765 (define_expand "csky_casesi_internal"
3766   [(match_operand:SI 0 "register_operand" "")
3767    (match_operand:SI 1 "csky_literal_Uk_operand" "")
3768    (match_operand    2 "" "")
3769    (match_operand    3 "" "")]
3770   ""
3771   {
3772     rtx reg0;
3773     rtx test = gen_rtx_GTU (VOIDmode, operands[0], operands[1]);
3774     emit_jump_insn (gen_cbranchsi4 (test, operands[0], operands[1],
3775                                     operands[3]));
3776     reg0 = gen_rtx_REG (SImode, 0);
3777     emit_move_insn (reg0, operands[0]);
3778     emit_jump_insn (gen_csky_casesi_dispatch (operands[2]));
3779     DONE;
3780   }
3783 (define_insn "csky_casesi_dispatch"
3784   [(parallel [(set (pc) (unspec [(reg:SI 0)
3785                                  (label_ref (match_operand 0 "" ""))]
3786                                 UNSPEC_CSKY_CASESI))
3787               (clobber (reg:SI CSKY_LR_REGNUM))])]
3788   ""
3789   "*return csky_output_casesi (operands);"
3790   [(set_attr "length" "4")]
3793 ;; ------------------------------------------------------------------------
3794 ;; index insns
3795 ;; ------------------------------------------------------------------------
3797 (define_insn "*cskyv2_indexsi_t"
3798   [(set (match_operand:SI 0 "register_operand" "=r")
3799         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
3800                           (const_int 4))
3801                  (match_operand:SI 2 "register_operand" "r")))]
3802   "CSKY_ISA_FEATURE (E2)"
3803   "ixw\t%0, %2, %1"
3806 (define_insn "*cskyv2_indexhi_t"
3807   [(set (match_operand:SI 0 "register_operand" "=r")
3808         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
3809                           (const_int 2))
3810                  (match_operand:SI 2 "register_operand" "r")))]
3811   "CSKY_ISA_FEATURE (E2)"
3812   "ixh\t%0, %2, %1"
3815 (define_insn "*cskyv2_indexdi_t"
3816   [(set (match_operand:SI 0 "register_operand" "=r")
3817         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
3818                           (const_int 8))
3819                  (match_operand:SI 2 "register_operand" "r")))]
3820   "CSKY_ISA_FEATURE (2E3)"
3821   "ixd\t%0, %2, %1"
3824 ;; ------------------------------------------------------------------------
3825 ;; swap insns
3826 ;; ------------------------------------------------------------------------
3828 (define_insn "bswapsi2"
3829   [(set (match_operand:SI 0 "register_operand" "=r")
3830         (bswap:SI (match_operand:SI 1 "register_operand" "r")))]
3831   "CSKY_ISA_FEATURE (E2)"
3832   "revb\t%0, %1"