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