]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/nios2/nios2.md
constraints.md (U, v): New constraints.
[thirdparty/gcc.git] / gcc / config / nios2 / nios2.md
1 ;; Machine Description for Altera Nios II.
2 ;; Copyright (C) 2012-2015 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 \f
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 \f
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 "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 [(set_attr "type" "st,ld,mov")])
228
229 (define_insn "movhi_internal"
230 [(set (match_operand:HI 0 "nonimmediate_operand" "=m, r,r")
231 (match_operand:HI 1 "general_operand" "rM,m,rI"))]
232 "(register_operand (operands[0], HImode)
233 || reg_or_0_operand (operands[1], HImode))"
234 "@
235 sth%o0%.\\t%z1, %0
236 ldhu%o1%.\\t%0, %1
237 mov%i1%.\\t%0, %z1"
238 [(set_attr "type" "st,ld,mov")])
239
240 (define_insn "movsi_internal"
241 [(set (match_operand:SI 0 "nonimmediate_operand" "=m, r,r, r")
242 (match_operand:SI 1 "general_operand" "rM,m,rIJK,S"))]
243 "(register_operand (operands[0], SImode)
244 || reg_or_0_operand (operands[1], SImode))"
245 {
246 switch (which_alternative)
247 {
248 case 0:
249 if (get_attr_length (insn) != 2)
250 return "stw%o0\\t%z1, %0";
251 else if (stack_memory_operand (operands[0], SImode))
252 return "stwsp.n\\t%z1, %0";
253 else if (const_0_operand (operands[1], SImode))
254 return "stwz.n\\t%z1, %0";
255 else
256 return "stw.n\\t%z1, %0";
257 case 1:
258 if (get_attr_length (insn) != 2)
259 return "ldw%o1\\t%0, %1";
260 else if (stack_memory_operand (operands[1], SImode))
261 return "ldwsp.n\\t%0, %1";
262 else
263 return "ldw.n\\t%0, %1";
264 case 2:
265 return "mov%i1%.\\t%0, %z1";
266 case 3:
267 return "addi\\t%0, gp, %%gprel(%1)";
268 default:
269 gcc_unreachable ();
270 }
271 }
272 [(set_attr "type" "st,ld,mov,alu")])
273
274 (define_mode_iterator BH [QI HI])
275 (define_mode_iterator BHW [QI HI SI])
276 (define_mode_attr bh [(QI "b") (HI "h")])
277 (define_mode_attr bhw [(QI "b") (HI "h") (SI "w")])
278 (define_mode_attr bhw_uns [(QI "bu") (HI "hu") (SI "w")])
279
280 (define_insn "ld<bhw_uns>io"
281 [(set (match_operand:BHW 0 "register_operand" "=r")
282 (unspec_volatile:BHW
283 [(match_operand:BHW 1 "ldstio_memory_operand" "w")] UNSPECV_LDXIO))]
284 ""
285 "ld<bhw_uns>io\\t%0, %1"
286 [(set_attr "type" "ld")])
287
288 (define_expand "ld<bh>io"
289 [(set (match_operand:BH 0 "register_operand" "=r")
290 (match_operand:BH 1 "ldstio_memory_operand" "w"))]
291 ""
292 {
293 rtx tmp = gen_reg_rtx (SImode);
294 emit_insn (gen_ld<bh>io_signed (tmp, operands[1]));
295 emit_insn (gen_mov<mode> (operands[0], gen_lowpart (<MODE>mode, tmp)));
296 DONE;
297 })
298
299 (define_insn "ld<bh>io_signed"
300 [(set (match_operand:SI 0 "register_operand" "=r")
301 (sign_extend:SI
302 (unspec_volatile:BH
303 [(match_operand:BH 1 "ldstio_memory_operand" "w")] UNSPECV_LDXIO)))]
304 ""
305 "ld<bh>io\\t%0, %1"
306 [(set_attr "type" "ld")])
307
308 (define_insn "st<bhw>io"
309 [(set (match_operand:BHW 0 "ldstio_memory_operand" "=w")
310 (unspec_volatile:BHW
311 [(match_operand:BHW 1 "reg_or_0_operand" "rM")] UNSPECV_STXIO))]
312 ""
313 "st<bhw>io\\t%z1, %0"
314 [(set_attr "type" "st")])
315
316 \f
317 ;; QI to [HI, SI] extension patterns are collected together
318 (define_mode_iterator QX [HI SI])
319
320 ;; Zero extension patterns
321 (define_insn "zero_extendhisi2"
322 [(set (match_operand:SI 0 "register_operand" "=r,r")
323 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
324 ""
325 "@
326 andi%.\\t%0, %1, 0xffff
327 ldhu%o1%.\\t%0, %1"
328 [(set_attr "type" "and,ld")])
329
330 (define_insn "zero_extendqi<mode>2"
331 [(set (match_operand:QX 0 "register_operand" "=r,r")
332 (zero_extend:QX (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
333 ""
334 "@
335 andi%.\\t%0, %1, 0xff
336 ldbu%o1%.\\t%0, %1"
337 [(set_attr "type" "and,ld")])
338
339 ;; Sign extension patterns
340
341 (define_insn "extendhisi2"
342 [(set (match_operand:SI 0 "register_operand" "=r,r")
343 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
344 ""
345 "@
346 #
347 ldh%o1%.\\t%0, %1"
348 [(set_attr "type" "alu,ld")])
349
350 (define_insn "extendqi<mode>2"
351 [(set (match_operand:QX 0 "register_operand" "=r,r")
352 (sign_extend:QX (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
353 ""
354 "@
355 #
356 ldb%o1%.\\t%0, %1"
357 [(set_attr "type" "alu,ld")])
358
359 ;; Split patterns for register alternative cases.
360 (define_split
361 [(set (match_operand:SI 0 "register_operand" "")
362 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
363 "reload_completed"
364 [(set (match_dup 0)
365 (and:SI (match_dup 1) (const_int 65535)))
366 (set (match_dup 0)
367 (xor:SI (match_dup 0) (const_int 32768)))
368 (set (match_dup 0)
369 (plus:SI (match_dup 0) (const_int -32768)))]
370 "operands[1] = gen_lowpart (SImode, operands[1]);")
371
372 (define_split
373 [(set (match_operand:QX 0 "register_operand" "")
374 (sign_extend:QX (match_operand:QI 1 "register_operand" "")))]
375 "reload_completed"
376 [(set (match_dup 0)
377 (and:SI (match_dup 1) (const_int 255)))
378 (set (match_dup 0)
379 (xor:SI (match_dup 0) (const_int 128)))
380 (set (match_dup 0)
381 (plus:SI (match_dup 0) (const_int -128)))]
382 "operands[0] = gen_lowpart (SImode, operands[0]);
383 operands[1] = gen_lowpart (SImode, operands[1]);")
384
385 \f
386 ;; Arithmetic Operations
387
388 (define_insn "addsi3"
389 [(set (match_operand:SI 0 "register_operand" "=r")
390 (plus:SI (match_operand:SI 1 "register_operand" "%r")
391 (match_operand:SI 2 "add_regimm_operand" "rIT")))]
392 ""
393 {
394 return nios2_add_insn_asm (insn, operands);
395 }
396 [(set_attr "type" "add")])
397
398 (define_insn "subsi3"
399 [(set (match_operand:SI 0 "register_operand" "=r")
400 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
401 (match_operand:SI 2 "register_operand" "r")))]
402 ""
403 "sub%.\\t%0, %z1, %2"
404 [(set_attr "type" "sub")])
405
406 (define_insn "mulsi3"
407 [(set (match_operand:SI 0 "register_operand" "=r")
408 (mult:SI (match_operand:SI 1 "register_operand" "%r")
409 (match_operand:SI 2 "arith_operand" "rI")))]
410 "TARGET_HAS_MUL"
411 "mul%i2\\t%0, %1, %z2"
412 [(set_attr "type" "mul")])
413
414 (define_expand "divsi3"
415 [(set (match_operand:SI 0 "register_operand" "=r")
416 (div:SI (match_operand:SI 1 "register_operand" "r")
417 (match_operand:SI 2 "register_operand" "r")))]
418 ""
419 {
420 if (!TARGET_HAS_DIV)
421 {
422 if (TARGET_FAST_SW_DIV)
423 {
424 nios2_emit_expensive_div (operands, SImode);
425 DONE;
426 }
427 else
428 FAIL;
429 }
430 })
431
432 (define_insn "divsi3_insn"
433 [(set (match_operand:SI 0 "register_operand" "=r")
434 (div:SI (match_operand:SI 1 "register_operand" "r")
435 (match_operand:SI 2 "register_operand" "r")))]
436 "TARGET_HAS_DIV"
437 "div\\t%0, %1, %2"
438 [(set_attr "type" "div")])
439
440 (define_insn "udivsi3"
441 [(set (match_operand:SI 0 "register_operand" "=r")
442 (udiv:SI (match_operand:SI 1 "register_operand" "r")
443 (match_operand:SI 2 "register_operand" "r")))]
444 "TARGET_HAS_DIV"
445 "divu\\t%0, %1, %2"
446 [(set_attr "type" "div")])
447
448 (define_code_iterator EXTEND [sign_extend zero_extend])
449 (define_code_attr us [(sign_extend "s") (zero_extend "u")])
450 (define_code_attr mul [(sign_extend "mul") (zero_extend "umul")])
451
452 (define_insn "<us>mulsi3_highpart"
453 [(set (match_operand:SI 0 "register_operand" "=r")
454 (truncate:SI
455 (lshiftrt:DI
456 (mult:DI (EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
457 (EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
458 (const_int 32))))]
459 "TARGET_HAS_MULX"
460 "mulx<us><us>\\t%0, %1, %2"
461 [(set_attr "type" "mul")])
462
463 (define_expand "<mul>sidi3"
464 [(set (match_operand:DI 0 "register_operand" "")
465 (mult:DI (EXTEND:DI (match_operand:SI 1 "register_operand" ""))
466 (EXTEND:DI (match_operand:SI 2 "register_operand" ""))))]
467 "TARGET_HAS_MULX"
468 {
469 rtx hi = gen_reg_rtx (SImode);
470 rtx lo = gen_reg_rtx (SImode);
471
472 emit_insn (gen_<us>mulsi3_highpart (hi, operands[1], operands[2]));
473 emit_insn (gen_mulsi3 (lo, operands[1], operands[2]));
474 emit_move_insn (gen_lowpart (SImode, operands[0]), lo);
475 emit_move_insn (gen_highpart (SImode, operands[0]), hi);
476 DONE;
477 })
478
479 \f
480 ;; Negate and ones complement
481
482 (define_insn "negsi2"
483 [(set (match_operand:SI 0 "register_operand" "=r")
484 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
485 ""
486 {
487 if (get_attr_length (insn) == 2)
488 return "neg.n\\t%0, %1";
489 else
490 return "sub\\t%0, zero, %1";
491 }
492 [(set_attr "type" "neg")])
493
494 (define_insn "one_cmplsi2"
495 [(set (match_operand:SI 0 "register_operand" "=r")
496 (not:SI (match_operand:SI 1 "register_operand" "r")))]
497 ""
498 {
499 if (get_attr_length (insn) == 2)
500 return "not.n\\t%0, %1";
501 else
502 return "nor\\t%0, zero, %1";
503 }
504 [(set_attr "type" "not")])
505
506 \f
507 ;; Integer logical Operations
508
509 (define_insn "andsi3"
510 [(set (match_operand:SI 0 "register_operand" "=r")
511 (and:SI (match_operand:SI 1 "register_operand" "%r")
512 (match_operand:SI 2 "and_operand" "rJKP")))]
513 ""
514 "and%x2%.\\t%0, %1, %y2"
515 [(set_attr "type" "and")])
516
517 (define_code_iterator LOGICAL [ior xor])
518 (define_code_attr logical_asm [(ior "or") (xor "xor")])
519
520 (define_insn "<code>si3"
521 [(set (match_operand:SI 0 "register_operand" "=r")
522 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r")
523 (match_operand:SI 2 "logical_operand" "rJK")))]
524 ""
525 "<logical_asm>%x2%.\\t%0, %1, %y2"
526 [(set_attr "type" "<logical_asm>")])
527
528 (define_insn "*norsi3"
529 [(set (match_operand:SI 0 "register_operand" "=r")
530 (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r"))
531 (not:SI (match_operand:SI 2 "register_operand" "r"))))]
532 ""
533 "nor\\t%0, %1, %2"
534 [(set_attr "type" "alu")])
535
536 \f
537 ;; Shift instructions
538
539 (define_code_iterator SHIFT [ashift ashiftrt lshiftrt rotate])
540 (define_code_attr shift_op [(ashift "ashl") (ashiftrt "ashr")
541 (lshiftrt "lshr") (rotate "rotl")])
542 (define_code_attr shift_asm [(ashift "sll") (ashiftrt "sra")
543 (lshiftrt "srl") (rotate "rol")])
544
545 (define_insn "<shift_op>si3"
546 [(set (match_operand:SI 0 "register_operand" "=r")
547 (SHIFT:SI (match_operand:SI 1 "register_operand" "r")
548 (match_operand:SI 2 "shift_operand" "rL")))]
549 ""
550 "<shift_asm>%i2%.\\t%0, %1, %z2"
551 [(set_attr "type" "<shift_asm>")])
552
553 (define_insn "rotrsi3"
554 [(set (match_operand:SI 0 "register_operand" "=r")
555 (rotatert:SI (match_operand:SI 1 "register_operand" "r")
556 (match_operand:SI 2 "register_operand" "r")))]
557 ""
558 "ror\\t%0, %1, %2"
559 [(set_attr "type" "ror")])
560
561 ;; Nios II R2 Bit Manipulation Extension (BMX), provides
562 ;; bit merge/insertion/extraction instructions.
563
564 (define_insn "*merge"
565 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
566 (match_operand:SI 1 "const_shift_operand" "L")
567 (match_operand:SI 2 "const_shift_operand" "L"))
568 (zero_extract:SI (match_operand:SI 3 "register_operand" "r")
569 (match_dup 1) (match_dup 2)))]
570 "TARGET_HAS_BMX"
571 {
572 operands[4] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[2]) - 1);
573 return "merge\\t%0, %3, %4, %2";
574 }
575 [(set_attr "type" "alu")])
576
577 (define_insn "extzv"
578 [(set (match_operand:SI 0 "register_operand" "=r")
579 (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
580 (match_operand:SI 2 "const_shift_operand" "L")
581 (match_operand:SI 3 "const_shift_operand" "L")))]
582 "TARGET_HAS_BMX"
583 {
584 operands[4] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]) - 1);
585 return "extract\\t%0, %1, %4, %3";
586 }
587 [(set_attr "type" "alu")])
588
589 (define_insn "insv"
590 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
591 (match_operand:SI 1 "const_shift_operand" "L")
592 (match_operand:SI 2 "const_shift_operand" "L"))
593 (match_operand:SI 3 "reg_or_0_operand" "rM"))]
594 "TARGET_HAS_BMX"
595 {
596 operands[4] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[2]) - 1);
597 return "insert\\t%0, %z3, %4, %2";
598 }
599 [(set_attr "type" "alu")])
600
601
602 \f
603 ;; Floating point instructions
604
605 ;; Mode iterator for single/double float
606 (define_mode_iterator F [SF DF])
607 (define_mode_attr f [(SF "s") (DF "d")])
608
609 ;; Basic arithmetic instructions
610 (define_code_iterator FOP3 [plus minus mult div])
611 (define_code_attr fop3 [(plus "add") (minus "sub") (mult "mul") (div "div")])
612
613 (define_insn "<fop3><mode>3"
614 [(set (match_operand:F 0 "register_operand" "=r")
615 (FOP3:F (match_operand:F 1 "register_operand" "r")
616 (match_operand:F 2 "register_operand" "r")))]
617 "nios2_fpu_insn_enabled (n2fpu_f<fop3><f>)"
618 { return nios2_fpu_insn_asm (n2fpu_f<fop3><f>); }
619 [(set_attr "type" "custom")])
620
621 ;; Floating point min/max operations
622 (define_code_iterator SMINMAX [smin smax])
623 (define_code_attr minmax [(smin "min") (smax "max")])
624 (define_insn "<code><mode>3"
625 [(set (match_operand:F 0 "register_operand" "=r")
626 (SMINMAX:F (match_operand:F 1 "register_operand" "r")
627 (match_operand:F 2 "register_operand" "r")))]
628 "nios2_fpu_insn_enabled (n2fpu_f<minmax><f>)"
629 { return nios2_fpu_insn_asm (n2fpu_f<minmax><f>); }
630 [(set_attr "type" "custom")])
631
632 ;; These 2-operand FP operations can be collected together
633 (define_code_iterator FOP2 [abs neg sqrt])
634 (define_insn "<code><mode>2"
635 [(set (match_operand:F 0 "register_operand" "=r")
636 (FOP2:F (match_operand:F 1 "register_operand" "r")))]
637 "nios2_fpu_insn_enabled (n2fpu_f<code><f>)"
638 { return nios2_fpu_insn_asm (n2fpu_f<code><f>); }
639 [(set_attr "type" "custom")])
640
641 ;; X, Y register access instructions
642 (define_insn "nios2_fwrx"
643 [(unspec_volatile [(match_operand:DF 0 "register_operand" "r")] UNSPECV_FWRX)]
644 "nios2_fpu_insn_enabled (n2fpu_fwrx)"
645 { return nios2_fpu_insn_asm (n2fpu_fwrx); }
646 [(set_attr "type" "custom")])
647
648 (define_insn "nios2_fwry"
649 [(unspec_volatile [(match_operand:SF 0 "register_operand" "r")] UNSPECV_FWRY)]
650 "nios2_fpu_insn_enabled (n2fpu_fwry)"
651 { return nios2_fpu_insn_asm (n2fpu_fwry); }
652 [(set_attr "type" "custom")])
653
654 ;; The X, Y read insns uses an int iterator
655 (define_int_iterator UNSPEC_READ_XY [UNSPECV_FRDXLO UNSPECV_FRDXHI
656 UNSPECV_FRDY])
657 (define_int_attr read_xy [(UNSPECV_FRDXLO "frdxlo") (UNSPECV_FRDXHI "frdxhi")
658 (UNSPECV_FRDY "frdy")])
659 (define_insn "nios2_<read_xy>"
660 [(set (match_operand:SF 0 "register_operand" "=r")
661 (unspec_volatile:SF [(const_int 0)] UNSPEC_READ_XY))]
662 "nios2_fpu_insn_enabled (n2fpu_<read_xy>)"
663 { return nios2_fpu_insn_asm (n2fpu_<read_xy>); }
664 [(set_attr "type" "custom")])
665
666 ;; Various math functions
667 (define_int_iterator MATHFUNC
668 [UNSPEC_FCOS UNSPEC_FSIN UNSPEC_FTAN UNSPEC_FATAN UNSPEC_FEXP UNSPEC_FLOG])
669 (define_int_attr mathfunc [(UNSPEC_FCOS "cos") (UNSPEC_FSIN "sin")
670 (UNSPEC_FTAN "tan") (UNSPEC_FATAN "atan")
671 (UNSPEC_FEXP "exp") (UNSPEC_FLOG "log")])
672
673 (define_insn "<mathfunc><mode>2"
674 [(set (match_operand:F 0 "register_operand" "=r")
675 (unspec:F [(match_operand:F 1 "register_operand" "r")] MATHFUNC))]
676 "nios2_fpu_insn_enabled (n2fpu_f<mathfunc><f>)"
677 { return nios2_fpu_insn_asm (n2fpu_f<mathfunc><f>); }
678 [(set_attr "type" "custom")])
679
680 ;; Converting between floating point and fixed point
681
682 (define_code_iterator FLOAT [float unsigned_float])
683 (define_code_iterator FIX [fix unsigned_fix])
684
685 (define_code_attr conv_op [(float "float") (unsigned_float "floatuns")
686 (fix "fix") (unsigned_fix "fixuns")])
687 (define_code_attr i [(float "i") (unsigned_float "u")
688 (fix "i") (unsigned_fix "u")])
689
690 ;; Integer to float conversions
691 (define_insn "<conv_op>si<mode>2"
692 [(set (match_operand:F 0 "register_operand" "=r")
693 (FLOAT:F (match_operand:SI 1 "register_operand" "r")))]
694 "nios2_fpu_insn_enabled (n2fpu_float<i><f>)"
695 { return nios2_fpu_insn_asm (n2fpu_float<i><f>); }
696 [(set_attr "type" "custom")])
697
698 ;; Float to integer conversions
699 (define_insn "<conv_op>_trunc<mode>si2"
700 [(set (match_operand:SI 0 "register_operand" "=r")
701 (FIX:SI (match_operand:F 1 "general_operand" "r")))]
702 "nios2_fpu_insn_enabled (n2fpu_fix<f><i>)"
703 { return nios2_fpu_insn_asm (n2fpu_fix<f><i>); }
704 [(set_attr "type" "custom")])
705
706 (define_insn "lroundsfsi2"
707 [(set (match_operand:SI 0 "register_operand" "=r")
708 (unspec:SI [(match_operand:SF 1 "general_operand" "r")] UNSPEC_ROUND))]
709 "nios2_fpu_insn_enabled (n2fpu_round)"
710 { return nios2_fpu_insn_asm (n2fpu_round); }
711 [(set_attr "type" "custom")])
712
713 (define_insn "extendsfdf2"
714 [(set (match_operand:DF 0 "register_operand" "=r")
715 (float_extend:DF (match_operand:SF 1 "general_operand" "r")))]
716 "nios2_fpu_insn_enabled (n2fpu_fextsd)"
717 { return nios2_fpu_insn_asm (n2fpu_fextsd); }
718 [(set_attr "type" "custom")])
719
720 (define_insn "truncdfsf2"
721 [(set (match_operand:SF 0 "register_operand" "=r")
722 (float_truncate:SF (match_operand:DF 1 "general_operand" "r")))]
723 "nios2_fpu_insn_enabled (n2fpu_ftruncds)"
724 { return nios2_fpu_insn_asm (n2fpu_ftruncds); }
725 [(set_attr "type" "custom")])
726
727
728 \f
729 ;; Prologue, Epilogue and Return
730
731 (define_expand "prologue"
732 [(const_int 1)]
733 ""
734 {
735 nios2_expand_prologue ();
736 DONE;
737 })
738
739 (define_expand "epilogue"
740 [(return)]
741 ""
742 {
743 nios2_expand_epilogue (false);
744 DONE;
745 })
746
747 (define_expand "sibcall_epilogue"
748 [(return)]
749 ""
750 {
751 nios2_expand_epilogue (true);
752 DONE;
753 })
754
755 (define_expand "return"
756 [(simple_return)]
757 "nios2_can_use_return_insn ()"
758 {
759 if (nios2_expand_return ())
760 DONE;
761 })
762
763 (define_insn "simple_return"
764 [(simple_return)]
765 ""
766 "ret%."
767 [(set_attr "type" "control")])
768
769 ;; Block any insns from being moved before this point, since the
770 ;; profiling call to mcount can use various registers that aren't
771 ;; saved or used to pass arguments.
772
773 (define_insn "blockage"
774 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
775 ""
776 ""
777 [(set_attr "type" "unknown")
778 (set_attr "length" "0")])
779
780 ;; This is used in compiling the unwind routines.
781 (define_expand "eh_return"
782 [(use (match_operand 0 "general_operand"))]
783 ""
784 {
785 if (GET_MODE (operands[0]) != Pmode)
786 operands[0] = convert_to_mode (Pmode, operands[0], 0);
787 emit_insn (gen_eh_set_ra (operands[0]));
788 DONE;
789 })
790
791 ;; Modify the return address for EH return. We can't expand this
792 ;; until we know where it will be put in the stack frame.
793
794 (define_insn_and_split "eh_set_ra"
795 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
796 (clobber (match_scratch:SI 1 "=&r"))]
797 ""
798 "#"
799 "reload_completed"
800 [(const_int 0)]
801 {
802 nios2_set_return_address (operands[0], operands[1]);
803 DONE;
804 })
805
806 \f
807 ;; Jumps and calls
808
809 ; Note that the assembler fixes up any out-of-range branch instructions not
810 ; caught by the compiler branch shortening code. The sequence emitted by
811 ; the assembler can be very inefficient, but it is correct for PIC code.
812 ; For non-PIC we are better off converting to an absolute JMPI.
813 ;
814 ; Direct calls and sibcalls use the CALL and JMPI instructions, respectively.
815 ; These instructions have an immediate operand that specifies the low 28 bits
816 ; of the PC, effectively allowing direct calls within a 256MB memory segment.
817 ; Per the Nios II Processor Reference Handbook, the linker is not required to
818 ; check or adjust for overflow.
819
820 (define_insn "indirect_jump"
821 [(set (pc) (match_operand:SI 0 "register_operand" "c"))]
822 ""
823 "jmp%!\\t%0"
824 [(set_attr "type" "control")])
825
826 (define_insn "jump"
827 [(set (pc)
828 (label_ref (match_operand 0 "" "")))]
829 ""
830 {
831 if (get_attr_length (insn) == 2)
832 return "br.n\\t%0";
833 else if (get_attr_length (insn) == 4)
834 return "br\\t%0";
835 else
836 return "jmpi\\t%0";
837 }
838 [(set_attr "type" "control")
839 (set (attr "length")
840 (if_then_else
841 (and (match_test "TARGET_HAS_CDX")
842 (and (ge (minus (match_dup 0) (pc)) (const_int -1022))
843 (le (minus (match_dup 0) (pc)) (const_int 1022))))
844 (const_int 2)
845 (if_then_else
846 (ior (match_test "flag_pic")
847 (and (ge (minus (match_dup 0) (pc)) (const_int -32764))
848 (le (minus (match_dup 0) (pc)) (const_int 32764))))
849 (const_int 4)
850 (const_int 8))))])
851
852 (define_expand "call"
853 [(parallel [(call (match_operand 0 "" "")
854 (match_operand 1 "" ""))
855 (clobber (reg:SI RA_REGNO))])]
856 ""
857 "nios2_adjust_call_address (&operands[0], NULL_RTX);")
858
859 (define_expand "call_value"
860 [(parallel [(set (match_operand 0 "" "")
861 (call (match_operand 1 "" "")
862 (match_operand 2 "" "")))
863 (clobber (reg:SI RA_REGNO))])]
864 ""
865 "nios2_adjust_call_address (&operands[1], NULL_RTX);")
866
867 (define_insn "*call"
868 [(call (mem:QI (match_operand:SI 0 "call_operand" "i,r"))
869 (match_operand 1 "" ""))
870 (clobber (reg:SI RA_REGNO))]
871 ""
872 "@
873 call\\t%0
874 callr%.\\t%0"
875 [(set_attr "type" "control")])
876
877 (define_insn "*call_value"
878 [(set (match_operand 0 "" "")
879 (call (mem:QI (match_operand:SI 1 "call_operand" "i,r"))
880 (match_operand 2 "" "")))
881 (clobber (reg:SI RA_REGNO))]
882 ""
883 "@
884 call\\t%1
885 callr%.\\t%1"
886 [(set_attr "type" "control")])
887
888 (define_expand "sibcall"
889 [(parallel [(call (match_operand 0 "" "")
890 (match_operand 1 "" ""))
891 (return)])]
892 ""
893 "nios2_adjust_call_address (&operands[0], NULL_RTX);")
894
895 (define_expand "sibcall_value"
896 [(parallel [(set (match_operand 0 "" "")
897 (call (match_operand 1 "" "")
898 (match_operand 2 "" "")))
899 (return)])]
900 ""
901 "nios2_adjust_call_address (&operands[1], NULL_RTX);")
902
903 (define_insn "sibcall_internal"
904 [(call (mem:QI (match_operand:SI 0 "call_operand" "i,j"))
905 (match_operand 1 "" ""))
906 (return)]
907 ""
908 "@
909 jmpi\\t%0
910 jmp%!\\t%0"
911 [(set_attr "type" "control")])
912
913 (define_insn "sibcall_value_internal"
914 [(set (match_operand 0 "register_operand" "")
915 (call (mem:QI (match_operand:SI 1 "call_operand" "i,j"))
916 (match_operand 2 "" "")))
917 (return)]
918 ""
919 "@
920 jmpi\\t%1
921 jmp%!\\t%1"
922 [(set_attr "type" "control")])
923
924 (define_expand "tablejump"
925 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
926 (use (label_ref (match_operand 1 "" "")))])]
927 ""
928 {
929 if (flag_pic)
930 {
931 /* Hopefully, CSE will eliminate this copy. */
932 rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1]));
933 rtx reg2 = gen_reg_rtx (SImode);
934
935 emit_insn (gen_addsi3 (reg2, operands[0], reg1));
936 operands[0] = reg2;
937 }
938 })
939
940 (define_insn "*tablejump"
941 [(set (pc)
942 (match_operand:SI 0 "register_operand" "c"))
943 (use (label_ref (match_operand 1 "" "")))]
944 ""
945 "jmp%!\\t%0"
946 [(set_attr "type" "control")])
947
948 \f
949 ;; cstore, cbranch patterns
950
951 (define_mode_iterator CM [SI SF DF])
952
953 (define_expand "cstore<mode>4"
954 [(set (match_operand:SI 0 "register_operand" "=r")
955 (match_operator:SI 1 "expandable_comparison_operator"
956 [(match_operand:CM 2 "register_operand")
957 (match_operand:CM 3 "nonmemory_operand")]))]
958 ""
959 {
960 if (!nios2_validate_compare (<MODE>mode, &operands[1], &operands[2],
961 &operands[3]))
962 FAIL;
963 })
964
965 (define_expand "cbranch<mode>4"
966 [(set (pc)
967 (if_then_else
968 (match_operator 0 "expandable_comparison_operator"
969 [(match_operand:CM 1 "register_operand")
970 (match_operand:CM 2 "nonmemory_operand")])
971 (label_ref (match_operand 3 ""))
972 (pc)))]
973 ""
974 {
975 if (!nios2_validate_compare (<MODE>mode, &operands[0], &operands[1],
976 &operands[2]))
977 FAIL;
978 if (GET_MODE_CLASS (<MODE>mode) == MODE_FLOAT
979 || !reg_or_0_operand (operands[2], <MODE>mode))
980 {
981 rtx condreg = gen_reg_rtx (SImode);
982 emit_insn (gen_cstore<mode>4
983 (condreg, operands[0], operands[1], operands[2]));
984 operands[1] = condreg;
985 operands[2] = const0_rtx;
986 operands[0] = gen_rtx_fmt_ee (NE, VOIDmode, condreg, const0_rtx);
987 }
988 })
989
990 (define_insn "nios2_cbranch"
991 [(set (pc)
992 (if_then_else
993 (match_operator 0 "ordered_comparison_operator"
994 [(match_operand:SI 1 "reg_or_0_operand" "rM")
995 (match_operand:SI 2 "reg_or_0_operand" "rM")])
996 (label_ref (match_operand 3 "" ""))
997 (pc)))]
998 ""
999 {
1000 if (get_attr_length (insn) == 2)
1001 return "b%0z.n\t%z1, %l3";
1002 else if (get_attr_length (insn) == 4)
1003 return "b%0\t%z1, %z2, %l3";
1004 else if (get_attr_length (insn) == 6)
1005 return "b%R0z.n\t%z1, .+6;jmpi\t%l3";
1006 else
1007 return "b%R0\t%z1, %z2, .+8;jmpi\t%l3";
1008 }
1009 [(set_attr "type" "control")
1010 (set (attr "length")
1011 (cond
1012 [(and (match_test "nios2_cdx_narrow_form_p (insn)")
1013 (ge (minus (match_dup 3) (pc)) (const_int -126))
1014 (le (minus (match_dup 3) (pc)) (const_int 126)))
1015 (const_int 2)
1016 (ior (match_test "flag_pic")
1017 (and (ge (minus (match_dup 3) (pc)) (const_int -32764))
1018 (le (minus (match_dup 3) (pc)) (const_int 32764))))
1019 (const_int 4)
1020 (match_test "nios2_cdx_narrow_form_p (insn)")
1021 (const_int 6)]
1022 (const_int 8)))])
1023
1024 ;; Floating point comparisons
1025 (define_code_iterator FCMP [eq ne gt ge le lt])
1026 (define_insn "nios2_s<code><mode>"
1027 [(set (match_operand:SI 0 "register_operand" "=r")
1028 (FCMP:SI (match_operand:F 1 "register_operand" "r")
1029 (match_operand:F 2 "register_operand" "r")))]
1030 "nios2_fpu_insn_enabled (n2fpu_fcmp<code><f>)"
1031 { return nios2_fpu_insn_asm (n2fpu_fcmp<code><f>); }
1032 [(set_attr "type" "custom")])
1033
1034 ;; Integer comparisons
1035
1036 (define_code_iterator EQNE [eq ne])
1037 (define_insn "nios2_cmp<code>"
1038 [(set (match_operand:SI 0 "register_operand" "=r")
1039 (EQNE:SI (match_operand:SI 1 "register_operand" "%r")
1040 (match_operand:SI 2 "arith_operand" "rI")))]
1041 ""
1042 "cmp<code>%i2\\t%0, %1, %z2"
1043 [(set_attr "type" "alu")])
1044
1045 (define_code_iterator SCMP [ge lt])
1046 (define_insn "nios2_cmp<code>"
1047 [(set (match_operand:SI 0 "register_operand" "=r")
1048 (SCMP:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
1049 (match_operand:SI 2 "arith_operand" "rI")))]
1050 ""
1051 "cmp<code>%i2\\t%0, %z1, %z2"
1052 [(set_attr "type" "alu")])
1053
1054 (define_code_iterator UCMP [geu ltu])
1055 (define_insn "nios2_cmp<code>"
1056 [(set (match_operand:SI 0 "register_operand" "=r")
1057 (UCMP:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
1058 (match_operand:SI 2 "uns_arith_operand" "rJ")))]
1059 ""
1060 "cmp<code>%u2\\t%0, %z1, %z2"
1061 [(set_attr "type" "alu")])
1062
1063
1064 \f
1065 ;; Custom instruction patterns. The operands are intentionally
1066 ;; mode-less, to serve as generic carriers of all Altera defined
1067 ;; built-in instruction/function types.
1068
1069 (define_insn "custom_nxx"
1070 [(unspec_volatile [(match_operand 0 "custom_insn_opcode" "N")
1071 (match_operand 1 "reg_or_0_operand" "rM")
1072 (match_operand 2 "reg_or_0_operand" "rM")]
1073 UNSPECV_CUSTOM_NXX)]
1074 ""
1075 "custom\\t%0, zero, %z1, %z2"
1076 [(set_attr "type" "custom")])
1077
1078 (define_insn "custom_xnxx"
1079 [(set (match_operand 0 "register_operand" "=r")
1080 (unspec_volatile [(match_operand 1 "custom_insn_opcode" "N")
1081 (match_operand 2 "reg_or_0_operand" "rM")
1082 (match_operand 3 "reg_or_0_operand" "rM")]
1083 UNSPECV_CUSTOM_XNXX))]
1084 ""
1085 "custom\\t%1, %0, %z2, %z3"
1086 [(set_attr "type" "custom")])
1087
1088 \f
1089 ;; Misc. patterns
1090
1091 (define_insn "nop"
1092 [(const_int 0)]
1093 ""
1094 "nop%."
1095 [(set_attr "type" "nop")])
1096
1097 ;; Connect 'sync' to 'memory_barrier' standard expand name
1098 (define_expand "memory_barrier"
1099 [(const_int 0)]
1100 ""
1101 {
1102 emit_insn (gen_sync ());
1103 DONE;
1104 })
1105
1106 ;; For the nios2 __builtin_sync built-in function
1107 (define_expand "sync"
1108 [(set (match_dup 0)
1109 (unspec:BLK [(match_dup 0)] UNSPEC_SYNC))]
1110 ""
1111 {
1112 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
1113 MEM_VOLATILE_P (operands[0]) = 1;
1114 })
1115
1116 (define_insn "*sync_insn"
1117 [(set (match_operand:BLK 0 "" "")
1118 (unspec:BLK [(match_dup 0)] UNSPEC_SYNC))]
1119 ""
1120 "sync"
1121 [(set_attr "type" "control")])
1122
1123 (define_insn "rdctl"
1124 [(set (match_operand:SI 0 "register_operand" "=r")
1125 (unspec_volatile:SI [(match_operand:SI 1 "rdwrctl_operand" "O")]
1126 UNSPECV_RDCTL))]
1127 ""
1128 "rdctl\\t%0, ctl%1"
1129 [(set_attr "type" "control")])
1130
1131 (define_insn "wrctl"
1132 [(unspec_volatile:SI [(match_operand:SI 0 "rdwrctl_operand" "O")
1133 (match_operand:SI 1 "reg_or_0_operand" "rM")]
1134 UNSPECV_WRCTL)]
1135 ""
1136 "wrctl\\tctl%0, %z1"
1137 [(set_attr "type" "control")])
1138
1139 (define_insn "rdprs"
1140 [(set (match_operand:SI 0 "register_operand" "=r")
1141 (unspec_volatile:SI [(match_operand:SI 1 "rdwrctl_operand" "O")
1142 (match_operand:SI 2 "arith_operand" "U")]
1143 UNSPECV_RDPRS))]
1144 ""
1145 "rdprs\\t%0, %1, %2"
1146 [(set_attr "type" "control")])
1147
1148 ;; Cache Instructions
1149
1150 (define_insn "flushd"
1151 [(unspec_volatile:SI [(match_operand:SI 0 "ldstio_memory_operand" "w")]
1152 UNSPECV_FLUSHD)]
1153 ""
1154 "flushd\\t%0"
1155 [(set_attr "type" "control")])
1156
1157 (define_insn "flushda"
1158 [(unspec_volatile:SI [(match_operand:SI 0 "ldstio_memory_operand" "w")]
1159 UNSPECV_FLUSHDA)]
1160 ""
1161 "flushda\\t%0"
1162 [(set_attr "type" "control")])
1163
1164 ;; R2 Instructions
1165
1166 (define_insn "wrpie"
1167 [(set (match_operand:SI 0 "register_operand" "=r")
1168 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r")]
1169 UNSPECV_WRPIE))]
1170 "TARGET_ARCH_R2"
1171 "wrpie\\t%0, %1"
1172 [(set_attr "type" "control")])
1173
1174 (define_insn "eni"
1175 [(unspec:VOID [(match_operand 0 "const_int_operand" "i")]
1176 UNSPECV_ENI)]
1177 "TARGET_ARCH_R2"
1178 "eni\\t%0"
1179 [(set_attr "type" "control")])
1180
1181 ;; Trap patterns
1182 (define_insn "trap"
1183 [(trap_if (const_int 1) (const_int 3))]
1184 ""
1185 "trap%.\\t3"
1186 [(set_attr "type" "control")])
1187
1188 (define_insn "ctrapsi4"
1189 [(trap_if (match_operator 0 "ordered_comparison_operator"
1190 [(match_operand:SI 1 "reg_or_0_operand" "rM")
1191 (match_operand:SI 2 "reg_or_0_operand" "rM")])
1192 (match_operand 3 "const_int_operand" "i"))]
1193 ""
1194 {
1195 if (get_attr_length (insn) == 6)
1196 return "b%R0\\t%z1, %z2, 1f\;trap.n\\t%3\;1:";
1197 else
1198 return "b%R0\\t%z1, %z2, 1f\;trap\\t%3\;1:";
1199 }
1200 [(set_attr "type" "control")
1201 (set (attr "length")
1202 (if_then_else (match_test "nios2_cdx_narrow_form_p (insn)")
1203 (const_int 6) (const_int 8)))])
1204
1205 ;; Load the GOT register.
1206 (define_insn "load_got_register"
1207 [(set (match_operand:SI 0 "register_operand" "=&r")
1208 (unspec:SI [(const_int 0)] UNSPEC_LOAD_GOT_REGISTER))
1209 (set (match_operand:SI 1 "register_operand" "=r")
1210 (unspec:SI [(const_int 0)] UNSPEC_LOAD_GOT_REGISTER))]
1211 ""
1212 "nextpc\\t%0
1213 \\t1:
1214 \\tmovhi\\t%1, %%hiadj(_gp_got - 1b)
1215 \\taddi\\t%1, %1, %%lo(_gp_got - 1b)"
1216 [(set_attr "length" "12")])
1217
1218 ;; Read thread pointer register
1219 (define_expand "get_thread_pointersi"
1220 [(match_operand:SI 0 "register_operand" "=r")]
1221 "TARGET_LINUX_ABI"
1222 {
1223 emit_move_insn (operands[0], gen_rtx_REG (Pmode, TP_REGNO));
1224 DONE;
1225 })
1226
1227 ;; Synchronization Primitives
1228 (include "sync.md")
1229
1230 ;; Include the ldwm/stwm/push.n/pop.n patterns and peepholes.
1231 (include "ldstwm.md")
1232