163d1a8abSmrg;; Machine Description for Altera Nios II. 2*ec02198aSmrg;; Copyright (C) 2012-2020 Free Software Foundation, Inc. 363d1a8abSmrg;; Contributed by Jonah Graham (jgraham@altera.com) and 463d1a8abSmrg;; Will Reece (wreece@altera.com). 563d1a8abSmrg;; Contributed by Mentor Graphics, Inc. 663d1a8abSmrg;; 763d1a8abSmrg;; This file is part of GCC. 863d1a8abSmrg;; 963d1a8abSmrg;; GCC is free software; you can redistribute it and/or modify 1063d1a8abSmrg;; it under the terms of the GNU General Public License as published by 1163d1a8abSmrg;; the Free Software Foundation; either version 3, or (at your option) 1263d1a8abSmrg;; any later version. 1363d1a8abSmrg;; 1463d1a8abSmrg;; GCC is distributed in the hope that it will be useful, 1563d1a8abSmrg;; but WITHOUT ANY WARRANTY; without even the implied warranty of 1663d1a8abSmrg;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1763d1a8abSmrg;; GNU General Public License for more details. 1863d1a8abSmrg;; 1963d1a8abSmrg;; You should have received a copy of the GNU General Public License 2063d1a8abSmrg;; along with GCC; see the file COPYING3. If not see 2163d1a8abSmrg;; <http://www.gnu.org/licenses/>. 2263d1a8abSmrg 2363d1a8abSmrg;; Register numbers 2463d1a8abSmrg(define_constants 2563d1a8abSmrg [ 2663d1a8abSmrg (FIRST_RETVAL_REGNO 2) ; Return value registers 2763d1a8abSmrg (LAST_RETVAL_REGNO 3) ; 2863d1a8abSmrg (FIRST_ARG_REGNO 4) ; Argument registers 2963d1a8abSmrg (LAST_ARG_REGNO 7) ; 3063d1a8abSmrg 3163d1a8abSmrg (TP_REGNO 23) ; Thread pointer register 3263d1a8abSmrg (GP_REGNO 26) ; Global pointer register 3363d1a8abSmrg (SP_REGNO 27) ; Stack pointer register 3463d1a8abSmrg (FP_REGNO 28) ; Frame pointer register 3563d1a8abSmrg (EA_REGNO 29) ; Exception return address register 3663d1a8abSmrg (RA_REGNO 31) ; Return address register 3763d1a8abSmrg (LAST_GP_REG 31) ; Last general purpose register 3863d1a8abSmrg 3963d1a8abSmrg ;; Target register definitions 4063d1a8abSmrg (STATIC_CHAIN_REGNUM 12) 4163d1a8abSmrg (STACK_POINTER_REGNUM 27) 4263d1a8abSmrg (HARD_FRAME_POINTER_REGNUM 28) 4363d1a8abSmrg (PC_REGNUM 37) 4463d1a8abSmrg (FRAME_POINTER_REGNUM 38) 4563d1a8abSmrg (ARG_POINTER_REGNUM 39) 4663d1a8abSmrg (FIRST_PSEUDO_REGISTER 40) 4763d1a8abSmrg ] 4863d1a8abSmrg) 4963d1a8abSmrg 5063d1a8abSmrg;; Enumeration of UNSPECs 5163d1a8abSmrg 5263d1a8abSmrg(define_c_enum "unspecv" [ 5363d1a8abSmrg UNSPECV_BLOCKAGE 5463d1a8abSmrg UNSPECV_WRCTL 5563d1a8abSmrg UNSPECV_RDCTL 5663d1a8abSmrg UNSPECV_FWRX 5763d1a8abSmrg UNSPECV_FWRY 5863d1a8abSmrg UNSPECV_FRDXLO 5963d1a8abSmrg UNSPECV_FRDXHI 6063d1a8abSmrg UNSPECV_FRDY 6163d1a8abSmrg UNSPECV_CUSTOM_NXX 6263d1a8abSmrg UNSPECV_CUSTOM_XNXX 6363d1a8abSmrg UNSPECV_LDXIO 6463d1a8abSmrg UNSPECV_STXIO 6563d1a8abSmrg UNSPECV_RDPRS 6663d1a8abSmrg UNSPECV_FLUSHD 6763d1a8abSmrg UNSPECV_FLUSHDA 6863d1a8abSmrg UNSPECV_WRPIE 6963d1a8abSmrg UNSPECV_ENI 7063d1a8abSmrg UNSPECV_LDEX 7163d1a8abSmrg UNSPECV_LDSEX 7263d1a8abSmrg UNSPECV_STEX 7363d1a8abSmrg UNSPECV_STSEX 7463d1a8abSmrg]) 7563d1a8abSmrg 7663d1a8abSmrg(define_c_enum "unspec" [ 7763d1a8abSmrg UNSPEC_FCOS 7863d1a8abSmrg UNSPEC_FSIN 7963d1a8abSmrg UNSPEC_FTAN 8063d1a8abSmrg UNSPEC_FATAN 8163d1a8abSmrg UNSPEC_FEXP 8263d1a8abSmrg UNSPEC_FLOG 8363d1a8abSmrg UNSPEC_ROUND 8463d1a8abSmrg UNSPEC_LOAD_GOT_REGISTER 8563d1a8abSmrg UNSPEC_PIC_SYM 8663d1a8abSmrg UNSPEC_PIC_CALL_SYM 8763d1a8abSmrg UNSPEC_PIC_GOTOFF_SYM 8863d1a8abSmrg UNSPEC_LOAD_TLS_IE 8963d1a8abSmrg UNSPEC_ADD_TLS_LE 9063d1a8abSmrg UNSPEC_ADD_TLS_GD 9163d1a8abSmrg UNSPEC_ADD_TLS_LDM 9263d1a8abSmrg UNSPEC_ADD_TLS_LDO 9363d1a8abSmrg UNSPEC_EH_RETURN 9463d1a8abSmrg UNSPEC_SYNC 9563d1a8abSmrg]) 9663d1a8abSmrg 9763d1a8abSmrg 9863d1a8abSmrg;; Instruction scheduler 9963d1a8abSmrg 10063d1a8abSmrg; No schedule info is currently available, using an assumption that no 10163d1a8abSmrg; instruction can use the results of the previous instruction without 10263d1a8abSmrg; incuring a stall. 10363d1a8abSmrg 10463d1a8abSmrg; length of an instruction (in bytes) 10563d1a8abSmrg(define_attr "length" "" 10663d1a8abSmrg (if_then_else (match_test "nios2_cdx_narrow_form_p (insn)") 10763d1a8abSmrg (const_int 2) 10863d1a8abSmrg (const_int 4))) 10963d1a8abSmrg 11063d1a8abSmrg(define_attr "type" 11163d1a8abSmrg "unknown,complex,control,alu,cond_alu,st,ld,stwm,ldwm,push,pop,mul,div,\ 11263d1a8abSmrg custom,add,sub,mov,and,or,xor,neg,not,sll,srl,sra,rol,ror,nop" 11363d1a8abSmrg (const_string "complex")) 11463d1a8abSmrg 11563d1a8abSmrg(define_asm_attributes 11663d1a8abSmrg [(set_attr "length" "4") 11763d1a8abSmrg (set_attr "type" "complex")]) 11863d1a8abSmrg 11963d1a8abSmrg(define_automaton "nios2") 12063d1a8abSmrg(automata_option "v") 12163d1a8abSmrg;(automata_option "no-minimization") 12263d1a8abSmrg(automata_option "ndfa") 12363d1a8abSmrg 12463d1a8abSmrg; The nios2 pipeline is fairly straightforward for the fast model. 12563d1a8abSmrg; Every alu operation is pipelined so that an instruction can 12663d1a8abSmrg; be issued every cycle. However, there are still potential 12763d1a8abSmrg; stalls which this description tries to deal with. 12863d1a8abSmrg 12963d1a8abSmrg(define_cpu_unit "cpu" "nios2") 13063d1a8abSmrg 13163d1a8abSmrg(define_insn_reservation "complex" 1 13263d1a8abSmrg (eq_attr "type" "complex") 13363d1a8abSmrg "cpu") 13463d1a8abSmrg 13563d1a8abSmrg(define_insn_reservation "control" 1 13663d1a8abSmrg (eq_attr "type" "control,pop") 13763d1a8abSmrg "cpu") 13863d1a8abSmrg 13963d1a8abSmrg(define_insn_reservation "alu" 1 14063d1a8abSmrg (eq_attr "type" "alu,add,sub,mov,and,or,xor,neg,not") 14163d1a8abSmrg "cpu") 14263d1a8abSmrg 14363d1a8abSmrg(define_insn_reservation "cond_alu" 1 14463d1a8abSmrg (eq_attr "type" "cond_alu") 14563d1a8abSmrg "cpu") 14663d1a8abSmrg 14763d1a8abSmrg(define_insn_reservation "st" 1 14863d1a8abSmrg (eq_attr "type" "st,stwm,push") 14963d1a8abSmrg "cpu") 15063d1a8abSmrg 15163d1a8abSmrg(define_insn_reservation "custom" 1 15263d1a8abSmrg (eq_attr "type" "custom") 15363d1a8abSmrg "cpu") 15463d1a8abSmrg 15563d1a8abSmrg; shifts, muls and lds have three cycle latency 15663d1a8abSmrg(define_insn_reservation "ld" 3 15763d1a8abSmrg (eq_attr "type" "ld,ldwm") 15863d1a8abSmrg "cpu") 15963d1a8abSmrg 16063d1a8abSmrg(define_insn_reservation "shift" 3 16163d1a8abSmrg (eq_attr "type" "sll,srl,sra,rol,ror") 16263d1a8abSmrg "cpu") 16363d1a8abSmrg 16463d1a8abSmrg(define_insn_reservation "mul" 3 16563d1a8abSmrg (eq_attr "type" "mul") 16663d1a8abSmrg "cpu") 16763d1a8abSmrg 16863d1a8abSmrg(define_insn_reservation "div" 1 16963d1a8abSmrg (eq_attr "type" "div") 17063d1a8abSmrg "cpu") 17163d1a8abSmrg 17263d1a8abSmrg(include "predicates.md") 17363d1a8abSmrg(include "constraints.md") 17463d1a8abSmrg 17563d1a8abSmrg 17663d1a8abSmrg;; Move instructions 17763d1a8abSmrg 17863d1a8abSmrg(define_mode_iterator M [QI HI SI]) 17963d1a8abSmrg 18063d1a8abSmrg(define_expand "mov<mode>" 18163d1a8abSmrg [(set (match_operand:M 0 "nonimmediate_operand" "") 18263d1a8abSmrg (match_operand:M 1 "general_operand" ""))] 18363d1a8abSmrg "" 18463d1a8abSmrg{ 18563d1a8abSmrg if (nios2_emit_move_sequence (operands, <MODE>mode)) 18663d1a8abSmrg DONE; 18763d1a8abSmrg}) 18863d1a8abSmrg 18963d1a8abSmrg(define_insn "*high" 19063d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 19163d1a8abSmrg (high:SI (match_operand:SI 1 "immediate_operand" "i")))] 19263d1a8abSmrg "" 19363d1a8abSmrg "movhi\\t%0, %H1" 19463d1a8abSmrg [(set_attr "type" "alu")]) 19563d1a8abSmrg 19663d1a8abSmrg(define_insn "*lo_sum" 19763d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 19863d1a8abSmrg (lo_sum:SI (match_operand:SI 1 "register_operand" "r") 19963d1a8abSmrg (match_operand:SI 2 "immediate_operand" "i")))] 20063d1a8abSmrg "" 20163d1a8abSmrg "addi\\t%0, %1, %L2" 20263d1a8abSmrg [(set_attr "type" "alu")]) 20363d1a8abSmrg 204c7a68eb7Smrg(define_insn_and_split "movqi_internal" 20563d1a8abSmrg [(set (match_operand:QI 0 "nonimmediate_operand" "=m, r,r") 20663d1a8abSmrg (match_operand:QI 1 "general_operand" "rM,m,rI"))] 20763d1a8abSmrg "(register_operand (operands[0], QImode) 20863d1a8abSmrg || reg_or_0_operand (operands[1], QImode))" 20963d1a8abSmrg { 21063d1a8abSmrg switch (which_alternative) 21163d1a8abSmrg { 21263d1a8abSmrg case 0: 21363d1a8abSmrg if (get_attr_length (insn) != 2) 21463d1a8abSmrg return "stb%o0\\t%z1, %0"; 21563d1a8abSmrg else if (const_0_operand (operands[1], QImode)) 21663d1a8abSmrg return "stbz.n\\t%z1, %0"; 21763d1a8abSmrg else 21863d1a8abSmrg return "stb.n\\t%z1, %0"; 21963d1a8abSmrg case 1: 22063d1a8abSmrg return "ldbu%o1%.\\t%0, %1"; 22163d1a8abSmrg case 2: 22263d1a8abSmrg return "mov%i1%.\\t%0, %z1"; 22363d1a8abSmrg default: 22463d1a8abSmrg gcc_unreachable (); 22563d1a8abSmrg } 22663d1a8abSmrg } 227c7a68eb7Smrg "(nios2_large_constant_memory_operand_p (operands[0]) 228c7a68eb7Smrg || nios2_large_constant_memory_operand_p (operands[1]))" 229c7a68eb7Smrg [(set (match_dup 0) (match_dup 1))] 230c7a68eb7Smrg { 231c7a68eb7Smrg if (nios2_large_constant_memory_operand_p (operands[0])) 232c7a68eb7Smrg operands[0] = nios2_split_large_constant_memory_operand (operands[0]); 233c7a68eb7Smrg else 234c7a68eb7Smrg operands[1] = nios2_split_large_constant_memory_operand (operands[1]); 235c7a68eb7Smrg } 23663d1a8abSmrg [(set_attr "type" "st,ld,mov")]) 23763d1a8abSmrg 238c7a68eb7Smrg(define_insn_and_split "movhi_internal" 23963d1a8abSmrg [(set (match_operand:HI 0 "nonimmediate_operand" "=m, r,r") 24063d1a8abSmrg (match_operand:HI 1 "general_operand" "rM,m,rI"))] 24163d1a8abSmrg "(register_operand (operands[0], HImode) 24263d1a8abSmrg || reg_or_0_operand (operands[1], HImode))" 243c7a68eb7Smrg { 244c7a68eb7Smrg switch (which_alternative) 245c7a68eb7Smrg { 246c7a68eb7Smrg case 0: 247c7a68eb7Smrg return "sth%o0%.\\t%z1, %0"; 248c7a68eb7Smrg case 1: 249c7a68eb7Smrg return "ldhu%o1%.\\t%0, %1"; 250c7a68eb7Smrg case 2: 251c7a68eb7Smrg return "mov%i1%.\\t%0, %z1"; 252c7a68eb7Smrg default: 253c7a68eb7Smrg gcc_unreachable (); 254c7a68eb7Smrg } 255c7a68eb7Smrg } 256c7a68eb7Smrg "(nios2_large_constant_memory_operand_p (operands[0]) 257c7a68eb7Smrg || nios2_large_constant_memory_operand_p (operands[1]))" 258c7a68eb7Smrg [(set (match_dup 0) (match_dup 1))] 259c7a68eb7Smrg { 260c7a68eb7Smrg if (nios2_large_constant_memory_operand_p (operands[0])) 261c7a68eb7Smrg operands[0] = nios2_split_large_constant_memory_operand (operands[0]); 262c7a68eb7Smrg else 263c7a68eb7Smrg operands[1] = nios2_split_large_constant_memory_operand (operands[1]); 264c7a68eb7Smrg } 26563d1a8abSmrg [(set_attr "type" "st,ld,mov")]) 26663d1a8abSmrg 267c7a68eb7Smrg(define_insn_and_split "movsi_internal" 26863d1a8abSmrg [(set (match_operand:SI 0 "nonimmediate_operand" "=m, r,r, r") 26963d1a8abSmrg (match_operand:SI 1 "general_operand" "rM,m,rIJK,S"))] 27063d1a8abSmrg "(register_operand (operands[0], SImode) 27163d1a8abSmrg || reg_or_0_operand (operands[1], SImode))" 27263d1a8abSmrg { 27363d1a8abSmrg switch (which_alternative) 27463d1a8abSmrg { 27563d1a8abSmrg case 0: 27663d1a8abSmrg if (get_attr_length (insn) != 2) 27763d1a8abSmrg return "stw%o0\\t%z1, %0"; 27863d1a8abSmrg else if (stack_memory_operand (operands[0], SImode)) 27963d1a8abSmrg return "stwsp.n\\t%z1, %0"; 28063d1a8abSmrg else if (const_0_operand (operands[1], SImode)) 28163d1a8abSmrg return "stwz.n\\t%z1, %0"; 28263d1a8abSmrg else 28363d1a8abSmrg return "stw.n\\t%z1, %0"; 28463d1a8abSmrg case 1: 28563d1a8abSmrg if (get_attr_length (insn) != 2) 28663d1a8abSmrg return "ldw%o1\\t%0, %1"; 28763d1a8abSmrg else if (stack_memory_operand (operands[1], SImode)) 28863d1a8abSmrg return "ldwsp.n\\t%0, %1"; 28963d1a8abSmrg else 29063d1a8abSmrg return "ldw.n\\t%0, %1"; 29163d1a8abSmrg case 2: 29263d1a8abSmrg return "mov%i1%.\\t%0, %z1"; 29363d1a8abSmrg case 3: 29463d1a8abSmrg return "addi\\t%0, gp, %%gprel(%1)"; 29563d1a8abSmrg default: 29663d1a8abSmrg gcc_unreachable (); 29763d1a8abSmrg } 29863d1a8abSmrg } 299c7a68eb7Smrg "(nios2_large_constant_memory_operand_p (operands[0]) 300c7a68eb7Smrg || nios2_large_constant_memory_operand_p (operands[1]) 301c7a68eb7Smrg || (nios2_large_constant_p (operands[1]) 302c7a68eb7Smrg && !(CONST_INT_P (operands[1]) 303c7a68eb7Smrg && (SMALL_INT_UNSIGNED (INTVAL (operands[1])) 304c7a68eb7Smrg || UPPER16_INT (INTVAL (operands[1]))))))" 305c7a68eb7Smrg [(set (match_dup 0) (match_dup 1))] 306c7a68eb7Smrg { 307c7a68eb7Smrg if (nios2_large_constant_memory_operand_p (operands[0])) 308c7a68eb7Smrg operands[0] = nios2_split_large_constant_memory_operand (operands[0]); 309c7a68eb7Smrg else if (nios2_large_constant_memory_operand_p (operands[1])) 310c7a68eb7Smrg operands[1] = nios2_split_large_constant_memory_operand (operands[1]); 311c7a68eb7Smrg else 312c7a68eb7Smrg operands[1] = nios2_split_large_constant (operands[1], operands[0]); 313c7a68eb7Smrg } 31463d1a8abSmrg [(set_attr "type" "st,ld,mov,alu")]) 31563d1a8abSmrg 31663d1a8abSmrg(define_mode_iterator BH [QI HI]) 31763d1a8abSmrg(define_mode_iterator BHW [QI HI SI]) 31863d1a8abSmrg(define_mode_attr bh [(QI "b") (HI "h")]) 31963d1a8abSmrg(define_mode_attr bhw [(QI "b") (HI "h") (SI "w")]) 32063d1a8abSmrg(define_mode_attr bhw_uns [(QI "bu") (HI "hu") (SI "w")]) 32163d1a8abSmrg 322c7a68eb7Smrg(define_insn_and_split "ld<bhw_uns>io" 32363d1a8abSmrg [(set (match_operand:BHW 0 "register_operand" "=r") 32463d1a8abSmrg (unspec_volatile:BHW 32563d1a8abSmrg [(match_operand:BHW 1 "ldstio_memory_operand" "w")] UNSPECV_LDXIO))] 32663d1a8abSmrg "" 32763d1a8abSmrg "ld<bhw_uns>io\\t%0, %1" 328c7a68eb7Smrg "nios2_large_constant_memory_operand_p (operands[1])" 329c7a68eb7Smrg [(set (match_dup 0) 330c7a68eb7Smrg (unspec_volatile:BHW [(match_dup 1)] UNSPECV_LDXIO))] 331c7a68eb7Smrg { 332c7a68eb7Smrg operands[1] = nios2_split_large_constant_memory_operand (operands[1]); 333c7a68eb7Smrg } 33463d1a8abSmrg [(set_attr "type" "ld")]) 33563d1a8abSmrg 33663d1a8abSmrg(define_expand "ld<bh>io" 33763d1a8abSmrg [(set (match_operand:BH 0 "register_operand" "=r") 33863d1a8abSmrg (match_operand:BH 1 "ldstio_memory_operand" "w"))] 33963d1a8abSmrg "" 34063d1a8abSmrg{ 34163d1a8abSmrg rtx tmp = gen_reg_rtx (SImode); 34263d1a8abSmrg emit_insn (gen_ld<bh>io_signed (tmp, operands[1])); 34363d1a8abSmrg emit_insn (gen_mov<mode> (operands[0], gen_lowpart (<MODE>mode, tmp))); 34463d1a8abSmrg DONE; 34563d1a8abSmrg}) 34663d1a8abSmrg 347c7a68eb7Smrg(define_insn_and_split "ld<bh>io_signed" 34863d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 34963d1a8abSmrg (sign_extend:SI 35063d1a8abSmrg (unspec_volatile:BH 35163d1a8abSmrg [(match_operand:BH 1 "ldstio_memory_operand" "w")] UNSPECV_LDXIO)))] 35263d1a8abSmrg "" 35363d1a8abSmrg "ld<bh>io\\t%0, %1" 354c7a68eb7Smrg "nios2_large_constant_memory_operand_p (operands[1])" 355c7a68eb7Smrg [(set (match_dup 0) 356c7a68eb7Smrg (sign_extend:SI (unspec_volatile:BH [(match_dup 1)] UNSPECV_LDXIO)))] 357c7a68eb7Smrg { 358c7a68eb7Smrg operands[1] = nios2_split_large_constant_memory_operand (operands[1]); 359c7a68eb7Smrg } 36063d1a8abSmrg [(set_attr "type" "ld")]) 36163d1a8abSmrg 362c7a68eb7Smrg(define_insn_and_split "st<bhw>io" 36363d1a8abSmrg [(set (match_operand:BHW 0 "ldstio_memory_operand" "=w") 36463d1a8abSmrg (unspec_volatile:BHW 36563d1a8abSmrg [(match_operand:BHW 1 "reg_or_0_operand" "rM")] UNSPECV_STXIO))] 36663d1a8abSmrg "" 36763d1a8abSmrg "st<bhw>io\\t%z1, %0" 368c7a68eb7Smrg "nios2_large_constant_memory_operand_p (operands[0])" 369c7a68eb7Smrg [(set (match_dup 0) (unspec_volatile:BHW [(match_dup 1)] UNSPECV_STXIO))] 370c7a68eb7Smrg { 371c7a68eb7Smrg operands[0] = nios2_split_large_constant_memory_operand (operands[0]); 372c7a68eb7Smrg } 37363d1a8abSmrg [(set_attr "type" "st")]) 37463d1a8abSmrg 37563d1a8abSmrg 37663d1a8abSmrg;; QI to [HI, SI] extension patterns are collected together 37763d1a8abSmrg(define_mode_iterator QX [HI SI]) 37863d1a8abSmrg 37963d1a8abSmrg;; Zero extension patterns 380c7a68eb7Smrg(define_insn_and_split "zero_extendhisi2" 38163d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r,r") 38263d1a8abSmrg (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))] 38363d1a8abSmrg "" 38463d1a8abSmrg "@ 38563d1a8abSmrg andi%.\\t%0, %1, 0xffff 38663d1a8abSmrg ldhu%o1%.\\t%0, %1" 387c7a68eb7Smrg "nios2_large_constant_memory_operand_p (operands[1])" 388c7a68eb7Smrg [(set (match_dup 0) (zero_extend:SI (match_dup 1)))] 389c7a68eb7Smrg { 390c7a68eb7Smrg operands[1] = nios2_split_large_constant_memory_operand (operands[1]); 391c7a68eb7Smrg } 39263d1a8abSmrg [(set_attr "type" "and,ld")]) 39363d1a8abSmrg 394c7a68eb7Smrg(define_insn_and_split "zero_extendqi<mode>2" 39563d1a8abSmrg [(set (match_operand:QX 0 "register_operand" "=r,r") 39663d1a8abSmrg (zero_extend:QX (match_operand:QI 1 "nonimmediate_operand" "r,m")))] 39763d1a8abSmrg "" 39863d1a8abSmrg "@ 39963d1a8abSmrg andi%.\\t%0, %1, 0xff 40063d1a8abSmrg ldbu%o1%.\\t%0, %1" 401c7a68eb7Smrg "nios2_large_constant_memory_operand_p (operands[1])" 402c7a68eb7Smrg [(set (match_dup 0) (zero_extend:QX (match_dup 1)))] 403c7a68eb7Smrg { 404c7a68eb7Smrg operands[1] = nios2_split_large_constant_memory_operand (operands[1]); 405c7a68eb7Smrg } 40663d1a8abSmrg [(set_attr "type" "and,ld")]) 40763d1a8abSmrg 40863d1a8abSmrg;; Sign extension patterns 40963d1a8abSmrg 410c7a68eb7Smrg(define_insn_and_split "extendhisi2" 41163d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r,r") 41263d1a8abSmrg (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))] 41363d1a8abSmrg "" 41463d1a8abSmrg "@ 41563d1a8abSmrg # 41663d1a8abSmrg ldh%o1%.\\t%0, %1" 417c7a68eb7Smrg "nios2_large_constant_memory_operand_p (operands[1])" 418c7a68eb7Smrg [(set (match_dup 0) (sign_extend:SI (match_dup 1)))] 419c7a68eb7Smrg { 420c7a68eb7Smrg operands[1] = nios2_split_large_constant_memory_operand (operands[1]); 421c7a68eb7Smrg } 42263d1a8abSmrg [(set_attr "type" "alu,ld")]) 42363d1a8abSmrg 424c7a68eb7Smrg(define_insn_and_split "extendqi<mode>2" 42563d1a8abSmrg [(set (match_operand:QX 0 "register_operand" "=r,r") 42663d1a8abSmrg (sign_extend:QX (match_operand:QI 1 "nonimmediate_operand" "r,m")))] 42763d1a8abSmrg "" 42863d1a8abSmrg "@ 42963d1a8abSmrg # 43063d1a8abSmrg ldb%o1%.\\t%0, %1" 431c7a68eb7Smrg "nios2_large_constant_memory_operand_p (operands[1])" 432c7a68eb7Smrg [(set (match_dup 0) (sign_extend:QX (match_dup 1)))] 433c7a68eb7Smrg { 434c7a68eb7Smrg operands[1] = nios2_split_large_constant_memory_operand (operands[1]); 435c7a68eb7Smrg } 43663d1a8abSmrg [(set_attr "type" "alu,ld")]) 43763d1a8abSmrg 43863d1a8abSmrg;; Split patterns for register alternative cases. 43963d1a8abSmrg(define_split 44063d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "") 44163d1a8abSmrg (sign_extend:SI (match_operand:HI 1 "register_operand" "")))] 44263d1a8abSmrg "reload_completed" 44363d1a8abSmrg [(set (match_dup 0) 44463d1a8abSmrg (and:SI (match_dup 1) (const_int 65535))) 44563d1a8abSmrg (set (match_dup 0) 44663d1a8abSmrg (xor:SI (match_dup 0) (const_int 32768))) 44763d1a8abSmrg (set (match_dup 0) 44863d1a8abSmrg (plus:SI (match_dup 0) (const_int -32768)))] 44963d1a8abSmrg "operands[1] = gen_lowpart (SImode, operands[1]);") 45063d1a8abSmrg 45163d1a8abSmrg(define_split 45263d1a8abSmrg [(set (match_operand:QX 0 "register_operand" "") 45363d1a8abSmrg (sign_extend:QX (match_operand:QI 1 "register_operand" "")))] 45463d1a8abSmrg "reload_completed" 45563d1a8abSmrg [(set (match_dup 0) 45663d1a8abSmrg (and:SI (match_dup 1) (const_int 255))) 45763d1a8abSmrg (set (match_dup 0) 45863d1a8abSmrg (xor:SI (match_dup 0) (const_int 128))) 45963d1a8abSmrg (set (match_dup 0) 46063d1a8abSmrg (plus:SI (match_dup 0) (const_int -128)))] 46163d1a8abSmrg "operands[0] = gen_lowpart (SImode, operands[0]); 46263d1a8abSmrg operands[1] = gen_lowpart (SImode, operands[1]);") 46363d1a8abSmrg 46463d1a8abSmrg 46563d1a8abSmrg;; Arithmetic Operations 46663d1a8abSmrg 46763d1a8abSmrg(define_insn "addsi3" 46863d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 46963d1a8abSmrg (plus:SI (match_operand:SI 1 "register_operand" "%r") 47063d1a8abSmrg (match_operand:SI 2 "add_regimm_operand" "rIT")))] 47163d1a8abSmrg "" 47263d1a8abSmrg{ 47363d1a8abSmrg return nios2_add_insn_asm (insn, operands); 47463d1a8abSmrg} 47563d1a8abSmrg [(set_attr "type" "add")]) 47663d1a8abSmrg 47763d1a8abSmrg(define_insn "subsi3" 47863d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 47963d1a8abSmrg (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rM") 48063d1a8abSmrg (match_operand:SI 2 "register_operand" "r")))] 48163d1a8abSmrg "" 48263d1a8abSmrg "sub%.\\t%0, %z1, %2" 48363d1a8abSmrg [(set_attr "type" "sub")]) 48463d1a8abSmrg 48563d1a8abSmrg(define_insn "mulsi3" 48663d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 48763d1a8abSmrg (mult:SI (match_operand:SI 1 "register_operand" "%r") 48863d1a8abSmrg (match_operand:SI 2 "arith_operand" "rI")))] 48963d1a8abSmrg "TARGET_HAS_MUL" 49063d1a8abSmrg "mul%i2\\t%0, %1, %z2" 49163d1a8abSmrg [(set_attr "type" "mul")]) 49263d1a8abSmrg 49363d1a8abSmrg(define_expand "divsi3" 49463d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 49563d1a8abSmrg (div:SI (match_operand:SI 1 "register_operand" "r") 49663d1a8abSmrg (match_operand:SI 2 "register_operand" "r")))] 49763d1a8abSmrg "" 49863d1a8abSmrg{ 49963d1a8abSmrg if (!TARGET_HAS_DIV) 50063d1a8abSmrg { 50163d1a8abSmrg if (TARGET_FAST_SW_DIV) 50263d1a8abSmrg { 50363d1a8abSmrg nios2_emit_expensive_div (operands, SImode); 50463d1a8abSmrg DONE; 50563d1a8abSmrg } 50663d1a8abSmrg else 50763d1a8abSmrg FAIL; 50863d1a8abSmrg } 50963d1a8abSmrg}) 51063d1a8abSmrg 51163d1a8abSmrg(define_insn "divsi3_insn" 51263d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 51363d1a8abSmrg (div:SI (match_operand:SI 1 "register_operand" "r") 51463d1a8abSmrg (match_operand:SI 2 "register_operand" "r")))] 51563d1a8abSmrg "TARGET_HAS_DIV" 51663d1a8abSmrg "div\\t%0, %1, %2" 51763d1a8abSmrg [(set_attr "type" "div")]) 51863d1a8abSmrg 51963d1a8abSmrg(define_insn "udivsi3" 52063d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 52163d1a8abSmrg (udiv:SI (match_operand:SI 1 "register_operand" "r") 52263d1a8abSmrg (match_operand:SI 2 "register_operand" "r")))] 52363d1a8abSmrg "TARGET_HAS_DIV" 52463d1a8abSmrg "divu\\t%0, %1, %2" 52563d1a8abSmrg [(set_attr "type" "div")]) 52663d1a8abSmrg 52763d1a8abSmrg(define_code_iterator EXTEND [sign_extend zero_extend]) 52863d1a8abSmrg(define_code_attr us [(sign_extend "s") (zero_extend "u")]) 52963d1a8abSmrg(define_code_attr mul [(sign_extend "mul") (zero_extend "umul")]) 53063d1a8abSmrg 53163d1a8abSmrg(define_insn "<us>mulsi3_highpart" 53263d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 53363d1a8abSmrg (truncate:SI 53463d1a8abSmrg (lshiftrt:DI 53563d1a8abSmrg (mult:DI (EXTEND:DI (match_operand:SI 1 "register_operand" "r")) 53663d1a8abSmrg (EXTEND:DI (match_operand:SI 2 "register_operand" "r"))) 53763d1a8abSmrg (const_int 32))))] 53863d1a8abSmrg "TARGET_HAS_MULX" 53963d1a8abSmrg "mulx<us><us>\\t%0, %1, %2" 54063d1a8abSmrg [(set_attr "type" "mul")]) 54163d1a8abSmrg 54263d1a8abSmrg(define_expand "<mul>sidi3" 54363d1a8abSmrg [(set (match_operand:DI 0 "register_operand" "") 54463d1a8abSmrg (mult:DI (EXTEND:DI (match_operand:SI 1 "register_operand" "")) 54563d1a8abSmrg (EXTEND:DI (match_operand:SI 2 "register_operand" ""))))] 54663d1a8abSmrg "TARGET_HAS_MULX" 54763d1a8abSmrg{ 54863d1a8abSmrg rtx hi = gen_reg_rtx (SImode); 54963d1a8abSmrg rtx lo = gen_reg_rtx (SImode); 55063d1a8abSmrg 55163d1a8abSmrg emit_insn (gen_<us>mulsi3_highpart (hi, operands[1], operands[2])); 55263d1a8abSmrg emit_insn (gen_mulsi3 (lo, operands[1], operands[2])); 55363d1a8abSmrg emit_move_insn (gen_lowpart (SImode, operands[0]), lo); 55463d1a8abSmrg emit_move_insn (gen_highpart (SImode, operands[0]), hi); 55563d1a8abSmrg DONE; 55663d1a8abSmrg}) 55763d1a8abSmrg 55863d1a8abSmrg 55963d1a8abSmrg;; Negate and ones complement 56063d1a8abSmrg 56163d1a8abSmrg(define_insn "negsi2" 56263d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 56363d1a8abSmrg (neg:SI (match_operand:SI 1 "register_operand" "r")))] 56463d1a8abSmrg "" 56563d1a8abSmrg{ 56663d1a8abSmrg if (get_attr_length (insn) == 2) 56763d1a8abSmrg return "neg.n\\t%0, %1"; 56863d1a8abSmrg else 56963d1a8abSmrg return "sub\\t%0, zero, %1"; 57063d1a8abSmrg} 57163d1a8abSmrg [(set_attr "type" "neg")]) 57263d1a8abSmrg 57363d1a8abSmrg(define_insn "one_cmplsi2" 57463d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 57563d1a8abSmrg (not:SI (match_operand:SI 1 "register_operand" "r")))] 57663d1a8abSmrg "" 57763d1a8abSmrg{ 57863d1a8abSmrg if (get_attr_length (insn) == 2) 57963d1a8abSmrg return "not.n\\t%0, %1"; 58063d1a8abSmrg else 58163d1a8abSmrg return "nor\\t%0, zero, %1"; 58263d1a8abSmrg} 58363d1a8abSmrg [(set_attr "type" "not")]) 58463d1a8abSmrg 58563d1a8abSmrg 58663d1a8abSmrg;; Integer logical Operations 58763d1a8abSmrg 58863d1a8abSmrg(define_insn "andsi3" 58963d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 59063d1a8abSmrg (and:SI (match_operand:SI 1 "register_operand" "%r") 59163d1a8abSmrg (match_operand:SI 2 "and_operand" "rJKP")))] 59263d1a8abSmrg "" 59363d1a8abSmrg "and%x2%.\\t%0, %1, %y2" 59463d1a8abSmrg [(set_attr "type" "and")]) 59563d1a8abSmrg 59663d1a8abSmrg(define_code_iterator LOGICAL [ior xor]) 59763d1a8abSmrg(define_code_attr logical_asm [(ior "or") (xor "xor")]) 59863d1a8abSmrg 59963d1a8abSmrg(define_insn "<code>si3" 60063d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 60163d1a8abSmrg (LOGICAL:SI (match_operand:SI 1 "register_operand" "%r") 60263d1a8abSmrg (match_operand:SI 2 "logical_operand" "rJK")))] 60363d1a8abSmrg "" 60463d1a8abSmrg "<logical_asm>%x2%.\\t%0, %1, %y2" 60563d1a8abSmrg [(set_attr "type" "<logical_asm>")]) 60663d1a8abSmrg 60763d1a8abSmrg(define_insn "*norsi3" 60863d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 60963d1a8abSmrg (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r")) 61063d1a8abSmrg (not:SI (match_operand:SI 2 "register_operand" "r"))))] 61163d1a8abSmrg "" 61263d1a8abSmrg "nor\\t%0, %1, %2" 61363d1a8abSmrg [(set_attr "type" "alu")]) 61463d1a8abSmrg 61563d1a8abSmrg 61663d1a8abSmrg;; Shift instructions 61763d1a8abSmrg 61863d1a8abSmrg(define_code_iterator SHIFT [ashift ashiftrt lshiftrt rotate]) 61963d1a8abSmrg(define_code_attr shift_op [(ashift "ashl") (ashiftrt "ashr") 62063d1a8abSmrg (lshiftrt "lshr") (rotate "rotl")]) 62163d1a8abSmrg(define_code_attr shift_asm [(ashift "sll") (ashiftrt "sra") 62263d1a8abSmrg (lshiftrt "srl") (rotate "rol")]) 62363d1a8abSmrg 62463d1a8abSmrg(define_insn "<shift_op>si3" 62563d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 62663d1a8abSmrg (SHIFT:SI (match_operand:SI 1 "register_operand" "r") 62763d1a8abSmrg (match_operand:SI 2 "shift_operand" "rL")))] 62863d1a8abSmrg "" 62963d1a8abSmrg "<shift_asm>%i2%.\\t%0, %1, %z2" 63063d1a8abSmrg [(set_attr "type" "<shift_asm>")]) 63163d1a8abSmrg 63263d1a8abSmrg(define_insn "rotrsi3" 63363d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 63463d1a8abSmrg (rotatert:SI (match_operand:SI 1 "register_operand" "r") 63563d1a8abSmrg (match_operand:SI 2 "register_operand" "r")))] 63663d1a8abSmrg "" 63763d1a8abSmrg "ror\\t%0, %1, %2" 63863d1a8abSmrg [(set_attr "type" "ror")]) 63963d1a8abSmrg 64063d1a8abSmrg;; Nios II R2 Bit Manipulation Extension (BMX), provides 64163d1a8abSmrg;; bit merge/insertion/extraction instructions. 64263d1a8abSmrg 64363d1a8abSmrg(define_insn "*merge" 64463d1a8abSmrg [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") 64563d1a8abSmrg (match_operand:SI 1 "const_shift_operand" "L") 64663d1a8abSmrg (match_operand:SI 2 "const_shift_operand" "L")) 64763d1a8abSmrg (zero_extract:SI (match_operand:SI 3 "register_operand" "r") 64863d1a8abSmrg (match_dup 1) (match_dup 2)))] 64963d1a8abSmrg "TARGET_HAS_BMX" 65063d1a8abSmrg{ 65163d1a8abSmrg operands[4] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[2]) - 1); 65263d1a8abSmrg return "merge\\t%0, %3, %4, %2"; 65363d1a8abSmrg} 65463d1a8abSmrg [(set_attr "type" "alu")]) 65563d1a8abSmrg 65663d1a8abSmrg(define_insn "extzv" 65763d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 65863d1a8abSmrg (zero_extract:SI (match_operand:SI 1 "register_operand" "r") 65963d1a8abSmrg (match_operand:SI 2 "const_shift_operand" "L") 66063d1a8abSmrg (match_operand:SI 3 "const_shift_operand" "L")))] 66163d1a8abSmrg "TARGET_HAS_BMX" 66263d1a8abSmrg{ 66363d1a8abSmrg operands[4] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]) - 1); 66463d1a8abSmrg return "extract\\t%0, %1, %4, %3"; 66563d1a8abSmrg} 66663d1a8abSmrg [(set_attr "type" "alu")]) 66763d1a8abSmrg 66863d1a8abSmrg(define_insn "insv" 66963d1a8abSmrg [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") 67063d1a8abSmrg (match_operand:SI 1 "const_shift_operand" "L") 67163d1a8abSmrg (match_operand:SI 2 "const_shift_operand" "L")) 67263d1a8abSmrg (match_operand:SI 3 "reg_or_0_operand" "rM"))] 67363d1a8abSmrg "TARGET_HAS_BMX" 67463d1a8abSmrg{ 67563d1a8abSmrg operands[4] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[2]) - 1); 67663d1a8abSmrg return "insert\\t%0, %z3, %4, %2"; 67763d1a8abSmrg} 67863d1a8abSmrg [(set_attr "type" "alu")]) 67963d1a8abSmrg 68063d1a8abSmrg 68163d1a8abSmrg 68263d1a8abSmrg;; Floating point instructions 68363d1a8abSmrg 68463d1a8abSmrg;; Mode iterator for single/double float 68563d1a8abSmrg(define_mode_iterator F [SF DF]) 68663d1a8abSmrg(define_mode_attr f [(SF "s") (DF "d")]) 68763d1a8abSmrg 68863d1a8abSmrg;; Basic arithmetic instructions 68963d1a8abSmrg(define_code_iterator FOP3 [plus minus mult div]) 69063d1a8abSmrg(define_code_attr fop3 [(plus "add") (minus "sub") (mult "mul") (div "div")]) 69163d1a8abSmrg 69263d1a8abSmrg(define_insn "<fop3><mode>3" 69363d1a8abSmrg [(set (match_operand:F 0 "register_operand" "=r") 69463d1a8abSmrg (FOP3:F (match_operand:F 1 "register_operand" "r") 69563d1a8abSmrg (match_operand:F 2 "register_operand" "r")))] 69663d1a8abSmrg "nios2_fpu_insn_enabled (n2fpu_f<fop3><f>)" 69763d1a8abSmrg { return nios2_fpu_insn_asm (n2fpu_f<fop3><f>); } 69863d1a8abSmrg [(set_attr "type" "custom")]) 69963d1a8abSmrg 70063d1a8abSmrg;; Floating point min/max operations 70163d1a8abSmrg(define_code_iterator SMINMAX [smin smax]) 70263d1a8abSmrg(define_code_attr minmax [(smin "min") (smax "max")]) 70363d1a8abSmrg(define_insn "<code><mode>3" 70463d1a8abSmrg [(set (match_operand:F 0 "register_operand" "=r") 70563d1a8abSmrg (SMINMAX:F (match_operand:F 1 "register_operand" "r") 70663d1a8abSmrg (match_operand:F 2 "register_operand" "r")))] 70763d1a8abSmrg "nios2_fpu_insn_enabled (n2fpu_f<minmax><f>)" 70863d1a8abSmrg { return nios2_fpu_insn_asm (n2fpu_f<minmax><f>); } 70963d1a8abSmrg [(set_attr "type" "custom")]) 71063d1a8abSmrg 71163d1a8abSmrg;; These 2-operand FP operations can be collected together 71263d1a8abSmrg(define_code_iterator FOP2 [abs neg sqrt]) 71363d1a8abSmrg(define_insn "<code><mode>2" 71463d1a8abSmrg [(set (match_operand:F 0 "register_operand" "=r") 71563d1a8abSmrg (FOP2:F (match_operand:F 1 "register_operand" "r")))] 71663d1a8abSmrg "nios2_fpu_insn_enabled (n2fpu_f<code><f>)" 71763d1a8abSmrg { return nios2_fpu_insn_asm (n2fpu_f<code><f>); } 71863d1a8abSmrg [(set_attr "type" "custom")]) 71963d1a8abSmrg 72063d1a8abSmrg;; X, Y register access instructions 72163d1a8abSmrg(define_insn "nios2_fwrx" 72263d1a8abSmrg [(unspec_volatile [(match_operand:DF 0 "register_operand" "r")] UNSPECV_FWRX)] 72363d1a8abSmrg "nios2_fpu_insn_enabled (n2fpu_fwrx)" 72463d1a8abSmrg { return nios2_fpu_insn_asm (n2fpu_fwrx); } 72563d1a8abSmrg [(set_attr "type" "custom")]) 72663d1a8abSmrg 72763d1a8abSmrg(define_insn "nios2_fwry" 72863d1a8abSmrg [(unspec_volatile [(match_operand:SF 0 "register_operand" "r")] UNSPECV_FWRY)] 72963d1a8abSmrg "nios2_fpu_insn_enabled (n2fpu_fwry)" 73063d1a8abSmrg { return nios2_fpu_insn_asm (n2fpu_fwry); } 73163d1a8abSmrg [(set_attr "type" "custom")]) 73263d1a8abSmrg 73363d1a8abSmrg;; The X, Y read insns uses an int iterator 73463d1a8abSmrg(define_int_iterator UNSPEC_READ_XY [UNSPECV_FRDXLO UNSPECV_FRDXHI 73563d1a8abSmrg UNSPECV_FRDY]) 73663d1a8abSmrg(define_int_attr read_xy [(UNSPECV_FRDXLO "frdxlo") (UNSPECV_FRDXHI "frdxhi") 73763d1a8abSmrg (UNSPECV_FRDY "frdy")]) 73863d1a8abSmrg(define_insn "nios2_<read_xy>" 73963d1a8abSmrg [(set (match_operand:SF 0 "register_operand" "=r") 74063d1a8abSmrg (unspec_volatile:SF [(const_int 0)] UNSPEC_READ_XY))] 74163d1a8abSmrg "nios2_fpu_insn_enabled (n2fpu_<read_xy>)" 74263d1a8abSmrg { return nios2_fpu_insn_asm (n2fpu_<read_xy>); } 74363d1a8abSmrg [(set_attr "type" "custom")]) 74463d1a8abSmrg 74563d1a8abSmrg;; Various math functions 74663d1a8abSmrg(define_int_iterator MATHFUNC 74763d1a8abSmrg [UNSPEC_FCOS UNSPEC_FSIN UNSPEC_FTAN UNSPEC_FATAN UNSPEC_FEXP UNSPEC_FLOG]) 74863d1a8abSmrg(define_int_attr mathfunc [(UNSPEC_FCOS "cos") (UNSPEC_FSIN "sin") 74963d1a8abSmrg (UNSPEC_FTAN "tan") (UNSPEC_FATAN "atan") 75063d1a8abSmrg (UNSPEC_FEXP "exp") (UNSPEC_FLOG "log")]) 75163d1a8abSmrg 75263d1a8abSmrg(define_insn "<mathfunc><mode>2" 75363d1a8abSmrg [(set (match_operand:F 0 "register_operand" "=r") 75463d1a8abSmrg (unspec:F [(match_operand:F 1 "register_operand" "r")] MATHFUNC))] 75563d1a8abSmrg "nios2_fpu_insn_enabled (n2fpu_f<mathfunc><f>)" 75663d1a8abSmrg { return nios2_fpu_insn_asm (n2fpu_f<mathfunc><f>); } 75763d1a8abSmrg [(set_attr "type" "custom")]) 75863d1a8abSmrg 75963d1a8abSmrg;; Converting between floating point and fixed point 76063d1a8abSmrg 76163d1a8abSmrg(define_code_iterator FLOAT [float unsigned_float]) 76263d1a8abSmrg(define_code_iterator FIX [fix unsigned_fix]) 76363d1a8abSmrg 76463d1a8abSmrg(define_code_attr conv_op [(float "float") (unsigned_float "floatuns") 76563d1a8abSmrg (fix "fix") (unsigned_fix "fixuns")]) 76663d1a8abSmrg(define_code_attr i [(float "i") (unsigned_float "u") 76763d1a8abSmrg (fix "i") (unsigned_fix "u")]) 76863d1a8abSmrg 76963d1a8abSmrg;; Integer to float conversions 77063d1a8abSmrg(define_insn "<conv_op>si<mode>2" 77163d1a8abSmrg [(set (match_operand:F 0 "register_operand" "=r") 77263d1a8abSmrg (FLOAT:F (match_operand:SI 1 "register_operand" "r")))] 77363d1a8abSmrg "nios2_fpu_insn_enabled (n2fpu_float<i><f>)" 77463d1a8abSmrg { return nios2_fpu_insn_asm (n2fpu_float<i><f>); } 77563d1a8abSmrg [(set_attr "type" "custom")]) 77663d1a8abSmrg 77763d1a8abSmrg;; Float to integer conversions 77863d1a8abSmrg(define_insn "<conv_op>_trunc<mode>si2" 77963d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 78063d1a8abSmrg (FIX:SI (match_operand:F 1 "general_operand" "r")))] 78163d1a8abSmrg "nios2_fpu_insn_enabled (n2fpu_fix<f><i>)" 78263d1a8abSmrg { return nios2_fpu_insn_asm (n2fpu_fix<f><i>); } 78363d1a8abSmrg [(set_attr "type" "custom")]) 78463d1a8abSmrg 78563d1a8abSmrg(define_insn "lroundsfsi2" 78663d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 78763d1a8abSmrg (unspec:SI [(match_operand:SF 1 "general_operand" "r")] UNSPEC_ROUND))] 78863d1a8abSmrg "nios2_fpu_insn_enabled (n2fpu_round)" 78963d1a8abSmrg { return nios2_fpu_insn_asm (n2fpu_round); } 79063d1a8abSmrg [(set_attr "type" "custom")]) 79163d1a8abSmrg 79263d1a8abSmrg(define_insn "extendsfdf2" 79363d1a8abSmrg [(set (match_operand:DF 0 "register_operand" "=r") 79463d1a8abSmrg (float_extend:DF (match_operand:SF 1 "general_operand" "r")))] 79563d1a8abSmrg "nios2_fpu_insn_enabled (n2fpu_fextsd)" 79663d1a8abSmrg { return nios2_fpu_insn_asm (n2fpu_fextsd); } 79763d1a8abSmrg [(set_attr "type" "custom")]) 79863d1a8abSmrg 79963d1a8abSmrg(define_insn "truncdfsf2" 80063d1a8abSmrg [(set (match_operand:SF 0 "register_operand" "=r") 80163d1a8abSmrg (float_truncate:SF (match_operand:DF 1 "general_operand" "r")))] 80263d1a8abSmrg "nios2_fpu_insn_enabled (n2fpu_ftruncds)" 80363d1a8abSmrg { return nios2_fpu_insn_asm (n2fpu_ftruncds); } 80463d1a8abSmrg [(set_attr "type" "custom")]) 80563d1a8abSmrg 80663d1a8abSmrg 80763d1a8abSmrg 80863d1a8abSmrg;; Prologue, Epilogue and Return 80963d1a8abSmrg 81063d1a8abSmrg(define_expand "prologue" 81163d1a8abSmrg [(const_int 1)] 81263d1a8abSmrg "" 81363d1a8abSmrg{ 81463d1a8abSmrg nios2_expand_prologue (); 81563d1a8abSmrg DONE; 81663d1a8abSmrg}) 81763d1a8abSmrg 81863d1a8abSmrg(define_expand "epilogue" 81963d1a8abSmrg [(return)] 82063d1a8abSmrg "" 82163d1a8abSmrg{ 82263d1a8abSmrg nios2_expand_epilogue (false); 82363d1a8abSmrg DONE; 82463d1a8abSmrg}) 82563d1a8abSmrg 82663d1a8abSmrg(define_expand "sibcall_epilogue" 82763d1a8abSmrg [(return)] 82863d1a8abSmrg "" 82963d1a8abSmrg{ 83063d1a8abSmrg nios2_expand_epilogue (true); 83163d1a8abSmrg DONE; 83263d1a8abSmrg}) 83363d1a8abSmrg 83463d1a8abSmrg(define_expand "return" 83563d1a8abSmrg [(simple_return)] 83663d1a8abSmrg "nios2_can_use_return_insn ()" 83763d1a8abSmrg{ 83863d1a8abSmrg if (nios2_expand_return ()) 83963d1a8abSmrg DONE; 84063d1a8abSmrg}) 84163d1a8abSmrg 84263d1a8abSmrg(define_insn "simple_return" 84363d1a8abSmrg [(simple_return)] 84463d1a8abSmrg "" 84563d1a8abSmrg "ret%." 84663d1a8abSmrg [(set_attr "type" "control")]) 84763d1a8abSmrg 84863d1a8abSmrg;; Block any insns from being moved before this point, since the 84963d1a8abSmrg;; profiling call to mcount can use various registers that aren't 85063d1a8abSmrg;; saved or used to pass arguments. 85163d1a8abSmrg 85263d1a8abSmrg(define_insn "blockage" 85363d1a8abSmrg [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 85463d1a8abSmrg "" 85563d1a8abSmrg "" 85663d1a8abSmrg [(set_attr "type" "unknown") 85763d1a8abSmrg (set_attr "length" "0")]) 85863d1a8abSmrg 85963d1a8abSmrg;; This is used in compiling the unwind routines. 86063d1a8abSmrg(define_expand "eh_return" 86163d1a8abSmrg [(use (match_operand 0 "general_operand"))] 86263d1a8abSmrg "" 86363d1a8abSmrg{ 86463d1a8abSmrg if (GET_MODE (operands[0]) != Pmode) 86563d1a8abSmrg operands[0] = convert_to_mode (Pmode, operands[0], 0); 86663d1a8abSmrg emit_insn (gen_eh_set_ra (operands[0])); 86763d1a8abSmrg DONE; 86863d1a8abSmrg}) 86963d1a8abSmrg 87063d1a8abSmrg;; Modify the return address for EH return. We can't expand this 87163d1a8abSmrg;; until we know where it will be put in the stack frame. 87263d1a8abSmrg 87363d1a8abSmrg(define_insn_and_split "eh_set_ra" 87463d1a8abSmrg [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN) 87563d1a8abSmrg (clobber (match_scratch:SI 1 "=&r"))] 87663d1a8abSmrg "" 87763d1a8abSmrg "#" 87863d1a8abSmrg "reload_completed" 87963d1a8abSmrg [(const_int 0)] 88063d1a8abSmrg{ 88163d1a8abSmrg nios2_set_return_address (operands[0], operands[1]); 88263d1a8abSmrg DONE; 88363d1a8abSmrg}) 88463d1a8abSmrg 88563d1a8abSmrg 88663d1a8abSmrg;; Jumps and calls 88763d1a8abSmrg 88863d1a8abSmrg; Note that the assembler fixes up any out-of-range branch instructions not 88963d1a8abSmrg; caught by the compiler branch shortening code. The sequence emitted by 89063d1a8abSmrg; the assembler can be very inefficient, but it is correct for PIC code. 89163d1a8abSmrg; For non-PIC we are better off converting to an absolute JMPI. 89263d1a8abSmrg; 89363d1a8abSmrg; Direct calls and sibcalls use the CALL and JMPI instructions, respectively. 89463d1a8abSmrg; These instructions have an immediate operand that specifies the low 28 bits 89563d1a8abSmrg; of the PC, effectively allowing direct calls within a 256MB memory segment. 89663d1a8abSmrg; Per the Nios II Processor Reference Handbook, the linker is not required to 89763d1a8abSmrg; check or adjust for overflow. 89863d1a8abSmrg 89963d1a8abSmrg(define_insn "indirect_jump" 90063d1a8abSmrg [(set (pc) (match_operand:SI 0 "register_operand" "c"))] 90163d1a8abSmrg "" 90263d1a8abSmrg "jmp%!\\t%0" 90363d1a8abSmrg [(set_attr "type" "control")]) 90463d1a8abSmrg 90563d1a8abSmrg(define_insn "jump" 90663d1a8abSmrg [(set (pc) 90763d1a8abSmrg (label_ref (match_operand 0 "" "")))] 90863d1a8abSmrg "" 90963d1a8abSmrg { 91063d1a8abSmrg if (get_attr_length (insn) == 2) 91163d1a8abSmrg return "br.n\\t%0"; 91263d1a8abSmrg else if (get_attr_length (insn) == 4) 91363d1a8abSmrg return "br\\t%0"; 91463d1a8abSmrg else 91563d1a8abSmrg return "jmpi\\t%0"; 91663d1a8abSmrg } 91763d1a8abSmrg [(set_attr "type" "control") 91863d1a8abSmrg (set (attr "length") 91963d1a8abSmrg (if_then_else 92063d1a8abSmrg (and (match_test "TARGET_HAS_CDX") 92163d1a8abSmrg (and (ge (minus (match_dup 0) (pc)) (const_int -1022)) 92263d1a8abSmrg (le (minus (match_dup 0) (pc)) (const_int 1022)))) 92363d1a8abSmrg (const_int 2) 92463d1a8abSmrg (if_then_else 92563d1a8abSmrg (ior (match_test "flag_pic") 92663d1a8abSmrg (and (ge (minus (match_dup 0) (pc)) (const_int -32764)) 92763d1a8abSmrg (le (minus (match_dup 0) (pc)) (const_int 32764)))) 92863d1a8abSmrg (const_int 4) 92963d1a8abSmrg (const_int 8))))]) 93063d1a8abSmrg 93163d1a8abSmrg(define_expand "call" 93263d1a8abSmrg [(parallel [(call (match_operand 0 "" "") 93363d1a8abSmrg (match_operand 1 "" "")) 93463d1a8abSmrg (clobber (reg:SI RA_REGNO))])] 93563d1a8abSmrg "" 93663d1a8abSmrg "nios2_adjust_call_address (&operands[0], NULL_RTX);") 93763d1a8abSmrg 93863d1a8abSmrg(define_expand "call_value" 93963d1a8abSmrg [(parallel [(set (match_operand 0 "" "") 94063d1a8abSmrg (call (match_operand 1 "" "") 94163d1a8abSmrg (match_operand 2 "" ""))) 94263d1a8abSmrg (clobber (reg:SI RA_REGNO))])] 94363d1a8abSmrg "" 94463d1a8abSmrg "nios2_adjust_call_address (&operands[1], NULL_RTX);") 94563d1a8abSmrg 94663d1a8abSmrg(define_insn "*call" 94763d1a8abSmrg [(call (mem:QI (match_operand:SI 0 "call_operand" "i,r")) 94863d1a8abSmrg (match_operand 1 "" "")) 94963d1a8abSmrg (clobber (reg:SI RA_REGNO))] 95063d1a8abSmrg "" 95163d1a8abSmrg "@ 95263d1a8abSmrg call\\t%0 95363d1a8abSmrg callr%.\\t%0" 95463d1a8abSmrg [(set_attr "type" "control")]) 95563d1a8abSmrg 95663d1a8abSmrg(define_insn "*call_value" 95763d1a8abSmrg [(set (match_operand 0 "" "") 95863d1a8abSmrg (call (mem:QI (match_operand:SI 1 "call_operand" "i,r")) 95963d1a8abSmrg (match_operand 2 "" ""))) 96063d1a8abSmrg (clobber (reg:SI RA_REGNO))] 96163d1a8abSmrg "" 96263d1a8abSmrg "@ 96363d1a8abSmrg call\\t%1 96463d1a8abSmrg callr%.\\t%1" 96563d1a8abSmrg [(set_attr "type" "control")]) 96663d1a8abSmrg 96763d1a8abSmrg(define_expand "sibcall" 96863d1a8abSmrg [(parallel [(call (match_operand 0 "" "") 96963d1a8abSmrg (match_operand 1 "" "")) 97063d1a8abSmrg (return)])] 97163d1a8abSmrg "" 97263d1a8abSmrg "nios2_adjust_call_address (&operands[0], NULL_RTX);") 97363d1a8abSmrg 97463d1a8abSmrg(define_expand "sibcall_value" 97563d1a8abSmrg [(parallel [(set (match_operand 0 "" "") 97663d1a8abSmrg (call (match_operand 1 "" "") 97763d1a8abSmrg (match_operand 2 "" ""))) 97863d1a8abSmrg (return)])] 97963d1a8abSmrg "" 98063d1a8abSmrg "nios2_adjust_call_address (&operands[1], NULL_RTX);") 98163d1a8abSmrg 98263d1a8abSmrg(define_insn "sibcall_internal" 98363d1a8abSmrg [(call (mem:QI (match_operand:SI 0 "call_operand" "i,j")) 98463d1a8abSmrg (match_operand 1 "" "")) 98563d1a8abSmrg (return)] 98663d1a8abSmrg "" 98763d1a8abSmrg "@ 98863d1a8abSmrg jmpi\\t%0 98963d1a8abSmrg jmp%!\\t%0" 99063d1a8abSmrg [(set_attr "type" "control")]) 99163d1a8abSmrg 99263d1a8abSmrg(define_insn "sibcall_value_internal" 99363d1a8abSmrg [(set (match_operand 0 "register_operand" "") 99463d1a8abSmrg (call (mem:QI (match_operand:SI 1 "call_operand" "i,j")) 99563d1a8abSmrg (match_operand 2 "" ""))) 99663d1a8abSmrg (return)] 99763d1a8abSmrg "" 99863d1a8abSmrg "@ 99963d1a8abSmrg jmpi\\t%1 100063d1a8abSmrg jmp%!\\t%1" 100163d1a8abSmrg [(set_attr "type" "control")]) 100263d1a8abSmrg 100363d1a8abSmrg(define_expand "tablejump" 100463d1a8abSmrg [(parallel [(set (pc) (match_operand 0 "register_operand" "r")) 100563d1a8abSmrg (use (label_ref (match_operand 1 "" "")))])] 100663d1a8abSmrg "" 100763d1a8abSmrg{ 100863d1a8abSmrg if (flag_pic) 100963d1a8abSmrg { 101063d1a8abSmrg /* Hopefully, CSE will eliminate this copy. */ 101163d1a8abSmrg rtx reg1 = copy_addr_to_reg (gen_rtx_LABEL_REF (Pmode, operands[1])); 101263d1a8abSmrg rtx reg2 = gen_reg_rtx (SImode); 101363d1a8abSmrg 101463d1a8abSmrg emit_insn (gen_addsi3 (reg2, operands[0], reg1)); 101563d1a8abSmrg operands[0] = reg2; 101663d1a8abSmrg } 101763d1a8abSmrg}) 101863d1a8abSmrg 101963d1a8abSmrg(define_insn "*tablejump" 102063d1a8abSmrg [(set (pc) 102163d1a8abSmrg (match_operand:SI 0 "register_operand" "c")) 102263d1a8abSmrg (use (label_ref (match_operand 1 "" "")))] 102363d1a8abSmrg "" 102463d1a8abSmrg "jmp%!\\t%0" 102563d1a8abSmrg [(set_attr "type" "control")]) 102663d1a8abSmrg 102763d1a8abSmrg 102863d1a8abSmrg;; cstore, cbranch patterns 102963d1a8abSmrg 103063d1a8abSmrg(define_mode_iterator CM [SI SF DF]) 103163d1a8abSmrg 103263d1a8abSmrg(define_expand "cstore<mode>4" 103363d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 103463d1a8abSmrg (match_operator:SI 1 "expandable_comparison_operator" 103563d1a8abSmrg [(match_operand:CM 2 "register_operand") 103663d1a8abSmrg (match_operand:CM 3 "nonmemory_operand")]))] 103763d1a8abSmrg "" 103863d1a8abSmrg{ 103963d1a8abSmrg if (!nios2_validate_compare (<MODE>mode, &operands[1], &operands[2], 104063d1a8abSmrg &operands[3])) 104163d1a8abSmrg FAIL; 104263d1a8abSmrg}) 104363d1a8abSmrg 104463d1a8abSmrg(define_expand "cbranch<mode>4" 104563d1a8abSmrg [(set (pc) 104663d1a8abSmrg (if_then_else 104763d1a8abSmrg (match_operator 0 "expandable_comparison_operator" 104863d1a8abSmrg [(match_operand:CM 1 "register_operand") 104963d1a8abSmrg (match_operand:CM 2 "nonmemory_operand")]) 105063d1a8abSmrg (label_ref (match_operand 3 "")) 105163d1a8abSmrg (pc)))] 105263d1a8abSmrg "" 105363d1a8abSmrg{ 105463d1a8abSmrg if (!nios2_validate_compare (<MODE>mode, &operands[0], &operands[1], 105563d1a8abSmrg &operands[2])) 105663d1a8abSmrg FAIL; 105763d1a8abSmrg if (GET_MODE_CLASS (<MODE>mode) == MODE_FLOAT 105863d1a8abSmrg || !reg_or_0_operand (operands[2], <MODE>mode)) 105963d1a8abSmrg { 106063d1a8abSmrg rtx condreg = gen_reg_rtx (SImode); 106163d1a8abSmrg emit_insn (gen_cstore<mode>4 106263d1a8abSmrg (condreg, operands[0], operands[1], operands[2])); 106363d1a8abSmrg operands[1] = condreg; 106463d1a8abSmrg operands[2] = const0_rtx; 106563d1a8abSmrg operands[0] = gen_rtx_fmt_ee (NE, VOIDmode, condreg, const0_rtx); 106663d1a8abSmrg } 106763d1a8abSmrg}) 106863d1a8abSmrg 106963d1a8abSmrg(define_insn "nios2_cbranch" 107063d1a8abSmrg [(set (pc) 107163d1a8abSmrg (if_then_else 107263d1a8abSmrg (match_operator 0 "ordered_comparison_operator" 107363d1a8abSmrg [(match_operand:SI 1 "reg_or_0_operand" "rM") 107463d1a8abSmrg (match_operand:SI 2 "reg_or_0_operand" "rM")]) 107563d1a8abSmrg (label_ref (match_operand 3 "" "")) 107663d1a8abSmrg (pc)))] 107763d1a8abSmrg "" 107863d1a8abSmrg{ 107963d1a8abSmrg if (get_attr_length (insn) == 2) 108063d1a8abSmrg return "b%0z.n\t%z1, %l3"; 108163d1a8abSmrg else if (get_attr_length (insn) == 4) 108263d1a8abSmrg return "b%0\t%z1, %z2, %l3"; 108363d1a8abSmrg else if (get_attr_length (insn) == 6) 108463d1a8abSmrg return "b%R0z.n\t%z1, .+6;jmpi\t%l3"; 108563d1a8abSmrg else 108663d1a8abSmrg return "b%R0\t%z1, %z2, .+8;jmpi\t%l3"; 108763d1a8abSmrg} 108863d1a8abSmrg [(set_attr "type" "control") 108963d1a8abSmrg (set (attr "length") 109063d1a8abSmrg (cond 109163d1a8abSmrg [(and (match_test "nios2_cdx_narrow_form_p (insn)") 109263d1a8abSmrg (ge (minus (match_dup 3) (pc)) (const_int -126)) 109363d1a8abSmrg (le (minus (match_dup 3) (pc)) (const_int 126))) 109463d1a8abSmrg (const_int 2) 109563d1a8abSmrg (ior (match_test "flag_pic") 109663d1a8abSmrg (and (ge (minus (match_dup 3) (pc)) (const_int -32764)) 109763d1a8abSmrg (le (minus (match_dup 3) (pc)) (const_int 32764)))) 109863d1a8abSmrg (const_int 4) 109963d1a8abSmrg (match_test "nios2_cdx_narrow_form_p (insn)") 110063d1a8abSmrg (const_int 6)] 110163d1a8abSmrg (const_int 8)))]) 110263d1a8abSmrg 110363d1a8abSmrg;; Floating point comparisons 110463d1a8abSmrg(define_code_iterator FCMP [eq ne gt ge le lt]) 110563d1a8abSmrg(define_insn "nios2_s<code><mode>" 110663d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 110763d1a8abSmrg (FCMP:SI (match_operand:F 1 "register_operand" "r") 110863d1a8abSmrg (match_operand:F 2 "register_operand" "r")))] 110963d1a8abSmrg "nios2_fpu_insn_enabled (n2fpu_fcmp<code><f>)" 111063d1a8abSmrg { return nios2_fpu_insn_asm (n2fpu_fcmp<code><f>); } 111163d1a8abSmrg [(set_attr "type" "custom")]) 111263d1a8abSmrg 111363d1a8abSmrg;; Integer comparisons 111463d1a8abSmrg 111563d1a8abSmrg(define_code_iterator EQNE [eq ne]) 111663d1a8abSmrg(define_insn "nios2_cmp<code>" 111763d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 111863d1a8abSmrg (EQNE:SI (match_operand:SI 1 "register_operand" "%r") 111963d1a8abSmrg (match_operand:SI 2 "arith_operand" "rI")))] 112063d1a8abSmrg "" 112163d1a8abSmrg "cmp<code>%i2\\t%0, %1, %z2" 112263d1a8abSmrg [(set_attr "type" "alu")]) 112363d1a8abSmrg 112463d1a8abSmrg(define_code_iterator SCMP [ge lt]) 112563d1a8abSmrg(define_insn "nios2_cmp<code>" 112663d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 112763d1a8abSmrg (SCMP:SI (match_operand:SI 1 "reg_or_0_operand" "rM") 112863d1a8abSmrg (match_operand:SI 2 "arith_operand" "rI")))] 112963d1a8abSmrg "" 113063d1a8abSmrg "cmp<code>%i2\\t%0, %z1, %z2" 113163d1a8abSmrg [(set_attr "type" "alu")]) 113263d1a8abSmrg 113363d1a8abSmrg(define_code_iterator UCMP [geu ltu]) 113463d1a8abSmrg(define_insn "nios2_cmp<code>" 113563d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 113663d1a8abSmrg (UCMP:SI (match_operand:SI 1 "reg_or_0_operand" "rM") 113763d1a8abSmrg (match_operand:SI 2 "uns_arith_operand" "rJ")))] 113863d1a8abSmrg "" 113963d1a8abSmrg "cmp<code>%u2\\t%0, %z1, %z2" 114063d1a8abSmrg [(set_attr "type" "alu")]) 114163d1a8abSmrg 114263d1a8abSmrg 114363d1a8abSmrg 114463d1a8abSmrg;; Custom instruction patterns. The operands are intentionally 114563d1a8abSmrg;; mode-less, to serve as generic carriers of all Altera defined 114663d1a8abSmrg;; built-in instruction/function types. 114763d1a8abSmrg 114863d1a8abSmrg(define_insn "custom_nxx" 114963d1a8abSmrg [(unspec_volatile [(match_operand 0 "custom_insn_opcode" "N") 115063d1a8abSmrg (match_operand 1 "reg_or_0_operand" "rM") 115163d1a8abSmrg (match_operand 2 "reg_or_0_operand" "rM")] 115263d1a8abSmrg UNSPECV_CUSTOM_NXX)] 115363d1a8abSmrg "" 115463d1a8abSmrg "custom\\t%0, zero, %z1, %z2" 115563d1a8abSmrg [(set_attr "type" "custom")]) 115663d1a8abSmrg 115763d1a8abSmrg(define_insn "custom_xnxx" 115863d1a8abSmrg [(set (match_operand 0 "register_operand" "=r") 115963d1a8abSmrg (unspec_volatile [(match_operand 1 "custom_insn_opcode" "N") 116063d1a8abSmrg (match_operand 2 "reg_or_0_operand" "rM") 116163d1a8abSmrg (match_operand 3 "reg_or_0_operand" "rM")] 116263d1a8abSmrg UNSPECV_CUSTOM_XNXX))] 116363d1a8abSmrg "" 116463d1a8abSmrg "custom\\t%1, %0, %z2, %z3" 116563d1a8abSmrg [(set_attr "type" "custom")]) 116663d1a8abSmrg 116763d1a8abSmrg 116863d1a8abSmrg;; Misc. patterns 116963d1a8abSmrg 117063d1a8abSmrg(define_insn "nop" 117163d1a8abSmrg [(const_int 0)] 117263d1a8abSmrg "" 117363d1a8abSmrg "nop%." 117463d1a8abSmrg [(set_attr "type" "nop")]) 117563d1a8abSmrg 117663d1a8abSmrg;; Connect 'sync' to 'memory_barrier' standard expand name 117763d1a8abSmrg(define_expand "memory_barrier" 117863d1a8abSmrg [(const_int 0)] 117963d1a8abSmrg "" 118063d1a8abSmrg{ 118163d1a8abSmrg emit_insn (gen_sync ()); 118263d1a8abSmrg DONE; 118363d1a8abSmrg}) 118463d1a8abSmrg 118563d1a8abSmrg;; For the nios2 __builtin_sync built-in function 118663d1a8abSmrg(define_expand "sync" 118763d1a8abSmrg [(set (match_dup 0) 118863d1a8abSmrg (unspec:BLK [(match_dup 0)] UNSPEC_SYNC))] 118963d1a8abSmrg "" 119063d1a8abSmrg{ 119163d1a8abSmrg operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 119263d1a8abSmrg MEM_VOLATILE_P (operands[0]) = 1; 119363d1a8abSmrg}) 119463d1a8abSmrg 119563d1a8abSmrg(define_insn "*sync_insn" 119663d1a8abSmrg [(set (match_operand:BLK 0 "" "") 119763d1a8abSmrg (unspec:BLK [(match_dup 0)] UNSPEC_SYNC))] 119863d1a8abSmrg "" 119963d1a8abSmrg "sync" 120063d1a8abSmrg [(set_attr "type" "control")]) 120163d1a8abSmrg 120263d1a8abSmrg(define_insn "rdctl" 120363d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 120463d1a8abSmrg (unspec_volatile:SI [(match_operand:SI 1 "rdwrctl_operand" "O")] 120563d1a8abSmrg UNSPECV_RDCTL))] 120663d1a8abSmrg "" 120763d1a8abSmrg "rdctl\\t%0, ctl%1" 120863d1a8abSmrg [(set_attr "type" "control")]) 120963d1a8abSmrg 121063d1a8abSmrg(define_insn "wrctl" 121163d1a8abSmrg [(unspec_volatile:SI [(match_operand:SI 0 "rdwrctl_operand" "O") 121263d1a8abSmrg (match_operand:SI 1 "reg_or_0_operand" "rM")] 121363d1a8abSmrg UNSPECV_WRCTL)] 121463d1a8abSmrg "" 121563d1a8abSmrg "wrctl\\tctl%0, %z1" 121663d1a8abSmrg [(set_attr "type" "control")]) 121763d1a8abSmrg 121863d1a8abSmrg(define_insn "rdprs" 121963d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 122063d1a8abSmrg (unspec_volatile:SI [(match_operand:SI 1 "rdwrctl_operand" "O") 122163d1a8abSmrg (match_operand:SI 2 "arith_operand" "U")] 122263d1a8abSmrg UNSPECV_RDPRS))] 122363d1a8abSmrg "" 122463d1a8abSmrg "rdprs\\t%0, %1, %2" 122563d1a8abSmrg [(set_attr "type" "control")]) 122663d1a8abSmrg 122763d1a8abSmrg;; Cache Instructions 122863d1a8abSmrg 122963d1a8abSmrg(define_insn "flushd" 123063d1a8abSmrg [(unspec_volatile:SI [(match_operand:SI 0 "ldstio_memory_operand" "w")] 123163d1a8abSmrg UNSPECV_FLUSHD)] 123263d1a8abSmrg "" 123363d1a8abSmrg "flushd\\t%0" 123463d1a8abSmrg [(set_attr "type" "control")]) 123563d1a8abSmrg 123663d1a8abSmrg(define_insn "flushda" 123763d1a8abSmrg [(unspec_volatile:SI [(match_operand:SI 0 "ldstio_memory_operand" "w")] 123863d1a8abSmrg UNSPECV_FLUSHDA)] 123963d1a8abSmrg "" 124063d1a8abSmrg "flushda\\t%0" 124163d1a8abSmrg [(set_attr "type" "control")]) 124263d1a8abSmrg 124363d1a8abSmrg;; R2 Instructions 124463d1a8abSmrg 124563d1a8abSmrg(define_insn "wrpie" 124663d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=r") 124763d1a8abSmrg (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r")] 124863d1a8abSmrg UNSPECV_WRPIE))] 124963d1a8abSmrg "TARGET_ARCH_R2" 125063d1a8abSmrg "wrpie\\t%0, %1" 125163d1a8abSmrg [(set_attr "type" "control")]) 125263d1a8abSmrg 125363d1a8abSmrg(define_insn "eni" 125463d1a8abSmrg [(unspec:VOID [(match_operand 0 "const_int_operand" "i")] 125563d1a8abSmrg UNSPECV_ENI)] 125663d1a8abSmrg "TARGET_ARCH_R2" 125763d1a8abSmrg "eni\\t%0" 125863d1a8abSmrg [(set_attr "type" "control")]) 125963d1a8abSmrg 126063d1a8abSmrg;; Trap patterns 126163d1a8abSmrg(define_insn "trap" 126263d1a8abSmrg [(trap_if (const_int 1) (const_int 3))] 126363d1a8abSmrg "" 126463d1a8abSmrg "trap%.\\t3" 126563d1a8abSmrg [(set_attr "type" "control")]) 126663d1a8abSmrg 126763d1a8abSmrg(define_insn "ctrapsi4" 126863d1a8abSmrg [(trap_if (match_operator 0 "ordered_comparison_operator" 126963d1a8abSmrg [(match_operand:SI 1 "reg_or_0_operand" "rM") 127063d1a8abSmrg (match_operand:SI 2 "reg_or_0_operand" "rM")]) 127163d1a8abSmrg (match_operand 3 "const_int_operand" "i"))] 127263d1a8abSmrg "" 127363d1a8abSmrg{ 127463d1a8abSmrg if (get_attr_length (insn) == 6) 127563d1a8abSmrg return "b%R0\\t%z1, %z2, 1f\;trap.n\\t%3\;1:"; 127663d1a8abSmrg else 127763d1a8abSmrg return "b%R0\\t%z1, %z2, 1f\;trap\\t%3\;1:"; 127863d1a8abSmrg} 127963d1a8abSmrg [(set_attr "type" "control") 128063d1a8abSmrg (set (attr "length") 128163d1a8abSmrg (if_then_else (match_test "nios2_cdx_narrow_form_p (insn)") 128263d1a8abSmrg (const_int 6) (const_int 8)))]) 128363d1a8abSmrg 128463d1a8abSmrg;; Load the GOT register. 128563d1a8abSmrg(define_insn "load_got_register" 128663d1a8abSmrg [(set (match_operand:SI 0 "register_operand" "=&r") 128763d1a8abSmrg (unspec:SI [(const_int 0)] UNSPEC_LOAD_GOT_REGISTER)) 128863d1a8abSmrg (set (match_operand:SI 1 "register_operand" "=r") 128963d1a8abSmrg (unspec:SI [(const_int 0)] UNSPEC_LOAD_GOT_REGISTER))] 129063d1a8abSmrg "" 129163d1a8abSmrg "nextpc\\t%0 129263d1a8abSmrg\\t1: 129363d1a8abSmrg\\tmovhi\\t%1, %%hiadj(_gp_got - 1b) 129463d1a8abSmrg\\taddi\\t%1, %1, %%lo(_gp_got - 1b)" 129563d1a8abSmrg [(set_attr "length" "12")]) 129663d1a8abSmrg 129763d1a8abSmrg;; Read thread pointer register 129863d1a8abSmrg(define_expand "get_thread_pointersi" 129963d1a8abSmrg [(match_operand:SI 0 "register_operand" "=r")] 130063d1a8abSmrg "TARGET_LINUX_ABI" 130163d1a8abSmrg{ 130263d1a8abSmrg emit_move_insn (operands[0], gen_rtx_REG (Pmode, TP_REGNO)); 130363d1a8abSmrg DONE; 130463d1a8abSmrg}) 130563d1a8abSmrg 130663d1a8abSmrg;; Synchronization Primitives 130763d1a8abSmrg(include "sync.md") 130863d1a8abSmrg 130963d1a8abSmrg;; Include the ldwm/stwm/push.n/pop.n patterns and peepholes. 131063d1a8abSmrg(include "ldstwm.md") 131163d1a8abSmrg 1312