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