]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/csky/csky.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / csky / csky.md
CommitLineData
cc7232b9 1;; Machine description for C-SKY processors.
99dee823 2;; Copyright (C) 2018-2021 Free Software Foundation, Inc.
cc7232b9
J
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)
01d56aea 53 (CSKY_NPARM_FREGS 4)
cc7232b9
J
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
01d56aea 104 VUNSPEC_BLOCKAGE
cc7232b9
J
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"
6d3c2b0a 924 [(set (match_operand:DI 0 "register_operand" "=&b,&r")
cc7232b9
J
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"
6d3c2b0a 1122 [(set (match_operand:DI 0 "register_operand" "=&b,&r")
cc7232b9
J
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
01d56aea
J
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)
cc7232b9
J
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)