1 ;; Machine Description for Altera Nios II.
2 ;; Copyright (C) 2012 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.
7 ;; This file is part of GCC.
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)
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.
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/>.
24 ;; Enumeration of UNSPECs
26 (define_c_enum "unspecv" [
31 UNSPECV_STACK_OVERFLOW_DETECT_AND_TRAP
43 (define_c_enum "unspec" [
50 UNSPEC_LOAD_GOT_REGISTER
65 ;; Instruction scheduler
67 ; No schedule info is currently available, using an assumption that no
68 ; instruction can use the results of the previous instruction without
71 ; length of an instruction (in bytes)
72 (define_attr "length" "" (const_int 4))
74 "unknown,complex,control,alu,cond_alu,st,ld,shift,mul,div,custom"
75 (const_string "complex"))
77 (define_asm_attributes
78 [(set_attr "length" "4")
79 (set_attr "type" "complex")])
81 (define_automaton "nios2")
83 ;(automata_option "no-minimization")
84 (automata_option "ndfa")
86 ; The nios2 pipeline is fairly straightforward for the fast model.
87 ; Every alu operation is pipelined so that an instruction can
88 ; be issued every cycle. However, there are still potential
89 ; stalls which this description tries to deal with.
91 (define_cpu_unit "cpu" "nios2")
93 (define_insn_reservation "complex" 1
94 (eq_attr "type" "complex")
97 (define_insn_reservation "control" 1
98 (eq_attr "type" "control")
101 (define_insn_reservation "alu" 1
102 (eq_attr "type" "alu")
105 (define_insn_reservation "cond_alu" 1
106 (eq_attr "type" "cond_alu")
109 (define_insn_reservation "st" 1
110 (eq_attr "type" "st")
113 (define_insn_reservation "custom" 1
114 (eq_attr "type" "custom")
117 ; shifts, muls and lds have three cycle latency
118 (define_insn_reservation "ld" 3
119 (eq_attr "type" "ld")
122 (define_insn_reservation "shift" 3
123 (eq_attr "type" "shift")
126 (define_insn_reservation "mul" 3
127 (eq_attr "type" "mul")
130 (define_insn_reservation "div" 1
131 (eq_attr "type" "div")
134 (include "predicates.md")
135 (include "constraints.md")
140 (define_mode_iterator M [QI HI SI])
142 (define_expand "mov<mode>"
143 [(set (match_operand:M 0 "nonimmediate_operand" "")
144 (match_operand:M 1 "general_operand" ""))]
147 if (nios2_emit_move_sequence (operands, <MODE>mode))
151 (define_insn "movqi_internal"
152 [(set (match_operand:QI 0 "nonimmediate_operand" "=m, r,r, r")
153 (match_operand:QI 1 "general_operand" "rM,m,rM,I"))]
154 "(register_operand (operands[0], QImode)
155 || reg_or_0_operand (operands[1], QImode))"
161 [(set_attr "type" "st,ld,alu,alu")])
163 (define_insn "movhi_internal"
164 [(set (match_operand:HI 0 "nonimmediate_operand" "=m, r,r, r,r")
165 (match_operand:HI 1 "general_operand" "rM,m,rM,I,J"))]
166 "(register_operand (operands[0], HImode)
167 || reg_or_0_operand (operands[1], HImode))"
174 [(set_attr "type" "st,ld,alu,alu,alu")])
176 (define_insn "movsi_internal"
177 [(set (match_operand:SI 0 "nonimmediate_operand" "=m, r,r, r,r,r,r,r")
178 (match_operand:SI 1 "general_operand" "rM,m,rM,I,J,K,S,i"))]
179 "(register_operand (operands[0], SImode)
180 || reg_or_0_operand (operands[1], SImode))"
188 addi\\t%0, gp, %%gprel(%1)
189 movhi\\t%0, %H1\;addi\\t%0, %0, %L1"
190 [(set_attr "type" "st,ld,alu,alu,alu,alu,alu,alu")
191 (set_attr "length" "4,4,4,4,4,4,4,8")])
194 (define_mode_iterator BH [QI HI])
195 (define_mode_iterator BHW [QI HI SI])
196 (define_mode_attr bh [(QI "b") (HI "h")])
197 (define_mode_attr bhw [(QI "b") (HI "h") (SI "w")])
198 (define_mode_attr bhw_uns [(QI "bu") (HI "hu") (SI "w")])
200 (define_insn "ld<bhw_uns>io"
201 [(set (match_operand:BHW 0 "register_operand" "=r")
203 [(match_operand:BHW 1 "memory_operand" "m")] UNSPECV_LDXIO))]
205 "ld<bhw_uns>io\\t%0, %1"
206 [(set_attr "type" "ld")])
208 (define_expand "ld<bh>io"
209 [(set (match_operand:BH 0 "register_operand" "=r")
210 (match_operand:BH 1 "memory_operand" "m"))]
213 rtx tmp = gen_reg_rtx (SImode);
214 emit_insn (gen_ld<bh>io_signed (tmp, operands[1]));
215 emit_insn (gen_mov<mode> (operands[0], gen_lowpart (<MODE>mode, tmp)));
219 (define_insn "ld<bh>io_signed"
220 [(set (match_operand:SI 0 "register_operand" "=r")
223 [(match_operand:BH 1 "memory_operand" "m")] UNSPECV_LDXIO)))]
226 [(set_attr "type" "ld")])
228 (define_insn "st<bhw>io"
229 [(set (match_operand:BHW 0 "memory_operand" "=m")
231 [(match_operand:BHW 1 "reg_or_0_operand" "rM")] UNSPECV_STXIO))]
233 "st<bhw>io\\t%z1, %0"
234 [(set_attr "type" "st")])
237 ;; QI to [HI, SI] extension patterns are collected together
238 (define_mode_iterator QX [HI SI])
240 ;; Zero extension patterns
241 (define_insn "zero_extendhisi2"
242 [(set (match_operand:SI 0 "register_operand" "=r,r")
243 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
246 andi\\t%0, %1, 0xffff
248 [(set_attr "type" "alu,ld")])
250 (define_insn "zero_extendqi<mode>2"
251 [(set (match_operand:QX 0 "register_operand" "=r,r")
252 (zero_extend:QX (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
257 [(set_attr "type" "alu,ld")])
259 ;; Sign extension patterns
261 (define_insn "extendhisi2"
262 [(set (match_operand:SI 0 "register_operand" "=r,r")
263 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
268 [(set_attr "type" "alu,ld")])
270 (define_insn "extendqi<mode>2"
271 [(set (match_operand:QX 0 "register_operand" "=r,r")
272 (sign_extend:QX (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
277 [(set_attr "type" "alu,ld")])
279 ;; Split patterns for register alternative cases.
281 [(set (match_operand:SI 0 "register_operand" "")
282 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
285 (and:SI (match_dup 1) (const_int 65535)))
287 (xor:SI (match_dup 0) (const_int 32768)))
289 (plus:SI (match_dup 0) (const_int -32768)))]
290 "operands[1] = gen_lowpart (SImode, operands[1]);")
293 [(set (match_operand:QX 0 "register_operand" "")
294 (sign_extend:QX (match_operand:QI 1 "register_operand" "")))]
297 (and:SI (match_dup 1) (const_int 255)))
299 (xor:SI (match_dup 0) (const_int 128)))
301 (plus:SI (match_dup 0) (const_int -128)))]
302 "operands[0] = gen_lowpart (SImode, operands[0]);
303 operands[1] = gen_lowpart (SImode, operands[1]);")
306 ;; Arithmetic Operations
308 (define_insn "addsi3"
309 [(set (match_operand:SI 0 "register_operand" "=r")
310 (plus:SI (match_operand:SI 1 "register_operand" "%r")
311 (match_operand:SI 2 "arith_operand" "rI")))]
313 "add%i2\\t%0, %1, %z2"
314 [(set_attr "type" "alu")])
316 (define_insn "subsi3"
317 [(set (match_operand:SI 0 "register_operand" "=r")
318 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
319 (match_operand:SI 2 "register_operand" "r")))]
322 [(set_attr "type" "alu")])
324 (define_insn "mulsi3"
325 [(set (match_operand:SI 0 "register_operand" "=r")
326 (mult:SI (match_operand:SI 1 "register_operand" "%r")
327 (match_operand:SI 2 "arith_operand" "rI")))]
329 "mul%i2\\t%0, %1, %z2"
330 [(set_attr "type" "mul")])
332 (define_expand "divsi3"
333 [(set (match_operand:SI 0 "register_operand" "=r")
334 (div:SI (match_operand:SI 1 "register_operand" "r")
335 (match_operand:SI 2 "register_operand" "r")))]
340 if (!TARGET_FAST_SW_DIV)
344 if (nios2_emit_expensive_div (operands, SImode))
350 (define_insn "divsi3_insn"
351 [(set (match_operand:SI 0 "register_operand" "=r")
352 (div:SI (match_operand:SI 1 "register_operand" "r")
353 (match_operand:SI 2 "register_operand" "r")))]
356 [(set_attr "type" "div")])
358 (define_insn "udivsi3"
359 [(set (match_operand:SI 0 "register_operand" "=r")
360 (udiv:SI (match_operand:SI 1 "register_operand" "r")
361 (match_operand:SI 2 "register_operand" "r")))]
364 [(set_attr "type" "div")])
366 (define_code_iterator EXTEND [sign_extend zero_extend])
367 (define_code_attr us [(sign_extend "s") (zero_extend "u")])
368 (define_code_attr mul [(sign_extend "mul") (zero_extend "umul")])
370 (define_insn "<us>mulsi3_highpart"
371 [(set (match_operand:SI 0 "register_operand" "=r")
374 (mult:DI (EXTEND:DI (match_operand:SI 1 "register_operand" "r"))
375 (EXTEND:DI (match_operand:SI 2 "register_operand" "r")))
378 "mulx<us><us>\\t%0, %1, %2"
379 [(set_attr "type" "mul")])
381 (define_expand "<mul>sidi3"
382 [(set (match_operand:DI 0 "register_operand" "")
383 (mult:DI (EXTEND:DI (match_operand:SI 1 "register_operand" ""))
384 (EXTEND:DI (match_operand:SI 2 "register_operand" ""))))]
387 rtx hi = gen_reg_rtx (SImode);
388 rtx lo = gen_reg_rtx (SImode);
390 emit_insn (gen_<us>mulsi3_highpart (hi, operands[1], operands[2]));
391 emit_insn (gen_mulsi3 (lo, operands[1], operands[2]));
392 emit_move_insn (gen_lowpart (SImode, operands[0]), lo);
393 emit_move_insn (gen_highpart (SImode, operands[0]), hi);
398 ;; Negate and ones complement
400 (define_insn "negsi2"
401 [(set (match_operand:SI 0 "register_operand" "=r")
402 (neg:SI (match_operand:SI 1 "register_operand" "r")))]
405 [(set_attr "type" "alu")])
407 (define_insn "one_cmplsi2"
408 [(set (match_operand:SI 0 "register_operand" "=r")
409 (not:SI (match_operand:SI 1 "register_operand" "r")))]
412 [(set_attr "type" "alu")])
415 ;; Integer logical Operations
417 (define_code_iterator LOGICAL [and ior xor])
418 (define_code_attr logical_asm [(and "and") (ior "or") (xor "xor")])
420 (define_insn "<code>si3"
421 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
422 (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r,r")
423 (match_operand:SI 2 "logical_operand" "rM,J,K")))]
426 <logical_asm>\\t%0, %1, %z2
427 <logical_asm>%i2\\t%0, %1, %2
428 <logical_asm>h%i2\\t%0, %1, %U2"
429 [(set_attr "type" "alu")])
431 (define_insn "*norsi3"
432 [(set (match_operand:SI 0 "register_operand" "=r")
433 (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r"))
434 (not:SI (match_operand:SI 2 "reg_or_0_operand" "rM"))))]
437 [(set_attr "type" "alu")])
440 ;; Shift instructions
442 (define_code_iterator SHIFT [ashift ashiftrt lshiftrt rotate])
443 (define_code_attr shift_op [(ashift "ashl") (ashiftrt "ashr")
444 (lshiftrt "lshr") (rotate "rotl")])
445 (define_code_attr shift_asm [(ashift "sll") (ashiftrt "sra")
446 (lshiftrt "srl") (rotate "rol")])
448 (define_insn "<shift_op>si3"
449 [(set (match_operand:SI 0 "register_operand" "=r")
450 (SHIFT:SI (match_operand:SI 1 "register_operand" "r")
451 (match_operand:SI 2 "shift_operand" "rL")))]
453 "<shift_asm>%i2\\t%0, %1, %z2"
454 [(set_attr "type" "shift")])
456 (define_insn "rotrsi3"
457 [(set (match_operand:SI 0 "register_operand" "=r")
458 (rotatert:SI (match_operand:SI 1 "register_operand" "r")
459 (match_operand:SI 2 "register_operand" "r")))]
462 [(set_attr "type" "shift")])
466 ;; Floating point instructions
468 ;; Mode iterator for single/double float
469 (define_mode_iterator F [SF DF])
470 (define_mode_attr f [(SF "s") (DF "d")])
472 ;; Basic arithmetic instructions
473 (define_code_iterator FOP3 [plus minus mult div])
474 (define_code_attr fop3 [(plus "add") (minus "sub") (mult "mul") (div "div")])
476 (define_insn "<fop3><mode>3"
477 [(set (match_operand:F 0 "register_operand" "=r")
478 (FOP3:F (match_operand:F 1 "register_operand" "r")
479 (match_operand:F 2 "register_operand" "r")))]
480 "nios2_fpu_insn_enabled (n2fpu_f<fop3><f>)"
481 "* return nios2_fpu_insn_asm (n2fpu_f<fop3><f>);"
482 [(set_attr "type" "custom")])
484 ;; Floating point min/max operations
485 (define_code_iterator SMINMAX [smin smax])
486 (define_code_attr minmax [(smin "min") (smax "max")])
487 (define_insn "<code><mode>3"
488 [(set (match_operand:F 0 "register_operand" "=r")
489 (SMINMAX:F (match_operand:F 1 "register_operand" "r")
490 (match_operand:F 2 "register_operand" "r")))]
491 "nios2_fpu_insn_enabled (n2fpu_f<minmax><f>)"
492 "* return nios2_fpu_insn_asm (n2fpu_f<minmax><f>);"
493 [(set_attr "type" "custom")])
495 ;; These 2-operand FP operations can be collected together
496 (define_code_iterator FOP2 [abs neg sqrt])
497 (define_insn "<code><mode>2"
498 [(set (match_operand:F 0 "register_operand" "=r")
499 (FOP2:F (match_operand:F 1 "register_operand" "r")))]
500 "nios2_fpu_insn_enabled (n2fpu_f<code><f>)"
501 "* return nios2_fpu_insn_asm (n2fpu_f<code><f>);"
502 [(set_attr "type" "custom")])
504 ;; X, Y register access instructions
505 (define_insn "nios2_fwrx"
506 [(unspec_volatile [(match_operand:DF 0 "register_operand" "r")] UNSPECV_FWRX)]
507 "nios2_fpu_insn_enabled (n2fpu_fwrx)"
508 "* return nios2_fpu_insn_asm (n2fpu_fwrx);"
509 [(set_attr "type" "custom")])
511 (define_insn "nios2_fwry"
512 [(unspec_volatile [(match_operand:SF 0 "register_operand" "r")] UNSPECV_FWRY)]
513 "nios2_fpu_insn_enabled (n2fpu_fwry)"
514 "* return nios2_fpu_insn_asm (n2fpu_fwry);"
515 [(set_attr "type" "custom")])
517 ;; The X, Y read insns uses an int iterator
518 (define_int_iterator UNSPEC_READ_XY [UNSPECV_FRDXLO UNSPECV_FRDXHI
520 (define_int_attr read_xy [(UNSPECV_FRDXLO "frdxlo") (UNSPECV_FRDXHI "frdxhi")
521 (UNSPECV_FRDY "frdy")])
522 (define_insn "nios2_<read_xy>"
523 [(set (match_operand:SF 0 "register_operand" "=r")
524 (unspec_volatile:SF [(const_int 0)] UNSPEC_READ_XY))]
525 "nios2_fpu_insn_enabled (n2fpu_<read_xy>)"
526 "* return nios2_fpu_insn_asm (n2fpu_<read_xy>);"
527 [(set_attr "type" "custom")])
529 ;; Various math functions
530 (define_int_iterator MATHFUNC
531 [UNSPEC_FCOS UNSPEC_FSIN UNSPEC_FTAN UNSPEC_FATAN UNSPEC_FEXP UNSPEC_FLOG])
532 (define_int_attr mathfunc [(UNSPEC_FCOS "cos") (UNSPEC_FSIN "sin")
533 (UNSPEC_FTAN "tan") (UNSPEC_FATAN "atan")
534 (UNSPEC_FEXP "exp") (UNSPEC_FLOG "log")])
536 (define_insn "<mathfunc><mode>2"
537 [(set (match_operand:F 0 "register_operand" "=r")
538 (unspec:F [(match_operand:F 1 "register_operand" "r")] MATHFUNC))]
539 "nios2_fpu_insn_enabled (n2fpu_f<mathfunc><f>)"
540 "* return nios2_fpu_insn_asm (n2fpu_f<mathfunc><f>);"
541 [(set_attr "type" "custom")])
543 ;; Converting between floating point and fixed point
545 (define_code_iterator FLOAT [float unsigned_float])
546 (define_code_iterator FIX [fix unsigned_fix])
548 (define_code_attr conv_op [(float "float") (unsigned_float "floatuns")
549 (fix "fix") (unsigned_fix "fixuns")])
550 (define_code_attr i [(float "i") (unsigned_float "u")
551 (fix "i") (unsigned_fix "u")])
553 ;; Integer to float conversions
554 (define_insn "<conv_op>si<mode>2"
555 [(set (match_operand:F 0 "register_operand" "=r")
556 (FLOAT:F (match_operand:SI 1 "register_operand" "r")))]
557 "nios2_fpu_insn_enabled (n2fpu_float<i><f>)"
558 "* return nios2_fpu_insn_asm (n2fpu_float<i><f>);"
559 [(set_attr "type" "custom")])
561 ;; Float to integer conversions
562 (define_insn "<conv_op>_trunc<mode>si2"
563 [(set (match_operand:SI 0 "register_operand" "=r")
564 (FIX:SI (match_operand:F 1 "general_operand" "r")))]
565 "nios2_fpu_insn_enabled (n2fpu_fix<f><i>)"
566 "* return nios2_fpu_insn_asm (n2fpu_fix<f><i>);"
567 [(set_attr "type" "custom")])
569 (define_insn "extendsfdf2"
570 [(set (match_operand:DF 0 "register_operand" "=r")
571 (float_extend:DF (match_operand:SF 1 "general_operand" "r")))]
572 "nios2_fpu_insn_enabled (n2fpu_fextsd)"
573 "* return nios2_fpu_insn_asm (n2fpu_fextsd);"
574 [(set_attr "type" "custom")])
576 (define_insn "truncdfsf2"
577 [(set (match_operand:SF 0 "register_operand" "=r")
578 (float_truncate:SF (match_operand:DF 1 "general_operand" "r")))]
579 "nios2_fpu_insn_enabled (n2fpu_ftruncds)"
580 "* return nios2_fpu_insn_asm (n2fpu_ftruncds);"
581 [(set_attr "type" "custom")])
585 ;; Prologue, Epilogue and Return
587 (define_expand "prologue"
595 (define_expand "epilogue"
599 expand_epilogue (false);
603 (define_expand "sibcall_epilogue"
607 expand_epilogue (true);
611 (define_insn "return"
613 "nios2_can_use_return_insn ()"
617 (define_insn "return_from_epilogue"
618 [(use (match_operand 0 "pmode_register_operand" ""))
624 ;; Block any insns from being moved before this point, since the
625 ;; profiling call to mcount can use various registers that aren't
626 ;; saved or used to pass arguments.
628 (define_insn "blockage"
629 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
632 [(set_attr "type" "unknown")
633 (set_attr "length" "0")])
635 ;; This is used in compiling the unwind routines.
636 (define_expand "eh_return"
637 [(use (match_operand 0 "general_operand"))]
640 if (GET_MODE (operands[0]) != Pmode)
641 operands[0] = convert_to_mode (Pmode, operands[0], 0);
642 emit_insn (gen_eh_set_ra (operands[0]));
647 ;; Clobber the return address on the stack. We can't expand this
648 ;; until we know where it will be put in the stack frame.
650 (define_insn "eh_set_ra"
651 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
652 (clobber (match_scratch:SI 1 "=&r"))]
657 [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN)
658 (clobber (match_scratch 1))]
662 nios2_set_return_address (operands[0], operands[1]);
669 ; Note that the assembler fixes up any out-of-range branch instructions not
670 ; caught by the compiler branch shortening code. The sequence emitted by
671 ; the assembler can be very inefficient, but it is correct for PIC code.
672 ; For non-PIC we are better off converting to an absolute JMPI.
674 ; Direct calls and sibcalls use the CALL and JMPI instructions, respectively.
675 ; These instructions have an immediate operand that specifies the low 28 bits
676 ; of the PC, effectively allowing direct calls within a 256MB memory segment.
677 ; Per the Nios II Processor Reference Handbook, the linker is not required to
678 ; check or adjust for overflow.
680 (define_insn "indirect_jump"
681 [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
684 [(set_attr "type" "control")])
688 (label_ref (match_operand 0 "" "")))]
691 if (flag_pic || get_attr_length (insn) == 4)
696 [(set_attr "type" "control")
699 (and (ge (minus (match_dup 0) (pc)) (const_int -32768))
700 (le (minus (match_dup 0) (pc)) (const_int 32764)))
705 (define_expand "call"
706 [(parallel [(call (match_operand 0 "" "")
707 (match_operand 1 "" ""))
708 (clobber (reg:SI 31))])]
710 "nios2_adjust_call_address (&XEXP (operands[0], 0));"
713 (define_expand "call_value"
714 [(parallel [(set (match_operand 0 "" "")
715 (call (match_operand 1 "" "")
716 (match_operand 2 "" "")))
717 (clobber (reg:SI 31))])]
719 "nios2_adjust_call_address (&XEXP (operands[1], 0));"
723 [(call (mem:QI (match_operand:SI 0 "call_operand" "i,r"))
724 (match_operand 1 "" ""))
725 (clobber (reg:SI 31))]
730 [(set_attr "type" "control,control")])
732 (define_insn "*call_value"
733 [(set (match_operand 0 "" "")
734 (call (mem:QI (match_operand:SI 1 "call_operand" "i,r"))
735 (match_operand 2 "" "")))
736 (clobber (reg:SI 31))]
741 [(set_attr "type" "control,control")])
743 (define_expand "sibcall"
744 [(parallel [(call (match_operand 0 "" "")
745 (match_operand 1 "" ""))
748 "nios2_adjust_call_address (&XEXP (operands[0], 0));"
751 (define_expand "sibcall_value"
752 [(parallel [(set (match_operand 0 "" "")
753 (call (match_operand 1 "" "")
754 (match_operand 2 "" "")))
757 "nios2_adjust_call_address (&XEXP (operands[1], 0));"
760 (define_insn "*sibcall"
761 [(call (mem:QI (match_operand:SI 0 "call_operand" "i,j"))
762 (match_operand 1 "" ""))
770 (define_insn "*sibcall_value"
771 [(set (match_operand 0 "register_operand" "")
772 (call (mem:QI (match_operand:SI 1 "call_operand" "i,j"))
773 (match_operand 2 "" "")))
781 (define_expand "tablejump"
782 [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
783 (use (label_ref (match_operand 1 "" "")))])]
788 /* Hopefully, CSE will eliminate this copy. */
789 rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1]));
790 rtx reg2 = gen_reg_rtx (SImode);
792 emit_insn (gen_addsi3 (reg2, operands[0], reg1));
798 (define_insn "*tablejump"
800 (match_operand:SI 0 "register_operand" "r"))
801 (use (label_ref (match_operand 1 "" "")))]
804 [(set_attr "type" "control")])
808 ;; cstore, cbranch patterns
810 (define_mode_iterator CM [SI SF DF])
812 (define_expand "cstore<mode>4"
813 [(set (match_operand:SI 0 "register_operand" "=r")
814 (match_operator:SI 1 "ordered_comparison_operator"
815 [(match_operand:CM 2 "register_operand")
816 (match_operand:CM 3 "nonmemory_operand")]))]
817 "nios2_supported_compare_p (<MODE>mode)"
819 if (!nios2_validate_compare (<MODE>mode, &operands[1], &operands[2],
824 (define_expand "cbranch<mode>4"
827 (match_operator 0 "ordered_comparison_operator"
828 [(match_operand:CM 1 "register_operand")
829 (match_operand:CM 2 "nonmemory_operand")])
830 (label_ref (match_operand 3 ""))
832 "nios2_supported_compare_p (<MODE>mode)"
834 if (!nios2_validate_compare (<MODE>mode, &operands[0], &operands[1],
837 if (GET_MODE_CLASS (<MODE>mode) == MODE_FLOAT
838 || !reg_or_0_operand (operands[2], <MODE>mode))
840 rtx condreg = gen_reg_rtx (SImode);
841 emit_insn (gen_cstore<mode>4
842 (condreg, operands[0], operands[1], operands[2]));
843 operands[1] = condreg;
844 operands[2] = const0_rtx;
845 operands[0] = gen_rtx_fmt_ee (NE, VOIDmode, condreg, const0_rtx);
849 (define_insn "nios2_cbranch"
852 (match_operator 0 "ordered_comparison_operator"
853 [(match_operand:SI 1 "reg_or_0_operand" "rM")
854 (match_operand:SI 2 "reg_or_0_operand" "rM")])
855 (label_ref (match_operand 3 "" ""))
859 if (flag_pic || get_attr_length (insn) == 4)
860 return "b%0\t%z1, %z2, %l3";
862 return "b%R0\t%z1, %z2, .+8;jmpi\t%l3";
864 [(set_attr "type" "control")
867 (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
868 (le (minus (match_dup 1) (pc)) (const_int 32764)))
869 (const_int 4) (const_int 8)))])
871 ;; Floating point comparisons
872 (define_code_iterator FCMP [eq ne gt ge le lt])
873 (define_insn "nios2_s<code><mode>"
874 [(set (match_operand:SI 0 "register_operand" "=r")
875 (FCMP:SI (match_operand:F 1 "register_operand" "r")
876 (match_operand:F 2 "register_operand" "r")))]
877 "nios2_fpu_insn_enabled (n2fpu_fcmp<code><f>)"
878 "* return nios2_fpu_insn_asm (n2fpu_fcmp<code><f>);"
879 [(set_attr "type" "custom")])
881 ;; Integer comparisons
883 (define_code_iterator EQNE [eq ne])
884 (define_insn "nios2_cmp<code>"
885 [(set (match_operand:SI 0 "register_operand" "=r")
886 (EQNE:SI (match_operand:SI 1 "reg_or_0_operand" "%rM")
887 (match_operand:SI 2 "arith_operand" "rI")))]
889 "cmp<code>%i2\\t%0, %z1, %z2"
890 [(set_attr "type" "alu")])
892 (define_code_iterator SCMP [ge lt])
893 (define_insn "nios2_cmp<code>"
894 [(set (match_operand:SI 0 "register_operand" "=r")
895 (SCMP:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
896 (match_operand:SI 2 "arith_operand" "rI")))]
898 "cmp<code>%i2\\t%0, %z1, %z2"
899 [(set_attr "type" "alu")])
901 (define_code_iterator UCMP [geu ltu])
902 (define_insn "nios2_cmp<code>"
903 [(set (match_operand:SI 0 "register_operand" "=r")
904 (UCMP:SI (match_operand:SI 1 "reg_or_0_operand" "rM")
905 (match_operand:SI 2 "uns_arith_operand" "rJ")))]
907 "cmp<code>%i2\\t%0, %z1, %z2"
908 [(set_attr "type" "alu")])
912 ;; Custom instruction patterns. The operands are intentionally
913 ;; mode-less, to serve as generic carriers of all Altera defined
914 ;; built-in instruction/function types.
916 (define_insn "custom_nxx"
917 [(unspec_volatile [(match_operand 0 "custom_insn_opcode" "N")
918 (match_operand 1 "reg_or_0_operand" "rM")
919 (match_operand 2 "reg_or_0_operand" "rM")]
922 "custom\\t%0, zero, %z1, %z2"
923 [(set_attr "type" "custom")])
925 (define_insn "custom_xnxx"
926 [(set (match_operand 0 "register_operand" "=r")
927 (unspec_volatile [(match_operand 1 "custom_insn_opcode" "N")
928 (match_operand 2 "reg_or_0_operand" "rM")
929 (match_operand 3 "reg_or_0_operand" "rM")]
930 UNSPECV_CUSTOM_XNXX))]
932 "custom\\t%1, %0, %z2, %z3"
933 [(set_attr "type" "custom")])
942 [(set_attr "type" "alu")])
944 ;; Connect 'sync' to 'memory_barrier' standard expand name
945 (define_expand "memory_barrier"
949 emit_insn (gen_sync ());
953 ;; For the nios2 __builtin_sync built-in function
954 (define_expand "sync"
956 (unspec:BLK [(match_dup 0)] UNSPEC_SYNC))]
959 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
960 MEM_VOLATILE_P (operands[0]) = 1;
963 (define_insn "*sync_insn"
964 [(set (match_operand:BLK 0 "" "")
965 (unspec:BLK [(match_dup 0)] UNSPEC_SYNC))]
968 [(set_attr "type" "control")])
971 [(set (match_operand:SI 0 "register_operand" "=r")
972 (unspec_volatile:SI [(match_operand:SI 1 "rdwrctl_operand" "O")]
976 [(set_attr "type" "control")])
979 [(unspec_volatile:SI [(match_operand:SI 0 "rdwrctl_operand" "O")
980 (match_operand:SI 1 "reg_or_0_operand" "rM")]
984 [(set_attr "type" "control")])
986 ;; Used to signal a stack overflow
988 [(unspec_volatile [(const_int 0)] UNSPECV_TRAP)]
991 [(set_attr "type" "control")])
993 (define_insn "stack_overflow_detect_and_trap"
994 [(unspec_volatile [(const_int 0)] UNSPECV_STACK_OVERFLOW_DETECT_AND_TRAP)]
996 "bgeu\\tsp, et, 1f\;break\\t3\;1:"
997 [(set_attr "type" "control")
998 (set_attr "length" "8")])
1000 ;; Load the GOT register.
1001 (define_insn "load_got_register"
1002 [(set (match_operand:SI 0 "register_operand" "=&r")
1003 (unspec:SI [(const_int 0)] UNSPEC_LOAD_GOT_REGISTER))
1004 (set (match_operand:SI 1 "register_operand" "=r")
1005 (unspec:SI [(const_int 0)] UNSPEC_LOAD_GOT_REGISTER))]
1009 \\tmovhi\\t%1, %%hiadj(_GLOBAL_OFFSET_TABLE_ - 1b)
1010 \\taddi\\t%1, %1, %%lo(_GLOBAL_OFFSET_TABLE_ - 1b)"
1011 [(set_attr "length" "12")])
1013 ;; When generating pic, we need to load the symbol offset into a register.
1014 ;; So that the optimizer does not confuse this with a normal symbol load
1015 ;; we use an unspec. The offset will be loaded from a constant pool entry,
1016 ;; since that is the only type of relocation we can use.
1018 ;; The rather odd constraints on the following are to force reload to leave
1019 ;; the insn alone, and to force the minipool generation pass to then move
1020 ;; the GOT symbol to memory.
1022 (define_insn "pic_load_addr"
1023 [(set (match_operand:SI 0 "register_operand" "=r")
1024 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1025 (match_operand:SI 2 "" "mX")] UNSPEC_PIC_SYM))]
1026 "flag_pic && TARGET_LINUX_ABI"
1027 "ldw\\t%0, %%got(%2)(%1)")
1029 (define_insn "pic_load_call_addr"
1030 [(set (match_operand:SI 0 "register_operand" "=r")
1031 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1032 (match_operand:SI 2 "" "mX")] UNSPEC_PIC_CALL_SYM))]
1033 "flag_pic && TARGET_LINUX_ABI"
1034 "ldw\\t%0, %%call(%2)(%1)")
1038 (define_insn "add_tls_gd"
1039 [(set (match_operand:SI 0 "register_operand" "=r")
1040 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1041 (match_operand:SI 2 "" "mX")] UNSPEC_ADD_TLS_GD))]
1043 "addi\t%0, %1, %%tls_gd(%2)")
1045 (define_insn "load_tls_ie"
1046 [(set (match_operand:SI 0 "register_operand" "=r")
1047 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1048 (match_operand:SI 2 "" "mX")] UNSPEC_LOAD_TLS_IE))]
1050 "ldw\t%0, %%tls_ie(%2)(%1)")
1052 (define_insn "add_tls_ldm"
1053 [(set (match_operand:SI 0 "register_operand" "=r")
1054 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1055 (match_operand:SI 2 "" "mX")] UNSPEC_ADD_TLS_LDM))]
1057 "addi\t%0, %1, %%tls_ldm(%2)")
1059 (define_insn "add_tls_ldo"
1060 [(set (match_operand:SI 0 "register_operand" "=r")
1061 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1062 (match_operand:SI 2 "" "mX")] UNSPEC_ADD_TLS_LDO))]
1064 "addi\t%0, %1, %%tls_ldo(%2)")
1066 (define_insn "add_tls_le"
1067 [(set (match_operand:SI 0 "register_operand" "=r")
1068 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1069 (match_operand:SI 2 "" "mX")] UNSPEC_ADD_TLS_LE))]
1071 "addi\t%0, %1, %%tls_le(%2)")