comparison gcc/config/nios2/nios2.md @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children 84e7813d76e9
comparison
equal deleted inserted replaced
68:561a7518be6b 111:04ced10e8804
1 ;; Machine Description for Altera Nios II.
2 ;; Copyright (C) 2012-2017 Free Software Foundation, Inc.
3 ;; Contributed by Jonah Graham (jgraham@altera.com) and
4 ;; Will Reece (wreece@altera.com).
5 ;; Contributed by Mentor Graphics, Inc.
6 ;;
7 ;; This file is part of GCC.
8 ;;
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; any later version.
13 ;;
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
18 ;;
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
22
23 ;; Register numbers
24 (define_constants
25 [
26 (FIRST_RETVAL_REGNO 2) ; Return value registers
27 (LAST_RETVAL_REGNO 3) ;
28 (FIRST_ARG_REGNO 4) ; Argument registers
29 (LAST_ARG_REGNO 7) ;
30
31 (TP_REGNO 23) ; Thread pointer register
32 (GP_REGNO 26) ; Global pointer register
33 (SP_REGNO 27) ; Stack pointer register
34 (FP_REGNO 28) ; Frame pointer register
35 (EA_REGNO 29) ; Exception return address register
36 (RA_REGNO 31) ; Return address register
37 (LAST_GP_REG 31) ; Last general purpose register
38
39 ;; Target register definitions
40 (STATIC_CHAIN_REGNUM 12)
41 (STACK_POINTER_REGNUM 27)
42 (HARD_FRAME_POINTER_REGNUM 28)
43 (PC_REGNUM 37)
44 (FRAME_POINTER_REGNUM 38)
45 (ARG_POINTER_REGNUM 39)
46 (FIRST_PSEUDO_REGISTER 40)
47 ]
48 )
49
50 ;; Enumeration of UNSPECs
51
52 (define_c_enum "unspecv" [
53 UNSPECV_BLOCKAGE
54 UNSPECV_WRCTL
55 UNSPECV_RDCTL
56 UNSPECV_FWRX
57 UNSPECV_FWRY
58 UNSPECV_FRDXLO
59 UNSPECV_FRDXHI
60 UNSPECV_FRDY
61 UNSPECV_CUSTOM_NXX
62 UNSPECV_CUSTOM_XNXX
63 UNSPECV_LDXIO
64 UNSPECV_STXIO
65 UNSPECV_RDPRS
66 UNSPECV_FLUSHD
67 UNSPECV_FLUSHDA
68 UNSPECV_WRPIE
69 UNSPECV_ENI
70 UNSPECV_LDEX
71 UNSPECV_LDSEX
72 UNSPECV_STEX
73 UNSPECV_STSEX
74 ])
75
76 (define_c_enum "unspec" [
77 UNSPEC_FCOS
78 UNSPEC_FSIN
79 UNSPEC_FTAN
80 UNSPEC_FATAN
81 UNSPEC_FEXP
82 UNSPEC_FLOG
83 UNSPEC_ROUND
84 UNSPEC_LOAD_GOT_REGISTER
85 UNSPEC_PIC_SYM
86 UNSPEC_PIC_CALL_SYM
87 UNSPEC_PIC_GOTOFF_SYM
88 UNSPEC_LOAD_TLS_IE
89 UNSPEC_ADD_TLS_LE
90 UNSPEC_ADD_TLS_GD
91 UNSPEC_ADD_TLS_LDM
92 UNSPEC_ADD_TLS_LDO
93 UNSPEC_EH_RETURN
94 UNSPEC_SYNC
95 ])
96
97
98 ;; Instruction scheduler
99
100 ; No schedule info is currently available, using an assumption that no
101 ; instruction can use the results of the previous instruction without
102 ; incuring a stall.
103
104 ; length of an instruction (in bytes)
105 (define_attr "length" ""
106 (if_then_else (match_test "nios2_cdx_narrow_form_p (insn)")
107 (const_int 2)
108 (const_int 4)))
109
110 (define_attr "type"
111 "unknown,complex,control,alu,cond_alu,st,ld,stwm,ldwm,push,pop,mul,div,\
112 custom,add,sub,mov,and,or,xor,neg,not,sll,srl,sra,rol,ror,nop"
113 (const_string "complex"))
114
115 (define_asm_attributes
116 [(set_attr "length" "4")
117 (set_attr "type" "complex")])
118
119 (define_automaton "nios2")
120 (automata_option "v")
121 ;(automata_option "no-minimization")
122 (automata_option "ndfa")
123
124 ; The nios2 pipeline is fairly straightforward for the fast model.
125 ; Every alu operation is pipelined so that an instruction can
126 ; be issued every cycle. However, there are still potential
127 ; stalls which this description tries to deal with.
128
129 (define_cpu_unit "cpu" "nios2")
130
131 (define_insn_reservation "complex" 1
132 (eq_attr "type" "complex")
133 "cpu")
134
135 (define_insn_reservation "control" 1
136 (eq_attr "type" "control,pop")
137 "cpu")
138
139 (define_insn_reservation "alu" 1
140 (eq_attr "type" "alu,add,sub,mov,and,or,xor,neg,not")
141 "cpu")
142
143 (define_insn_reservation "cond_alu" 1
144 (eq_attr "type" "cond_alu")
145 "cpu")
146
147 (define_insn_reservation "st" 1
148 (eq_attr "type" "st,stwm,push")
149 "cpu")
150
151 (define_insn_reservation "custom" 1
152 (eq_attr "type" "custom")
153 "cpu")
154
155 ; shifts, muls and lds have three cycle latency
156 (define_insn_reservation "ld" 3
157 (eq_attr "type" "ld,ldwm")
158 "cpu")
159
160 (define_insn_reservation "shift" 3
161 (eq_attr "type" "sll,srl,sra,rol,ror")
162 "cpu")
163
164 (define_insn_reservation "mul" 3
165 (eq_attr "type" "mul")
166 "cpu")
167
168 (define_insn_reservation "div" 1
169 (eq_attr "type" "div")
170 "cpu")
171
172 (include "predicates.md")
173 (include "constraints.md")
174
175
176 ;; Move instructions
177
178 (define_mode_iterator M [QI HI SI])
179
180 (define_expand "mov<mode>"
181 [(set (match_operand:M 0 "nonimmediate_operand" "")
182 (match_operand:M 1 "general_operand" ""))]
183 ""
184 {
185 if (nios2_emit_move_sequence (operands, <MODE>mode))
186 DONE;
187 })
188
189 (define_insn "*high"
190 [(set (match_operand:SI 0 "register_operand" "=r")
191 (high:SI (match_operand:SI 1 "immediate_operand" "i")))]
192 ""
193 "movhi\\t%0, %H1"
194 [(set_attr "type" "alu")])
195
196 (define_insn "*lo_sum"
197 [(set (match_operand:SI 0 "register_operand" "=r")
198 (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
199 (match_operand:SI 2 "immediate_operand" "i")))]
200 ""
201 "addi\\t%0, %1, %L2"
202 [(set_attr "type" "alu")])
203
204 (define_insn_and_split "movqi_internal"
205 [(set (match_operand:QI 0 "nonimmediate_operand" "=m, r,r")
206 (match_operand:QI 1 "general_operand" "rM,m,rI"))]
207 "(register_operand (operands[0], QImode)
208 || reg_or_0_operand (operands[1], QImode))"
209 {
210 switch (which_alternative)
211 {
212 case 0:
213 if (get_attr_length (insn) != 2)
214 return "stb%o0\\t%z1, %0";
215 else if (const_0_operand (operands[1], QImode))
216 return "stbz.n\\t%z1, %0";
217 else
218 return "stb.n\\t%z1, %0";
219 case 1:
220 return "ldbu%o1%.\\t%0, %1";
221 case 2:
222 return "mov%i1%.\\t%0, %z1";
223 default:
224 gcc_unreachable ();
225 }
226 }
227 "(nios2_symbolic_memory_operand_p (operands[0])
228 || nios2_symbolic_memory_operand_p (operands[1]))"
229 [(set (match_dup 0) (match_dup 1))]
230 {
231 if (nios2_symbolic_memory_operand_p (operands[0]))
232 operands[0] = nios2_split_symbolic_memory_operand (operands[0]);
233 else
234 operands[1] = nios2_split_symbolic_memory_operand (operands[1]);
235 }
236 [(set_attr "type" "st,ld,mov")])
237
238 (define_insn_and_split "movhi_internal"
239 [(set (match_operand:HI 0 "nonimmediate_operand" "=m, r,r")
240 (match_operand:HI 1 "general_operand" "rM,m,rI"))]
241 "(register_operand (operands[0], HImode)
242 || reg_or_0_operand (operands[1], HImode))"
243 {
244 switch (which_alternative)
245 {
246 case 0:
247 return "sth%o0%.\\t%z1, %0";
248 case 1:
249 return "ldhu%o1%.\\t%0, %1";
250 case 2:
251 return "mov%i1%.\\t%0, %z1";
252 default:
253 gcc_unreachable ();
254 }
255 }
256 "(nios2_symbolic_memory_operand_p (operands[0])
257 || nios2_symbolic_memory_operand_p (operands[1]))"
258 [(set (match_dup 0) (match_dup 1))]
259 {
260 if (nios2_symbolic_memory_operand_p (operands[0]))
261 operands[0] = nios2_split_symbolic_memory_operand (operands[0]);
262 else
263 operands[1] = nios2_split_symbolic_memory_operand (operands[1]);
264 }
265 [(set_attr "type" "st,ld,mov")])
266
267 (define_insn_and_split "movsi_internal"
268 [(set (match_operand:SI 0 "nonimmediate_operand" "=m, r,r, r")
269 (match_operand:SI 1 "general_operand" "rM,m,rIJK,S"))]
270 "(register_operand (operands[0], SImode)
271 || reg_or_0_operand (operands[1], SImode))"
272 {
273 switch (which_alternative)
274 {
275 case 0:
276 if (get_attr_length (insn) != 2)
277 return "stw%o0\\t%z1, %0";
278 else if (stack_memory_operand (operands[0], SImode))
279 return "stwsp.n\\t%z1, %0";
280 else if (const_0_operand (operands[1], SImode))
281 return "stwz.n\\t%z1, %0";
282 else
283 return "stw.n\\t%z1, %0";
284 case 1:
285 if (get_attr_length (insn) != 2)
286 return "ldw%o1\\t%0, %1";
287 else if (stack_memory_operand (operands[1], SImode))
288 return "ldwsp.n\\t%0, %1";
289 else
290 return "ldw.n\\t%0, %1";
291 case 2:
292 return "mov%i1%.\\t%0, %z1";
293 case 3:
294 return "addi\\t%0, gp, %%gprel(%1)";
295 default:
296 gcc_unreachable ();
297 }
298 }
299 "(nios2_symbolic_memory_operand_p (operands[0])
300 || nios2_symbolic_memory_operand_p (operands[1])
301 || nios2_large_constant_p (operands[1]))"
302 [(set (match_dup 0) (match_dup 1))]
303 {
304 if (nios2_symbolic_memory_operand_p (operands[0]))
305 operands[0] = nios2_split_symbolic_memory_operand (operands[0]);
306 else if (nios2_symbolic_memory_operand_p (operands[1]))
307 operands[1] = nios2_split_symbolic_memory_operand (operands[1]);
308 else
309 operands[1] = nios2_split_large_constant (operands[1], operands[0]);
310 }
311 [(set_attr "type" "st,ld,mov,alu")])
312
313 (define_mode_iterator BH [QI HI])
314 (define_mode_iterator BHW [QI HI SI])
315 (define_mode_attr bh [(QI "b") (HI "h")])
316 (define_mode_attr bhw [(QI "b") (HI "h") (SI "w")])
317 (define_mode_attr bhw_uns [(QI "bu") (HI "hu") (SI "w")])
318
319 (define_insn "ld<bhw_uns>io"
320 [(set (match_operand:BHW 0 "register_operand" "=r")
321 (unspec_volatile:BHW
322 [(match_operand:BHW 1 "ldstio_memory_operand" "w")] UNSPECV_LDXIO))]
323 ""
324 "ld<bhw_uns>io\\t%0, %1"
325 [(set_attr "type" "ld")])
326
327 (define_expand "ld<bh>io"
328 [(set (match_operand:BH 0 "register_operand" "=r")
329 (match_operand:BH 1 "ldstio_memory_operand" "w"))]
330 ""
331 {
332 rtx tmp = gen_reg_rtx (SImode);
333 emit_insn (gen_ld<bh>io_signed (tmp, operands[1]));
334 emit_insn (gen_mov<mode> (operands[0], gen_lowpart (<MODE>mode, tmp)));
335 DONE;
336 })
337
338 (define_insn "ld<bh>io_signed"
339 [(set (match_operand:SI 0 "register_operand" "=r")
340 (sign_extend:SI
341 (unspec_volatile:BH
342 [(match_operand:BH 1 "ldstio_memory_operand" "w")] UNSPECV_LDXIO)))]
343 ""
344 "ld<bh>io\\t%0, %1"
345 [(set_attr "type" "ld")])
346
347 (define_insn "st<bhw>io"
348 [(set (match_operand:BHW 0 "ldstio_memory_operand" "=w")
349 (unspec_volatile:BHW
350 [(match_operand:BHW 1 "reg_or_0_operand" "rM")] UNSPECV_STXIO))]
351 ""
352 "st<bhw>io\\t%z1, %0"
353 [(set_attr "type" "st")])
354
355
356 ;; QI to [HI, SI] extension patterns are collected together
357 (define_mode_iterator QX [HI SI])
358
359 ;; Zero extension patterns
360 (define_insn_and_split "zero_extendhisi2"
361 [(set (match_operand:SI 0 "register_operand" "=r,r")
362 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
363 ""
364 "@
365 andi%.\\t%0, %1, 0xffff
366 ldhu%o1%.\\t%0, %1"
367 "nios2_symbolic_memory_operand_p (operands[1])"
368 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))]
369 {
370 operands[1] = nios2_split_symbolic_memory_operand (operands[1]);
371 }
372 [(set_attr "type" "and,ld")])
373
374 (define_insn_and_split "zero_extendqi<mode>2"
375 [(set (match_operand:QX 0 "register_operand" "=r,r")
376 (zero_extend:QX (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
377 ""
378 "@
379 andi%.\\t%0, %1, 0xff
380 ldbu%o1%.\\t%0, %1"
381 "nios2_symbolic_memory_operand_p (operands[1])"
382 [(set (match_dup 0) (zero_extend:QX (match_dup 1)))]
383 {
384 operands[1] = nios2_split_symbolic_memory_operand (operands[1]);
385 }
386 [(set_attr "type" "and,ld")])
387
388 ;; Sign extension patterns
389
390 (define_insn_and_split "extendhisi2"
391 [(set (match_operand:SI 0 "register_operand" "=r,r")
392 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
393 ""
394 "@
395 #
396 ldh%o1%.\\t%0, %1"
397 "nios2_symbolic_memory_operand_p (operands[1])"
398 [(set (match_dup 0) (sign_extend:SI (match_dup 1)))]
399 {
400 operands[1] = nios2_split_symbolic_memory_operand (operands[1]);
401 }
402 [(set_attr "type" "alu,ld")])
403
404 (define_insn_and_split "extendqi<mode>2"
405 [(set (match_operand:QX 0 "register_operand" "=r,r")
406 (sign_extend:QX (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
407 ""
408 "@
409 #
410 ldb%o1%.\\t%0, %1"
411 "nios2_symbolic_memory_operand_p (operands[1])"
412 [(set (match_dup 0) (sign_extend:QX (match_dup 1)))]
413 {
414 operands[1] = nios2_split_symbolic_memory_operand (operands[1]);
415 }
416 [(set_attr "type" "alu,ld")])
417
418 ;; Split patterns for register alternative cases.
419 (define_split
420 [(set (match_operand:SI 0 "register_operand" "")
421 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
422 "reload_completed"
423 [(set (match_dup 0)
424 (and:SI (match_dup 1) (const_int 65535)))
425 (set (match_dup 0)
426 (xor:SI (match_dup 0) (const_int 32768)))
427 (set (match_dup 0)
428 (plus:SI (match_dup 0) (const_int -32768)))]
429 "operands[1] = gen_lowpart (SImode, operands[1]);")
430
431 (define_split
432 [(set (match_operand:QX 0 "register_operand" "")
433 (sign_extend:QX (match_operand:QI 1 "register_operand" "")))]
434 "reload_completed"
435 [(set (match_dup 0)
436 (and:SI (match_dup 1) (const_int 255)))
437 (set (match_dup 0)
438 (xor:SI (match_dup 0) (const_int 128)))
439 (set (match_dup 0)
440 (plus:SI (match_dup 0) (const_int -128)))]
441 "operands[0] = gen_lowpart (SImode, operands[0]);
442 operands[1] = gen_lowpart (SImode, operands[1]);")
443
444
445 ;; Arithmetic Operations
446
447 (define_insn "addsi3"
448 [(set (match_operand:SI 0 "register_operand" "=r")
449 (plus:SI (match_operand:SI 1 "register_operand" "%r")
450 (match_operand:SI 2 "add_regimm_operand" "rIT")))]
451 ""
452 {
453 return nios2_add_insn_asm (insn, operands);
454 }
455 [(set_attr "type" "add")])
456
457 (define_insn "subsi3"
458 [(set (match_operand:SI 0 "register_operand" "=r")
459 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
460 (match_operand:SI 2 "register_operand" "r")))]
461 ""
462 "sub%.\\t%0, %z1, %2"
463 [(set_attr "type" "sub")])
464
465 (define_insn "mulsi3"
466 [(set (match_operand:SI 0 "register_operand" "=r")
467 (mult:SI (match_operand:SI 1 "register_operand" "%r")
468 (match_operand:SI 2 "arith_operand" "rI")))]
469 "TARGET_HAS_MUL"
470 "mul%i2\\t%0, %1, %z2"
471 [(set_attr "type" "mul")])
472
473 (define_expand "divsi3"
474 [(set (match_operand:SI 0 "register_operand" "=r")
475 (div:SI (match_operand:SI 1 "register_operand" "r")
476 (match_operand:SI 2 "register_operand" "r")))]
477 ""
478 {
479 if (!TARGET_HAS_DIV)
480 {
481 if (TARGET_FAST_SW_DIV)
482 {
483 nios2_emit_expensive_div (operands, SImode);
484 DONE;
485 }
486 else
487 FAIL;
488 }
489 })
490
491 (define_insn "divsi3_insn"
492 [(set (match_operand:SI 0 "register_operand" "=r")
493 (div:SI (match_operand:SI 1 "register_operand" "r")
494 (match_operand:SI 2 "register_operand" "r")))]
495 "TARGET_HAS_DIV"
496 "div\\t%0, %1, %2"
497 [(set_attr "type" "div")])
498
499 (define_insn "udivsi3"
500 [(set (match_operand:SI 0 "register_operand" "=r")
501 (udiv:SI (match_operand:SI 1 "register_operand" "r")
502 (match_operand:SI 2 "register_operand" "r")))]
503 "TARGET_HAS_DIV"
504 "divu\\t%0, %1, %2"
505 [(set_attr "type" "div")])
506
507 (define_code_iterator EXTEND [sign_extend zero_extend])
508 (define_code_attr us [(sign_extend "s") (zero_extend "u")])
509 (define_code_attr mul [(sign_extend "mul") (zero_extend "umul")])
510
511 (define_insn "<us>mulsi3_highpart"
512 [(set (match_operand:SI 0 "register_operand" "=r")
513 (truncate:SI
514 (lshiftrt:DI
515 (mult:DI (EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
516 (EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
517 (const_int 32))))]
518 "TARGET_HAS_MULX"
519 "mulx<us><us>\\t%0, %1, %2"
520 [(set_attr "type" "mul")])
521
522 (define_expand "<mul>sidi3"
523 [(set (match_operand:DI 0 "register_operand" "")
524 (mult:DI (EXTEND:DI (match_operand:SI 1 "register_operand" ""))
525 (EXTEND:DI (match_operand:SI 2 "register_operand" ""))))]
526 "TARGET_HAS_MULX"
527 {
528 rtx hi = gen_reg_rtx (SImode);
529 rtx lo = gen_reg_rtx (SImode);
530
531 emit_insn (gen_<us>mulsi3_highpart (hi, operands[1], operands[2]));
532 emit_insn (gen_mulsi3 (lo, operands[1], operands[2]));
533 emit_move_insn (gen_lowpart (SImode, operands[0]), lo);
534 emit_move_insn (gen_highpart (SImode, operands[0]), hi);
535 DONE;
536 })
537
538
539 ;; Negate and ones complement
540
541 (define_insn "negsi2"
542 [(set (match_operand:SI 0 "register_operand" "=r")
543 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
544 ""
545 {
546 if (get_attr_length (insn) == 2)
547 return "neg.n\\t%0, %1";
548 else
549 return "sub\\t%0, zero, %1";
550 }
551 [(set_attr "type" "neg")])
552
553 (define_insn "one_cmplsi2"
554 [(set (match_operand:SI 0 "register_operand" "=r")
555 (not:SI (match_operand:SI 1 "register_operand" "r")))]
556 ""
557 {
558 if (get_attr_length (insn) == 2)
559 return "not.n\\t%0, %1";
560 else
561 return "nor\\t%0, zero, %1";
562 }
563 [(set_attr "type" "not")])
564
565
566 ;; Integer logical Operations
567
568 (define_insn "andsi3"
569 [(set (match_operand:SI 0 "register_operand" "=r")
570 (and:SI (match_operand:SI 1 "register_operand" "%r")
571 (match_operand:SI 2 "and_operand" "rJKP")))]
572 ""
573 "and%x2%.\\t%0, %1, %y2"
574 [(set_attr "type" "and")])
575
576 (define_code_iterator LOGICAL [ior xor])
577 (define_code_attr logical_asm [(ior "or") (xor "xor")])
578
579 (define_insn "<code>si3"
580 [(set (match_operand:SI 0 "register_operand" "=r")
581 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r")
582 (match_operand:SI 2 "logical_operand" "rJK")))]
583 ""
584 "<logical_asm>%x2%.\\t%0, %1, %y2"
585 [(set_attr "type" "<logical_asm>")])
586
587 (define_insn "*norsi3"
588 [(set (match_operand:SI 0 "register_operand" "=r")
589 (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r"))
590 (not:SI (match_operand:SI 2 "register_operand" "r"))))]
591 ""
592 "nor\\t%0, %1, %2"
593 [(set_attr "type" "alu")])
594
595
596 ;; Shift instructions
597
598 (define_code_iterator SHIFT [ashift ashiftrt lshiftrt rotate])
599 (define_code_attr shift_op [(ashift "ashl") (ashiftrt "ashr")
600 (lshiftrt "lshr") (rotate "rotl")])
601 (define_code_attr shift_asm [(ashift "sll") (ashiftrt "sra")
602 (lshiftrt "srl") (rotate "rol")])
603
604 (define_insn "<shift_op>si3"
605 [(set (match_operand:SI 0 "register_operand" "=r")
606 (SHIFT:SI (match_operand:SI 1 "register_operand" "r")
607 (match_operand:SI 2 "shift_operand" "rL")))]
608 ""
609 "<shift_asm>%i2%.\\t%0, %1, %z2"
610 [(set_attr "type" "<shift_asm>")])
611
612 (define_insn "rotrsi3"
613 [(set (match_operand:SI 0 "register_operand" "=r")
614 (rotatert:SI (match_operand:SI 1 "register_operand" "r")
615 (match_operand:SI 2 "register_operand" "r")))]
616 ""
617 "ror\\t%0, %1, %2"
618 [(set_attr "type" "ror")])
619
620 ;; Nios II R2 Bit Manipulation Extension (BMX), provides
621 ;; bit merge/insertion/extraction instructions.
622
623 (define_insn "*merge"
624 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
625 (match_operand:SI 1 "const_shift_operand" "L")
626 (match_operand:SI 2 "const_shift_operand" "L"))
627 (zero_extract:SI (match_operand:SI 3 "register_operand" "r")
628 (match_dup 1) (match_dup 2)))]
629 "TARGET_HAS_BMX"
630 {
631 operands[4] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[2]) - 1);
632 return "merge\\t%0, %3, %4, %2";
633 }
634 [(set_attr "type" "alu")])
635
636 (define_insn "extzv"
637 [(set (match_operand:SI 0 "register_operand" "=r")
638 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
639 (match_operand:SI 2 "const_shift_operand" "L")
640 (match_operand:SI 3 "const_shift_operand" "L")))]
641 "TARGET_HAS_BMX"
642 {
643 operands[4] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]) - 1);
644 return "extract\\t%0, %1, %4, %3";
645 }
646 [(set_attr "type" "alu")])
647
648 (define_insn "insv"
649 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
650 (match_operand:SI 1 "const_shift_operand" "L")
651 (match_operand:SI 2 "const_shift_operand" "L"))
652 (match_operand:SI 3 "reg_or_0_operand" "rM"))]
653 "TARGET_HAS_BMX"
654 {
655 operands[4] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[2]) - 1);
656 return "insert\\t%0, %z3, %4, %2";
657 }
658 [(set_attr "type" "alu")])
659
660
661
662 ;; Floating point instructions
663
664 ;; Mode iterator for single/double float
665 (define_mode_iterator F [SF DF])
666 (define_mode_attr f [(SF "s") (DF "d")])
667
668 ;; Basic arithmetic instructions
669 (define_code_iterator FOP3 [plus minus mult div])
670 (define_code_attr fop3 [(plus "add") (minus "sub") (mult "mul") (div "div")])
671
672 (define_insn "<fop3><mode>3"
673 [(set (match_operand:F 0 "register_operand" "=r")
674 (FOP3:F (match_operand:F 1 "register_operand" "r")
675 (match_operand:F 2 "register_operand" "r")))]
676 "nios2_fpu_insn_enabled (n2fpu_f<fop3><f>)"
677 { return nios2_fpu_insn_asm (n2fpu_f<fop3><f>); }
678 [(set_attr "type" "custom")])
679
680 ;; Floating point min/max operations
681 (define_code_iterator SMINMAX [smin smax])
682 (define_code_attr minmax [(smin "min") (smax "max")])
683 (define_insn "<code><mode>3"
684 [(set (match_operand:F 0 "register_operand" "=r")
685 (SMINMAX:F (match_operand:F 1 "register_operand" "r")
686 (match_operand:F 2 "register_operand" "r")))]
687 "nios2_fpu_insn_enabled (n2fpu_f<minmax><f>)"
688 { return nios2_fpu_insn_asm (n2fpu_f<minmax><f>); }
689 [(set_attr "type" "custom")])
690
691 ;; These 2-operand FP operations can be collected together
692 (define_code_iterator FOP2 [abs neg sqrt])
693 (define_insn "<code><mode>2"
694 [(set (match_operand:F 0 "register_operand" "=r")
695 (FOP2:F (match_operand:F 1 "register_operand" "r")))]
696 "nios2_fpu_insn_enabled (n2fpu_f<code><f>)"
697 { return nios2_fpu_insn_asm (n2fpu_f<code><f>); }
698 [(set_attr "type" "custom")])
699
700 ;; X, Y register access instructions
701 (define_insn "nios2_fwrx"
702 [(unspec_volatile [(match_operand:DF 0 "register_operand" "r")] UNSPECV_FWRX)]
703 "nios2_fpu_insn_enabled (n2fpu_fwrx)"
704 { return nios2_fpu_insn_asm (n2fpu_fwrx); }
705 [(set_attr "type" "custom")])
706
707 (define_insn "nios2_fwry"
708 [(unspec_volatile [(match_operand:SF 0 "register_operand" "r")] UNSPECV_FWRY)]
709 "nios2_fpu_insn_enabled (n2fpu_fwry)"
710 { return nios2_fpu_insn_asm (n2fpu_fwry); }
711 [(set_attr "type" "custom")])
712
713 ;; The X, Y read insns uses an int iterator
714 (define_int_iterator UNSPEC_READ_XY [UNSPECV_FRDXLO UNSPECV_FRDXHI
715 UNSPECV_FRDY])
716 (define_int_attr read_xy [(UNSPECV_FRDXLO "frdxlo") (UNSPECV_FRDXHI "frdxhi")
717 (UNSPECV_FRDY "frdy")])
718 (define_insn "nios2_<read_xy>"
719 [(set (match_operand:SF 0 "register_operand" "=r")
720 (unspec_volatile:SF [(const_int 0)] UNSPEC_READ_XY))]
721 "nios2_fpu_insn_enabled (n2fpu_<read_xy>)"
722 { return nios2_fpu_insn_asm (n2fpu_<read_xy>); }
723 [(set_attr "type" "custom")])
724
725 ;; Various math functions
726 (define_int_iterator MATHFUNC
727 [UNSPEC_FCOS UNSPEC_FSIN UNSPEC_FTAN UNSPEC_FATAN UNSPEC_FEXP UNSPEC_FLOG])
728 (define_int_attr mathfunc [(UNSPEC_FCOS "cos") (UNSPEC_FSIN "sin")
729 (UNSPEC_FTAN "tan") (UNSPEC_FATAN "atan")
730 (UNSPEC_FEXP "exp") (UNSPEC_FLOG "log")])
731
732 (define_insn "<mathfunc><mode>2"
733 [(set (match_operand:F 0 "register_operand" "=r")
734 (unspec:F [(match_operand:F 1 "register_operand" "r")] MATHFUNC))]
735 "nios2_fpu_insn_enabled (n2fpu_f<mathfunc><f>)"
736 { return nios2_fpu_insn_asm (n2fpu_f<mathfunc><f>); }
737 [(set_attr "type" "custom")])
738
739 ;; Converting between floating point and fixed point
740
741 (define_code_iterator FLOAT [float unsigned_float])
742 (define_code_iterator FIX [fix unsigned_fix])
743
744 (define_code_attr conv_op [(float "float") (unsigned_float "floatuns")
745 (fix "fix") (unsigned_fix "fixuns")])
746 (define_code_attr i [(float "i") (unsigned_float "u")
747 (fix "i") (unsigned_fix "u")])
748
749 ;; Integer to float conversions
750 (define_insn "<conv_op>si<mode>2"
751 [(set (match_operand:F 0 "register_operand" "=r")
752 (FLOAT:F (match_operand:SI 1 "register_operand" "r")))]
753 "nios2_fpu_insn_enabled (n2fpu_float<i><f>)"
754 { return nios2_fpu_insn_asm (n2fpu_float<i><f>); }
755 [(set_attr "type" "custom")])
756
757 ;; Float to integer conversions
758 (define_insn "<conv_op>_trunc<mode>si2"
759 [(set (match_operand:SI 0 "register_operand" "=r")
760 (FIX:SI (match_operand:F 1 "general_operand" "r")))]
761 "nios2_fpu_insn_enabled (n2fpu_fix<f><i>)"
762 { return nios2_fpu_insn_asm (n2fpu_fix<f><i>); }
763 [(set_attr "type" "custom")])
764
765 (define_insn "lroundsfsi2"
766 [(set (match_operand:SI 0 "register_operand" "=r")
767 (unspec:SI [(match_operand:SF 1 "general_operand" "r")] UNSPEC_ROUND))]
768 "nios2_fpu_insn_enabled (n2fpu_round)"
769 { return nios2_fpu_insn_asm (n2fpu_round); }
770 [(set_attr "type" "custom")])
771
772 (define_insn "extendsfdf2"
773 [(set (match_operand:DF 0 "register_operand" "=r")
774 (float_extend:DF (match_operand:SF 1 "general_operand" "r")))]
775 "nios2_fpu_insn_enabled (n2fpu_fextsd)"
776 { return nios2_fpu_insn_asm (n2fpu_fextsd); }
777 [(set_attr "type" "custom")])
778
779 (define_insn "truncdfsf2"
780 [(set (match_operand:SF 0 "register_operand" "=r")
781 (float_truncate:SF (match_operand:DF 1 "general_operand" "r")))]
782 "nios2_fpu_insn_enabled (n2fpu_ftruncds)"
783 { return nios2_fpu_insn_asm (n2fpu_ftruncds); }
784 [(set_attr "type" "custom")])
785
786
787
788 ;; Prologue, Epilogue and Return
789
790 (define_expand "prologue"
791 [(const_int 1)]
792 ""
793 {
794 nios2_expand_prologue ();
795 DONE;
796 })
797
798 (define_expand "epilogue"
799 [(return)]
800 ""
801 {
802 nios2_expand_epilogue (false);
803 DONE;
804 })
805
806 (define_expand "sibcall_epilogue"
807 [(return)]
808 ""
809 {
810 nios2_expand_epilogue (true);
811 DONE;
812 })
813
814 (define_expand "return"
815 [(simple_return)]
816 "nios2_can_use_return_insn ()"
817 {
818 if (nios2_expand_return ())
819 DONE;
820 })
821
822 (define_insn "simple_return"
823 [(simple_return)]
824 ""
825 "ret%."
826 [(set_attr "type" "control")])
827
828 ;; Block any insns from being moved before this point, since the
829 ;; profiling call to mcount can use various registers that aren't
830 ;; saved or used to pass arguments.
831
832 (define_insn "blockage"
833 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
834 ""
835 ""
836 [(set_attr "type" "unknown")
837 (set_attr "length" "0")])
838
839 ;; This is used in compiling the unwind routines.
840 (define_expand "eh_return"
841 [(use (match_operand 0 "general_operand"))]
842 ""
843 {
844 if (GET_MODE (operands[0]) != Pmode)
845 operands[0] = convert_to_mode (Pmode, operands[0], 0);
846 emit_insn (gen_eh_set_ra (operands[0]));
847 DONE;
848 })
849
850 ;; Modify the return address for EH return. We can't expand this
851 ;; until we know where it will be put in the stack frame.
852
853 (define_insn_and_split "eh_set_ra"
854 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
855 (clobber (match_scratch:SI 1 "=&r"))]
856 ""
857 "#"
858 "reload_completed"
859 [(const_int 0)]
860 {
861 nios2_set_return_address (operands[0], operands[1]);
862 DONE;
863 })
864
865
866 ;; Jumps and calls
867
868 ; Note that the assembler fixes up any out-of-range branch instructions not
869 ; caught by the compiler branch shortening code. The sequence emitted by
870 ; the assembler can be very inefficient, but it is correct for PIC code.
871 ; For non-PIC we are better off converting to an absolute JMPI.
872 ;
873 ; Direct calls and sibcalls use the CALL and JMPI instructions, respectively.
874 ; These instructions have an immediate operand that specifies the low 28 bits
875 ; of the PC, effectively allowing direct calls within a 256MB memory segment.
876 ; Per the Nios II Processor Reference Handbook, the linker is not required to
877 ; check or adjust for overflow.
878
879 (define_insn "indirect_jump"
880 [(set (pc) (match_operand:SI 0 "register_operand" "c"))]
881 ""
882 "jmp%!\\t%0"
883 [(set_attr "type" "control")])
884
885 (define_insn "jump"
886 [(set (pc)
887 (label_ref (match_operand 0 "" "")))]
888 ""
889 {
890 if (get_attr_length (insn) == 2)
891 return "br.n\\t%0";
892 else if (get_attr_length (insn) == 4)
893 return "br\\t%0";
894 else
895 return "jmpi\\t%0";
896 }
897 [(set_attr "type" "control")
898 (set (attr "length")
899 (if_then_else
900 (and (match_test "TARGET_HAS_CDX")
901 (and (ge (minus (match_dup 0) (pc)) (const_int -1022))
902 (le (minus (match_dup 0) (pc)) (const_int 1022))))
903 (const_int 2)
904 (if_then_else
905 (ior (match_test "flag_pic")
906 (and (ge (minus (match_dup 0) (pc)) (const_int -32764))
907 (le (minus (match_dup 0) (pc)) (const_int 32764))))
908 (const_int 4)
909 (const_int 8))))])
910
911 (define_expand "call"
912 [(parallel [(call (match_operand 0 "" "")
913 (match_operand 1 "" ""))
914 (clobber (reg:SI RA_REGNO))])]
915 ""
916 "nios2_adjust_call_address (&operands[0], NULL_RTX);")
917
918 (define_expand "call_value"
919 [(parallel [(set (match_operand 0 "" "")
920 (call (match_operand 1 "" "")
921 (match_operand 2 "" "")))
922 (clobber (reg:SI RA_REGNO))])]
923 ""
924 "nios2_adjust_call_address (&operands[1], NULL_RTX);")
925
926 (define_insn "*call"
927 [(call (mem:QI (match_operand:SI 0 "call_operand" "i,r"))
928 (match_operand 1 "" ""))
929 (clobber (reg:SI RA_REGNO))]
930 ""
931 "@
932 call\\t%0
933 callr%.\\t%0"
934 [(set_attr "type" "control")])
935
936 (define_insn "*call_value"
937 [(set (match_operand 0 "" "")
938 (call (mem:QI (match_operand:SI 1 "call_operand" "i,r"))
939 (match_operand 2 "" "")))
940 (clobber (reg:SI RA_REGNO))]
941 ""
942 "@
943 call\\t%1
944 callr%.\\t%1"
945 [(set_attr "type" "control")])
946
947 (define_expand "sibcall"
948 [(parallel [(call (match_operand 0 "" "")
949 (match_operand 1 "" ""))
950 (return)])]
951 ""
952 "nios2_adjust_call_address (&operands[0], NULL_RTX);")
953
954 (define_expand "sibcall_value"
955 [(parallel [(set (match_operand 0 "" "")
956 (call (match_operand 1 "" "")
957 (match_operand 2 "" "")))
958 (return)])]
959 ""
960 "nios2_adjust_call_address (&operands[1], NULL_RTX);")
961
962 (define_insn "sibcall_internal"
963 [(call (mem:QI (match_operand:SI 0 "call_operand" "i,j"))
964 (match_operand 1 "" ""))
965 (return)]
966 ""
967 "@
968 jmpi\\t%0
969 jmp%!\\t%0"
970 [(set_attr "type" "control")])
971
972 (define_insn "sibcall_value_internal"
973 [(set (match_operand 0 "register_operand" "")
974 (call (mem:QI (match_operand:SI 1 "call_operand" "i,j"))
975 (match_operand 2 "" "")))
976 (return)]
977 ""
978 "@
979 jmpi\\t%1
980 jmp%!\\t%1"
981 [(set_attr "type" "control")])
982
983 (define_expand "tablejump"
984 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
985 (use (label_ref (match_operand 1 "" "")))])]
986 ""
987 {
988 if (flag_pic)
989 {
990 /* Hopefully, CSE will eliminate this copy. */
991 rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1]));
992 rtx reg2 = gen_reg_rtx (SImode);
993
994 emit_insn (gen_addsi3 (reg2, operands[0], reg1));
995 operands[0] = reg2;
996 }
997 })
998
999 (define_insn "*tablejump"
1000 [(set (pc)
1001 (match_operand:SI 0 "register_operand" "c"))
1002 (use (label_ref (match_operand 1 "" "")))]
1003 ""
1004 "jmp%!\\t%0"
1005 [(set_attr "type" "control")])
1006
1007
1008 ;; cstore, cbranch patterns
1009
1010 (define_mode_iterator CM [SI SF DF])
1011
1012 (define_expand "cstore<mode>4"
1013 [(set (match_operand:SI 0 "register_operand" "=r")
1014 (match_operator:SI 1 "expandable_comparison_operator"
1015 [(match_operand:CM 2 "register_operand")
1016 (match_operand:CM 3 "nonmemory_operand")]))]
1017 ""
1018 {
1019 if (!nios2_validate_compare (<MODE>mode, &operands[1], &operands[2],
1020 &operands[3]))
1021 FAIL;
1022 })
1023
1024 (define_expand "cbranch<mode>4"
1025 [(set (pc)
1026 (if_then_else
1027 (match_operator 0 "expandable_comparison_operator"
1028 [(match_operand:CM 1 "register_operand")
1029 (match_operand:CM 2 "nonmemory_operand")])
1030 (label_ref (match_operand 3 ""))
1031 (pc)))]
1032 ""
1033 {
1034 if (!nios2_validate_compare (<MODE>mode, &operands[0], &operands[1],
1035 &operands[2]))
1036 FAIL;
1037 if (GET_MODE_CLASS (<MODE>mode) == MODE_FLOAT
1038 || !reg_or_0_operand (operands[2], <MODE>mode))
1039 {
1040 rtx condreg = gen_reg_rtx (SImode);
1041 emit_insn (gen_cstore<mode>4
1042 (condreg, operands[0], operands[1], operands[2]));
1043 operands[1] = condreg;
1044 operands[2] = const0_rtx;
1045 operands[0] = gen_rtx_fmt_ee (NE, VOIDmode, condreg, const0_rtx);
1046 }
1047 })
1048
1049 (define_insn "nios2_cbranch"
1050 [(set (pc)
1051 (if_then_else
1052 (match_operator 0 "ordered_comparison_operator"
1053 [(match_operand:SI 1 "reg_or_0_operand" "rM")
1054 (match_operand:SI 2 "reg_or_0_operand" "rM")])
1055 (label_ref (match_operand 3 "" ""))
1056 (pc)))]
1057 ""
1058 {
1059 if (get_attr_length (insn) == 2)
1060 return "b%0z.n\t%z1, %l3";
1061 else if (get_attr_length (insn) == 4)
1062 return "b%0\t%z1, %z2, %l3";
1063 else if (get_attr_length (insn) == 6)
1064 return "b%R0z.n\t%z1, .+6;jmpi\t%l3";
1065 else
1066 return "b%R0\t%z1, %z2, .+8;jmpi\t%l3";
1067 }
1068 [(set_attr "type" "control")
1069 (set (attr "length")
1070 (cond
1071 [(and (match_test "nios2_cdx_narrow_form_p (insn)")
1072 (ge (minus (match_dup 3) (pc)) (const_int -126))
1073 (le (minus (match_dup 3) (pc)) (const_int 126)))
1074 (const_int 2)
1075 (ior (match_test "flag_pic")
1076 (and (ge (minus (match_dup 3) (pc)) (const_int -32764))
1077 (le (minus (match_dup 3) (pc)) (const_int 32764))))
1078 (const_int 4)
1079 (match_test "nios2_cdx_narrow_form_p (insn)")
1080 (const_int 6)]
1081 (const_int 8)))])
1082
1083 ;; Floating point comparisons
1084 (define_code_iterator FCMP [eq ne gt ge le lt])
1085 (define_insn "nios2_s<code><mode>"
1086 [(set (match_operand:SI 0 "register_operand" "=r")
1087 (FCMP:SI (match_operand:F 1 "register_operand" "r")
1088 (match_operand:F 2 "register_operand" "r")))]
1089 "nios2_fpu_insn_enabled (n2fpu_fcmp<code><f>)"
1090 { return nios2_fpu_insn_asm (n2fpu_fcmp<code><f>); }
1091 [(set_attr "type" "custom")])
1092
1093 ;; Integer comparisons
1094
1095 (define_code_iterator EQNE [eq ne])
1096 (define_insn "nios2_cmp<code>"
1097 [(set (match_operand:SI 0 "register_operand" "=r")
1098 (EQNE:SI (match_operand:SI 1 "register_operand" "%r")
1099 (match_operand:SI 2 "arith_operand" "rI")))]
1100 ""
1101 "cmp<code>%i2\\t%0, %1, %z2"
1102 [(set_attr "type" "alu")])
1103
1104 (define_code_iterator SCMP [ge lt])
1105 (define_insn "nios2_cmp<code>"
1106 [(set (match_operand:SI 0 "register_operand" "=r")
1107 (SCMP:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
1108 (match_operand:SI 2 "arith_operand" "rI")))]
1109 ""
1110 "cmp<code>%i2\\t%0, %z1, %z2"
1111 [(set_attr "type" "alu")])
1112
1113 (define_code_iterator UCMP [geu ltu])
1114 (define_insn "nios2_cmp<code>"
1115 [(set (match_operand:SI 0 "register_operand" "=r")
1116 (UCMP:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
1117 (match_operand:SI 2 "uns_arith_operand" "rJ")))]
1118 ""
1119 "cmp<code>%u2\\t%0, %z1, %z2"
1120 [(set_attr "type" "alu")])
1121
1122
1123
1124 ;; Custom instruction patterns. The operands are intentionally
1125 ;; mode-less, to serve as generic carriers of all Altera defined
1126 ;; built-in instruction/function types.
1127
1128 (define_insn "custom_nxx"
1129 [(unspec_volatile [(match_operand 0 "custom_insn_opcode" "N")
1130 (match_operand 1 "reg_or_0_operand" "rM")
1131 (match_operand 2 "reg_or_0_operand" "rM")]
1132 UNSPECV_CUSTOM_NXX)]
1133 ""
1134 "custom\\t%0, zero, %z1, %z2"
1135 [(set_attr "type" "custom")])
1136
1137 (define_insn "custom_xnxx"
1138 [(set (match_operand 0 "register_operand" "=r")
1139 (unspec_volatile [(match_operand 1 "custom_insn_opcode" "N")
1140 (match_operand 2 "reg_or_0_operand" "rM")
1141 (match_operand 3 "reg_or_0_operand" "rM")]
1142 UNSPECV_CUSTOM_XNXX))]
1143 ""
1144 "custom\\t%1, %0, %z2, %z3"
1145 [(set_attr "type" "custom")])
1146
1147
1148 ;; Misc. patterns
1149
1150 (define_insn "nop"
1151 [(const_int 0)]
1152 ""
1153 "nop%."
1154 [(set_attr "type" "nop")])
1155
1156 ;; Connect 'sync' to 'memory_barrier' standard expand name
1157 (define_expand "memory_barrier"
1158 [(const_int 0)]
1159 ""
1160 {
1161 emit_insn (gen_sync ());
1162 DONE;
1163 })
1164
1165 ;; For the nios2 __builtin_sync built-in function
1166 (define_expand "sync"
1167 [(set (match_dup 0)
1168 (unspec:BLK [(match_dup 0)] UNSPEC_SYNC))]
1169 ""
1170 {
1171 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
1172 MEM_VOLATILE_P (operands[0]) = 1;
1173 })
1174
1175 (define_insn "*sync_insn"
1176 [(set (match_operand:BLK 0 "" "")
1177 (unspec:BLK [(match_dup 0)] UNSPEC_SYNC))]
1178 ""
1179 "sync"
1180 [(set_attr "type" "control")])
1181
1182 (define_insn "rdctl"
1183 [(set (match_operand:SI 0 "register_operand" "=r")
1184 (unspec_volatile:SI [(match_operand:SI 1 "rdwrctl_operand" "O")]
1185 UNSPECV_RDCTL))]
1186 ""
1187 "rdctl\\t%0, ctl%1"
1188 [(set_attr "type" "control")])
1189
1190 (define_insn "wrctl"
1191 [(unspec_volatile:SI [(match_operand:SI 0 "rdwrctl_operand" "O")
1192 (match_operand:SI 1 "reg_or_0_operand" "rM")]
1193 UNSPECV_WRCTL)]
1194 ""
1195 "wrctl\\tctl%0, %z1"
1196 [(set_attr "type" "control")])
1197
1198 (define_insn "rdprs"
1199 [(set (match_operand:SI 0 "register_operand" "=r")
1200 (unspec_volatile:SI [(match_operand:SI 1 "rdwrctl_operand" "O")
1201 (match_operand:SI 2 "arith_operand" "U")]
1202 UNSPECV_RDPRS))]
1203 ""
1204 "rdprs\\t%0, %1, %2"
1205 [(set_attr "type" "control")])
1206
1207 ;; Cache Instructions
1208
1209 (define_insn "flushd"
1210 [(unspec_volatile:SI [(match_operand:SI 0 "ldstio_memory_operand" "w")]
1211 UNSPECV_FLUSHD)]
1212 ""
1213 "flushd\\t%0"
1214 [(set_attr "type" "control")])
1215
1216 (define_insn "flushda"
1217 [(unspec_volatile:SI [(match_operand:SI 0 "ldstio_memory_operand" "w")]
1218 UNSPECV_FLUSHDA)]
1219 ""
1220 "flushda\\t%0"
1221 [(set_attr "type" "control")])
1222
1223 ;; R2 Instructions
1224
1225 (define_insn "wrpie"
1226 [(set (match_operand:SI 0 "register_operand" "=r")
1227 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r")]
1228 UNSPECV_WRPIE))]
1229 "TARGET_ARCH_R2"
1230 "wrpie\\t%0, %1"
1231 [(set_attr "type" "control")])
1232
1233 (define_insn "eni"
1234 [(unspec:VOID [(match_operand 0 "const_int_operand" "i")]
1235 UNSPECV_ENI)]
1236 "TARGET_ARCH_R2"
1237 "eni\\t%0"
1238 [(set_attr "type" "control")])
1239
1240 ;; Trap patterns
1241 (define_insn "trap"
1242 [(trap_if (const_int 1) (const_int 3))]
1243 ""
1244 "trap%.\\t3"
1245 [(set_attr "type" "control")])
1246
1247 (define_insn "ctrapsi4"
1248 [(trap_if (match_operator 0 "ordered_comparison_operator"
1249 [(match_operand:SI 1 "reg_or_0_operand" "rM")
1250 (match_operand:SI 2 "reg_or_0_operand" "rM")])
1251 (match_operand 3 "const_int_operand" "i"))]
1252 ""
1253 {
1254 if (get_attr_length (insn) == 6)
1255 return "b%R0\\t%z1, %z2, 1f\;trap.n\\t%3\;1:";
1256 else
1257 return "b%R0\\t%z1, %z2, 1f\;trap\\t%3\;1:";
1258 }
1259 [(set_attr "type" "control")
1260 (set (attr "length")
1261 (if_then_else (match_test "nios2_cdx_narrow_form_p (insn)")
1262 (const_int 6) (const_int 8)))])
1263
1264 ;; Load the GOT register.
1265 (define_insn "load_got_register"
1266 [(set (match_operand:SI 0 "register_operand" "=&r")
1267 (unspec:SI [(const_int 0)] UNSPEC_LOAD_GOT_REGISTER))
1268 (set (match_operand:SI 1 "register_operand" "=r")
1269 (unspec:SI [(const_int 0)] UNSPEC_LOAD_GOT_REGISTER))]
1270 ""
1271 "nextpc\\t%0
1272 \\t1:
1273 \\tmovhi\\t%1, %%hiadj(_gp_got - 1b)
1274 \\taddi\\t%1, %1, %%lo(_gp_got - 1b)"
1275 [(set_attr "length" "12")])
1276
1277 ;; Read thread pointer register
1278 (define_expand "get_thread_pointersi"
1279 [(match_operand:SI 0 "register_operand" "=r")]
1280 "TARGET_LINUX_ABI"
1281 {
1282 emit_move_insn (operands[0], gen_rtx_REG (Pmode, TP_REGNO));
1283 DONE;
1284 })
1285
1286 ;; Synchronization Primitives
1287 (include "sync.md")
1288
1289 ;; Include the ldwm/stwm/push.n/pop.n patterns and peepholes.
1290 (include "ldstwm.md")
1291