ia64.md revision 132718
190075Sobrien;; IA-64 Machine description template 2132718Skan;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 3132718Skan;; Free Software Foundation, Inc. 490075Sobrien;; Contributed by James E. Wilson <wilson@cygnus.com> and 590075Sobrien;; David Mosberger <davidm@hpl.hp.com>. 690075Sobrien 7132718Skan;; This file is part of GCC. 890075Sobrien 9132718Skan;; GCC is free software; you can redistribute it and/or modify 1090075Sobrien;; it under the terms of the GNU General Public License as published by 1190075Sobrien;; the Free Software Foundation; either version 2, or (at your option) 1290075Sobrien;; any later version. 1390075Sobrien 14132718Skan;; GCC is distributed in the hope that it will be useful, 1590075Sobrien;; but WITHOUT ANY WARRANTY; without even the implied warranty of 1690075Sobrien;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1790075Sobrien;; GNU General Public License for more details. 1890075Sobrien 1990075Sobrien;; You should have received a copy of the GNU General Public License 20132718Skan;; along with GCC; see the file COPYING. If not, write to 2190075Sobrien;; the Free Software Foundation, 59 Temple Place - Suite 330, 2290075Sobrien;; Boston, MA 02111-1307, USA. 2390075Sobrien 2490075Sobrien;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. 2590075Sobrien 2690075Sobrien;; ??? register_operand accepts (subreg:DI (mem:SI X)) which forces later 2790075Sobrien;; reload. This will be fixed once scheduling support is turned on. 2890075Sobrien 2990075Sobrien;; ??? Optimize for post-increment addressing modes. 3090075Sobrien 3190075Sobrien;; ??? fselect is not supported, because there is no integer register 3290075Sobrien;; equivalent. 3390075Sobrien 3490075Sobrien;; ??? fp abs/min/max instructions may also work for integer values. 3590075Sobrien 3690075Sobrien;; ??? Would a predicate_reg_operand predicate be useful? The HP one is buggy, 3790075Sobrien;; it assumes the operand is a register and takes REGNO of it without checking. 3890075Sobrien 3990075Sobrien;; ??? Would a branch_reg_operand predicate be useful? The HP one is buggy, 4090075Sobrien;; it assumes the operand is a register and takes REGNO of it without checking. 4190075Sobrien 4290075Sobrien;; ??? Go through list of documented named patterns and look for more to 4390075Sobrien;; implement. 4490075Sobrien 4590075Sobrien;; ??? Go through instruction manual and look for more instructions that 4690075Sobrien;; can be emitted. 4790075Sobrien 4890075Sobrien;; ??? Add function unit scheduling info for Itanium (TM) processor. 4990075Sobrien 5090075Sobrien;; ??? Need a better way to describe alternate fp status registers. 5190075Sobrien 52117395Skan(define_constants 53117395Skan [; Relocations 54117395Skan (UNSPEC_LTOFF_DTPMOD 0) 55117395Skan (UNSPEC_LTOFF_DTPREL 1) 56117395Skan (UNSPEC_DTPREL 2) 57117395Skan (UNSPEC_LTOFF_TPREL 3) 58117395Skan (UNSPEC_TPREL 4) 59117395Skan 60117395Skan (UNSPEC_LD_BASE 9) 61117395Skan (UNSPEC_GR_SPILL 10) 62117395Skan (UNSPEC_GR_RESTORE 11) 63117395Skan (UNSPEC_FR_SPILL 12) 64117395Skan (UNSPEC_FR_RESTORE 13) 65117395Skan (UNSPEC_FR_RECIP_APPROX 14) 66117395Skan (UNSPEC_PRED_REL_MUTEX 15) 67132718Skan (UNSPEC_GETF_EXP 16) 68117395Skan (UNSPEC_PIC_CALL 17) 69117395Skan (UNSPEC_MF 18) 70117395Skan (UNSPEC_CMPXCHG_ACQ 19) 71117395Skan (UNSPEC_FETCHADD_ACQ 20) 72117395Skan (UNSPEC_BSP_VALUE 21) 73117395Skan (UNSPEC_FLUSHRS 22) 74117395Skan (UNSPEC_BUNDLE_SELECTOR 23) 75117395Skan (UNSPEC_ADDP4 24) 76117395Skan (UNSPEC_PROLOGUE_USE 25) 77122180Skan (UNSPEC_RET_ADDR 26) 78132718Skan (UNSPEC_SETF_EXP 27) 79132718Skan (UNSPEC_FR_SQRT_RECIP_APPROX 28) 80117395Skan ]) 81117395Skan 82117395Skan(define_constants 83117395Skan [(UNSPECV_ALLOC 0) 84117395Skan (UNSPECV_BLOCKAGE 1) 85117395Skan (UNSPECV_INSN_GROUP_BARRIER 2) 86117395Skan (UNSPECV_BREAK 3) 87117395Skan (UNSPECV_SET_BSP 4) 88117395Skan (UNSPECV_PSAC_ALL 5) ; pred.safe_across_calls 89117395Skan (UNSPECV_PSAC_NORMAL 6) 90117395Skan (UNSPECV_SETJMP_RECEIVER 7) 91117395Skan ]) 9290075Sobrien 9390075Sobrien;; :::::::::::::::::::: 9490075Sobrien;; :: 9590075Sobrien;; :: Attributes 9690075Sobrien;; :: 9790075Sobrien;; :::::::::::::::::::: 9890075Sobrien 99132718Skan;; Processor type. This attribute must exactly match the processor_type 100132718Skan;; enumeration in ia64.h. 101132718Skan(define_attr "cpu" "itanium,itanium2" (const (symbol_ref "ia64_tune"))) 102132718Skan 10390075Sobrien;; Instruction type. This primarily determines how instructions can be 10490075Sobrien;; packed in bundles, and secondarily affects scheduling to function units. 10590075Sobrien 10690075Sobrien;; A alu, can go in I or M syllable of a bundle 10790075Sobrien;; I integer 10890075Sobrien;; M memory 10990075Sobrien;; F floating-point 11090075Sobrien;; B branch 11190075Sobrien;; L long immediate, takes two syllables 11290075Sobrien;; S stop bit 11390075Sobrien 11490075Sobrien;; ??? Should not have any pattern with type unknown. Perhaps add code to 11590075Sobrien;; check this in md_reorg? Currently use unknown for patterns which emit 11690075Sobrien;; multiple instructions, patterns which emit 0 instructions, and patterns 11790075Sobrien;; which emit instruction that can go in any slot (e.g. nop). 11890075Sobrien 119117395Skan(define_attr "itanium_class" "unknown,ignore,stop_bit,br,fcmp,fcvtfx,fld, 120117395Skan fmac,fmisc,frar_i,frar_m,frbr,frfr,frpr,ialu,icmp,ilog,ishf,ld, 121117395Skan chk_s,long_i,mmmul,mmshf,mmshfi,rse_m,scall,sem,stf,st,syst_m0, 122132718Skan syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop,nop_b,nop_f, 123132718Skan nop_i,nop_m,nop_x,lfetch,pre_cycle" 124117395Skan (const_string "unknown")) 12590075Sobrien 12690075Sobrien;; chk_s has an I and an M form; use type A for convenience. 12790075Sobrien(define_attr "type" "unknown,A,I,M,F,B,L,X,S" 12890075Sobrien (cond [(eq_attr "itanium_class" "ld,st,fld,stf,sem,nop_m") (const_string "M") 12990075Sobrien (eq_attr "itanium_class" "rse_m,syst_m,syst_m0") (const_string "M") 13090075Sobrien (eq_attr "itanium_class" "frar_m,toar_m,frfr,tofr") (const_string "M") 13190075Sobrien (eq_attr "itanium_class" "lfetch") (const_string "M") 13290075Sobrien (eq_attr "itanium_class" "chk_s,ialu,icmp,ilog") (const_string "A") 13390075Sobrien (eq_attr "itanium_class" "fmisc,fmac,fcmp,xmpy") (const_string "F") 13490075Sobrien (eq_attr "itanium_class" "fcvtfx,nop_f") (const_string "F") 13590075Sobrien (eq_attr "itanium_class" "frar_i,toar_i,frbr,tobr") (const_string "I") 13690075Sobrien (eq_attr "itanium_class" "frpr,topr,ishf,xtd,tbit") (const_string "I") 13790075Sobrien (eq_attr "itanium_class" "mmmul,mmshf,mmshfi,nop_i") (const_string "I") 13890075Sobrien (eq_attr "itanium_class" "br,scall,nop_b") (const_string "B") 13990075Sobrien (eq_attr "itanium_class" "stop_bit") (const_string "S") 14090075Sobrien (eq_attr "itanium_class" "nop_x") (const_string "X") 14190075Sobrien (eq_attr "itanium_class" "long_i") (const_string "L")] 14290075Sobrien (const_string "unknown"))) 14390075Sobrien 14490075Sobrien(define_attr "itanium_requires_unit0" "no,yes" 14590075Sobrien (cond [(eq_attr "itanium_class" "syst_m0,sem,frfr,rse_m") (const_string "yes") 14690075Sobrien (eq_attr "itanium_class" "toar_m,frar_m") (const_string "yes") 14790075Sobrien (eq_attr "itanium_class" "frbr,tobr,mmmul") (const_string "yes") 14890075Sobrien (eq_attr "itanium_class" "tbit,ishf,topr,frpr") (const_string "yes") 14990075Sobrien (eq_attr "itanium_class" "toar_i,frar_i") (const_string "yes") 15090075Sobrien (eq_attr "itanium_class" "fmisc,fcmp") (const_string "yes")] 15190075Sobrien (const_string "no"))) 15290075Sobrien 15390075Sobrien;; Predication. True iff this instruction can be predicated. 15490075Sobrien 15590075Sobrien(define_attr "predicable" "no,yes" (const_string "yes")) 15690075Sobrien 157132718Skan;; Empty. True iff this insn does not generate any code. 158132718Skan 159132718Skan(define_attr "empty" "no,yes" (const_string "no")) 160132718Skan 16190075Sobrien 16290075Sobrien 163132718Skan;; DFA descriptions of ia64 processors used for insn scheduling and 164132718Skan;; bundling. 16590075Sobrien 166132718Skan(automata_option "ndfa") 16790075Sobrien 168132718Skan;; Uncomment the following line to output automata for debugging. 169132718Skan;; (automata_option "v") 17090075Sobrien 171132718Skan(automata_option "w") 17290075Sobrien 173132718Skan;;(automata_option "no-minimization") 17490075Sobrien 17590075Sobrien 176132718Skan(include "itanium1.md") 177132718Skan(include "itanium2.md") 17890075Sobrien 17990075Sobrien 18090075Sobrien;; :::::::::::::::::::: 18190075Sobrien;; :: 18290075Sobrien;; :: Moves 18390075Sobrien;; :: 18490075Sobrien;; :::::::::::::::::::: 18590075Sobrien 18690075Sobrien;; Set of a single predicate register. This is only used to implement 18790075Sobrien;; pr-to-pr move and complement. 18890075Sobrien 18990075Sobrien(define_insn "*movcci" 19090075Sobrien [(set (match_operand:CCI 0 "register_operand" "=c,c,c") 19190075Sobrien (match_operand:CCI 1 "nonmemory_operand" "O,n,c"))] 19290075Sobrien "" 19390075Sobrien "@ 19490075Sobrien cmp.ne %0, p0 = r0, r0 19590075Sobrien cmp.eq %0, p0 = r0, r0 19690075Sobrien (%1) cmp.eq.unc %0, p0 = r0, r0" 19790075Sobrien [(set_attr "itanium_class" "icmp") 19890075Sobrien (set_attr "predicable" "no")]) 19990075Sobrien 20090075Sobrien(define_insn "movbi" 20190075Sobrien [(set (match_operand:BI 0 "nonimmediate_operand" "=c,c,?c,?*r, c,*r,*r,*m,*r") 20290075Sobrien (match_operand:BI 1 "move_operand" " O,n, c, c,*r, n,*m,*r,*r"))] 20390075Sobrien "" 20490075Sobrien "@ 20590075Sobrien cmp.ne %0, %I0 = r0, r0 20690075Sobrien cmp.eq %0, %I0 = r0, r0 20790075Sobrien # 20890075Sobrien # 20990075Sobrien tbit.nz %0, %I0 = %1, 0 21090075Sobrien adds %0 = %1, r0 21190075Sobrien ld1%O1 %0 = %1%P1 21290075Sobrien st1%Q0 %0 = %1%P0 21390075Sobrien mov %0 = %1" 21490075Sobrien [(set_attr "itanium_class" "icmp,icmp,unknown,unknown,tbit,ialu,ld,st,ialu")]) 21590075Sobrien 21690075Sobrien(define_split 21790075Sobrien [(set (match_operand:BI 0 "register_operand" "") 21890075Sobrien (match_operand:BI 1 "register_operand" ""))] 21990075Sobrien "reload_completed 22090075Sobrien && GET_CODE (operands[0]) == REG && GR_REGNO_P (REGNO (operands[0])) 22190075Sobrien && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))" 22290075Sobrien [(cond_exec (ne (match_dup 1) (const_int 0)) 22390075Sobrien (set (match_dup 0) (const_int 1))) 22490075Sobrien (cond_exec (eq (match_dup 1) (const_int 0)) 22590075Sobrien (set (match_dup 0) (const_int 0)))] 22690075Sobrien "") 22790075Sobrien 22890075Sobrien(define_split 22990075Sobrien [(set (match_operand:BI 0 "register_operand" "") 23090075Sobrien (match_operand:BI 1 "register_operand" ""))] 23190075Sobrien "reload_completed 23290075Sobrien && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0])) 23390075Sobrien && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))" 23490075Sobrien [(set (match_dup 2) (match_dup 4)) 23590075Sobrien (set (match_dup 3) (match_dup 5)) 236117395Skan (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))] 23790075Sobrien "operands[2] = gen_rtx_REG (CCImode, REGNO (operands[0])); 23890075Sobrien operands[3] = gen_rtx_REG (CCImode, REGNO (operands[0]) + 1); 23990075Sobrien operands[4] = gen_rtx_REG (CCImode, REGNO (operands[1])); 24090075Sobrien operands[5] = gen_rtx_REG (CCImode, REGNO (operands[1]) + 1);") 24190075Sobrien 24290075Sobrien(define_expand "movqi" 24390075Sobrien [(set (match_operand:QI 0 "general_operand" "") 24490075Sobrien (match_operand:QI 1 "general_operand" ""))] 24590075Sobrien "" 24690075Sobrien{ 247117395Skan rtx op1 = ia64_expand_move (operands[0], operands[1]); 248117395Skan if (!op1) 249117395Skan DONE; 250117395Skan operands[1] = op1; 251117395Skan}) 25290075Sobrien 25390075Sobrien(define_insn "*movqi_internal" 25490075Sobrien [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f") 25590075Sobrien (match_operand:QI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))] 25690075Sobrien "ia64_move_ok (operands[0], operands[1])" 25790075Sobrien "@ 25890075Sobrien mov %0 = %r1 25990075Sobrien addl %0 = %1, r0 26090075Sobrien ld1%O1 %0 = %1%P1 26190075Sobrien st1%Q0 %0 = %r1%P0 26290075Sobrien getf.sig %0 = %1 26390075Sobrien setf.sig %0 = %r1 26490075Sobrien mov %0 = %1" 26590075Sobrien [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")]) 26690075Sobrien 26790075Sobrien(define_expand "movhi" 26890075Sobrien [(set (match_operand:HI 0 "general_operand" "") 26990075Sobrien (match_operand:HI 1 "general_operand" ""))] 27090075Sobrien "" 27190075Sobrien{ 272117395Skan rtx op1 = ia64_expand_move (operands[0], operands[1]); 273117395Skan if (!op1) 274117395Skan DONE; 275117395Skan operands[1] = op1; 276117395Skan}) 27790075Sobrien 27890075Sobrien(define_insn "*movhi_internal" 27990075Sobrien [(set (match_operand:HI 0 "destination_operand" "=r,r,r, m, r,*f,*f") 28090075Sobrien (match_operand:HI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))] 28190075Sobrien "ia64_move_ok (operands[0], operands[1])" 28290075Sobrien "@ 28390075Sobrien mov %0 = %r1 28490075Sobrien addl %0 = %1, r0 28590075Sobrien ld2%O1 %0 = %1%P1 28690075Sobrien st2%Q0 %0 = %r1%P0 28790075Sobrien getf.sig %0 = %1 28890075Sobrien setf.sig %0 = %r1 28990075Sobrien mov %0 = %1" 29090075Sobrien [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")]) 29190075Sobrien 29290075Sobrien(define_expand "movsi" 29390075Sobrien [(set (match_operand:SI 0 "general_operand" "") 29490075Sobrien (match_operand:SI 1 "general_operand" ""))] 29590075Sobrien "" 29690075Sobrien{ 297117395Skan rtx op1 = ia64_expand_move (operands[0], operands[1]); 298117395Skan if (!op1) 299117395Skan DONE; 300117395Skan operands[1] = op1; 301117395Skan}) 30290075Sobrien 30390075Sobrien(define_insn "*movsi_internal" 30490075Sobrien [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d") 30590075Sobrien (match_operand:SI 1 "move_operand" "rO,J,i,m,rO,*f,rO,*f,*d,rK"))] 30690075Sobrien "ia64_move_ok (operands[0], operands[1])" 30790075Sobrien "@ 30890075Sobrien mov %0 = %r1 30990075Sobrien addl %0 = %1, r0 31090075Sobrien movl %0 = %1 31190075Sobrien ld4%O1 %0 = %1%P1 31290075Sobrien st4%Q0 %0 = %r1%P0 31390075Sobrien getf.sig %0 = %1 31490075Sobrien setf.sig %0 = %r1 31590075Sobrien mov %0 = %1 31690075Sobrien mov %0 = %1 31790075Sobrien mov %0 = %r1" 318117395Skan ;; frar_m, toar_m ??? why not frar_i and toar_i 31990075Sobrien [(set_attr "itanium_class" "ialu,ialu,long_i,ld,st,frfr,tofr,fmisc,frar_m,toar_m")]) 32090075Sobrien 32190075Sobrien(define_expand "movdi" 32290075Sobrien [(set (match_operand:DI 0 "general_operand" "") 32390075Sobrien (match_operand:DI 1 "general_operand" ""))] 32490075Sobrien "" 32590075Sobrien{ 326117395Skan rtx op1 = ia64_expand_move (operands[0], operands[1]); 327117395Skan if (!op1) 328117395Skan DONE; 329117395Skan operands[1] = op1; 330117395Skan}) 33190075Sobrien 33290075Sobrien(define_insn "*movdi_internal" 33390075Sobrien [(set (match_operand:DI 0 "destination_operand" 33490075Sobrien "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b, r,*e, r,*d, r,*c") 33590075Sobrien (match_operand:DI 1 "move_operand" 336132718Skan "rO,JT,i,m,rO,*f,rO,*f, Q,*f,*b,rO,*e,rK,*d,rK,*c,rO"))] 33790075Sobrien "ia64_move_ok (operands[0], operands[1])" 33890075Sobrien{ 33990075Sobrien static const char * const alt[] = { 340117395Skan "%,mov %0 = %r1", 341117395Skan "%,addl %0 = %1, r0", 342117395Skan "%,movl %0 = %1", 343117395Skan "%,ld8%O1 %0 = %1%P1", 344117395Skan "%,st8%Q0 %0 = %r1%P0", 345117395Skan "%,getf.sig %0 = %1", 346117395Skan "%,setf.sig %0 = %r1", 347117395Skan "%,mov %0 = %1", 348117395Skan "%,ldf8 %0 = %1%P1", 349117395Skan "%,stf8 %0 = %1%P0", 350117395Skan "%,mov %0 = %1", 351117395Skan "%,mov %0 = %r1", 352117395Skan "%,mov %0 = %1", 353117395Skan "%,mov %0 = %1", 354117395Skan "%,mov %0 = %1", 355117395Skan "%,mov %0 = %1", 356117395Skan "mov %0 = pr", 357117395Skan "mov pr = %1, -1" 35890075Sobrien }; 35990075Sobrien 36090075Sobrien if (which_alternative == 2 && ! TARGET_NO_PIC 36190075Sobrien && symbolic_operand (operands[1], VOIDmode)) 36290075Sobrien abort (); 36390075Sobrien 36490075Sobrien return alt[which_alternative]; 365117395Skan} 36690075Sobrien [(set_attr "itanium_class" "ialu,ialu,long_i,ld,st,frfr,tofr,fmisc,fld,stf,frbr,tobr,frar_i,toar_i,frar_m,toar_m,frpr,topr")]) 36790075Sobrien 36890075Sobrien(define_split 369132718Skan [(set (match_operand 0 "register_operand" "") 370132718Skan (match_operand 1 "symbolic_operand" ""))] 37190075Sobrien "reload_completed && ! TARGET_NO_PIC" 37290075Sobrien [(const_int 0)] 37390075Sobrien{ 374132718Skan ia64_expand_load_address (operands[0], operands[1]); 37590075Sobrien DONE; 376117395Skan}) 37790075Sobrien 37890075Sobrien(define_expand "load_fptr" 37990075Sobrien [(set (match_dup 2) 380117395Skan (plus:DI (reg:DI 1) (match_operand 1 "function_operand" ""))) 38190075Sobrien (set (match_operand:DI 0 "register_operand" "") (match_dup 3))] 38290075Sobrien "" 38390075Sobrien{ 38490075Sobrien operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode); 38590075Sobrien operands[3] = gen_rtx_MEM (DImode, operands[2]); 38690075Sobrien RTX_UNCHANGING_P (operands[3]) = 1; 387117395Skan}) 38890075Sobrien 38990075Sobrien(define_insn "*load_fptr_internal1" 39090075Sobrien [(set (match_operand:DI 0 "register_operand" "=r") 391117395Skan (plus:DI (reg:DI 1) (match_operand 1 "function_operand" "s")))] 39290075Sobrien "" 39390075Sobrien "addl %0 = @ltoff(@fptr(%1)), gp" 39490075Sobrien [(set_attr "itanium_class" "ialu")]) 39590075Sobrien 39690075Sobrien(define_insn "load_gprel" 39790075Sobrien [(set (match_operand:DI 0 "register_operand" "=r") 398117395Skan (plus:DI (reg:DI 1) (match_operand 1 "sdata_symbolic_operand" "s")))] 39990075Sobrien "" 40090075Sobrien "addl %0 = @gprel(%1), gp" 40190075Sobrien [(set_attr "itanium_class" "ialu")]) 40290075Sobrien 40390075Sobrien(define_insn "gprel64_offset" 40490075Sobrien [(set (match_operand:DI 0 "register_operand" "=r") 40590075Sobrien (minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))] 40690075Sobrien "" 40790075Sobrien "movl %0 = @gprel(%1)" 40890075Sobrien [(set_attr "itanium_class" "long_i")]) 40990075Sobrien 41090075Sobrien(define_expand "load_gprel64" 41190075Sobrien [(set (match_dup 2) 41290075Sobrien (minus:DI (match_operand:DI 1 "symbolic_operand" "") (match_dup 3))) 41390075Sobrien (set (match_operand:DI 0 "register_operand" "") 41490075Sobrien (plus:DI (match_dup 3) (match_dup 2)))] 41590075Sobrien "" 41690075Sobrien{ 41790075Sobrien operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode); 41890075Sobrien operands[3] = pic_offset_table_rtx; 419117395Skan}) 42090075Sobrien 421132718Skan;; This is used as a placeholder for the return address during early 422132718Skan;; compilation. We won't know where we've placed this until during 423132718Skan;; reload, at which point it can wind up in b0, a general register, 424132718Skan;; or memory. The only safe destination under these conditions is a 425132718Skan;; general register. 426132718Skan 427132718Skan(define_insn_and_split "*movdi_ret_addr" 428132718Skan [(set (match_operand:DI 0 "register_operand" "=r") 429132718Skan (unspec:DI [(const_int 0)] UNSPEC_RET_ADDR))] 43090075Sobrien "" 431132718Skan "#" 432132718Skan "reload_completed" 433132718Skan [(const_int 0)] 43490075Sobrien{ 435132718Skan ia64_split_return_addr_rtx (operands[0]); 436132718Skan DONE; 437132718Skan} 438132718Skan [(set_attr "itanium_class" "ialu")]) 43990075Sobrien 440117395Skan(define_insn "*load_symptr_high" 44190075Sobrien [(set (match_operand:DI 0 "register_operand" "=r") 442117395Skan (plus:DI (high:DI (match_operand 1 "got_symbolic_operand" "s")) 443117395Skan (match_operand:DI 2 "register_operand" "a")))] 44490075Sobrien "" 445117395Skan{ 446117395Skan if (HAVE_AS_LTOFFX_LDXMOV_RELOCS) 447117395Skan return "%,addl %0 = @ltoffx(%1), %2"; 448117395Skan else 449117395Skan return "%,addl %0 = @ltoff(%1), %2"; 450117395Skan} 45190075Sobrien [(set_attr "itanium_class" "ialu")]) 45290075Sobrien 453117395Skan(define_insn "*load_symptr_low" 454117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 455117395Skan (lo_sum:DI (match_operand:DI 1 "register_operand" "r") 456117395Skan (match_operand 2 "got_symbolic_operand" "s")))] 457117395Skan "" 458117395Skan{ 459117395Skan if (HAVE_AS_LTOFFX_LDXMOV_RELOCS) 460117395Skan return "%,ld8.mov %0 = [%1], %2"; 461117395Skan else 462117395Skan return "%,ld8 %0 = [%1]"; 463117395Skan} 464117395Skan [(set_attr "itanium_class" "ld")]) 465117395Skan 466117395Skan(define_insn "load_ltoff_dtpmod" 467117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 468117395Skan (plus:DI (reg:DI 1) 469117395Skan (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 470117395Skan UNSPEC_LTOFF_DTPMOD)))] 471117395Skan "" 472117395Skan "addl %0 = @ltoff(@dtpmod(%1)), gp" 473117395Skan [(set_attr "itanium_class" "ialu")]) 474117395Skan 475117395Skan(define_insn "load_ltoff_dtprel" 476117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 477117395Skan (plus:DI (reg:DI 1) 478117395Skan (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 479117395Skan UNSPEC_LTOFF_DTPREL)))] 480117395Skan "" 481117395Skan "addl %0 = @ltoff(@dtprel(%1)), gp" 482117395Skan [(set_attr "itanium_class" "ialu")]) 483117395Skan 484117395Skan(define_expand "load_dtprel" 485117395Skan [(set (match_operand:DI 0 "register_operand" "") 486117395Skan (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 487117395Skan UNSPEC_DTPREL))] 488117395Skan "" 489117395Skan "") 490117395Skan 491117395Skan(define_insn "*load_dtprel64" 492117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 493117395Skan (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 494117395Skan UNSPEC_DTPREL))] 495117395Skan "TARGET_TLS64" 496117395Skan "movl %0 = @dtprel(%1)" 497117395Skan [(set_attr "itanium_class" "long_i")]) 498117395Skan 499117395Skan(define_insn "*load_dtprel22" 500117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 501117395Skan (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 502117395Skan UNSPEC_DTPREL))] 503117395Skan "" 504117395Skan "addl %0 = @dtprel(%1), r0" 505117395Skan [(set_attr "itanium_class" "ialu")]) 506117395Skan 507117395Skan(define_expand "add_dtprel" 508117395Skan [(set (match_operand:DI 0 "register_operand" "") 509117395Skan (plus:DI (match_operand:DI 1 "register_operand" "") 510117395Skan (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 511117395Skan UNSPEC_DTPREL)))] 512117395Skan "!TARGET_TLS64" 513117395Skan "") 514117395Skan 515117395Skan(define_insn "*add_dtprel14" 516117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 517117395Skan (plus:DI (match_operand:DI 1 "register_operand" "r") 518117395Skan (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 519117395Skan UNSPEC_DTPREL)))] 520117395Skan "TARGET_TLS14" 521117395Skan "adds %0 = @dtprel(%2), %1" 522117395Skan [(set_attr "itanium_class" "ialu")]) 523117395Skan 524117395Skan(define_insn "*add_dtprel22" 525117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 526117395Skan (plus:DI (match_operand:DI 1 "register_operand" "a") 527117395Skan (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 528117395Skan UNSPEC_DTPREL)))] 529117395Skan "TARGET_TLS22" 530117395Skan "addl %0 = @dtprel(%2), %1" 531117395Skan [(set_attr "itanium_class" "ialu")]) 532117395Skan 533117395Skan(define_insn "load_ltoff_tprel" 534117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 535117395Skan (plus:DI (reg:DI 1) 536117395Skan (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 537117395Skan UNSPEC_LTOFF_TPREL)))] 538117395Skan "" 539117395Skan "addl %0 = @ltoff(@tprel(%1)), gp" 540117395Skan [(set_attr "itanium_class" "ialu")]) 541117395Skan 542117395Skan(define_expand "load_tprel" 543117395Skan [(set (match_operand:DI 0 "register_operand" "") 544117395Skan (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 545117395Skan UNSPEC_TPREL))] 546117395Skan "" 547117395Skan "") 548117395Skan 549117395Skan(define_insn "*load_tprel64" 550117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 551117395Skan (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 552117395Skan UNSPEC_TPREL))] 553117395Skan "TARGET_TLS64" 554117395Skan "movl %0 = @tprel(%1)" 555117395Skan [(set_attr "itanium_class" "long_i")]) 556117395Skan 557117395Skan(define_insn "*load_tprel22" 558117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 559117395Skan (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 560117395Skan UNSPEC_TPREL))] 561117395Skan "" 562117395Skan "addl %0 = @tprel(%1), r0" 563117395Skan [(set_attr "itanium_class" "ialu")]) 564117395Skan 565117395Skan(define_expand "add_tprel" 566117395Skan [(set (match_operand:DI 0 "register_operand" "") 567117395Skan (plus:DI (match_operand:DI 1 "register_operand" "") 568117395Skan (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 569117395Skan UNSPEC_TPREL)))] 570117395Skan "!TARGET_TLS64" 571117395Skan "") 572117395Skan 573117395Skan(define_insn "*add_tprel14" 574117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 575117395Skan (plus:DI (match_operand:DI 1 "register_operand" "r") 576117395Skan (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 577117395Skan UNSPEC_TPREL)))] 578117395Skan "TARGET_TLS14" 579117395Skan "adds %0 = @tprel(%2), %1" 580117395Skan [(set_attr "itanium_class" "ialu")]) 581117395Skan 582117395Skan(define_insn "*add_tprel22" 583117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 584117395Skan (plus:DI (match_operand:DI 1 "register_operand" "a") 585117395Skan (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 586117395Skan UNSPEC_TPREL)))] 587117395Skan "TARGET_TLS22" 588117395Skan "addl %0 = @tprel(%2), %1" 589117395Skan [(set_attr "itanium_class" "ialu")]) 590117395Skan 59190075Sobrien;; With no offsettable memory references, we've got to have a scratch 592132718Skan;; around to play with the second word. However, in order to avoid a 593132718Skan;; reload nightmare we lie, claim we don't need one, and fix it up 594132718Skan;; in ia64_split_tmode_move. 59590075Sobrien(define_expand "movti" 596132718Skan [(set (match_operand:TI 0 "general_operand" "") 597132718Skan (match_operand:TI 1 "general_operand" ""))] 59890075Sobrien "" 59990075Sobrien{ 600117395Skan rtx op1 = ia64_expand_move (operands[0], operands[1]); 601117395Skan if (!op1) 602117395Skan DONE; 603117395Skan operands[1] = op1; 604117395Skan}) 60590075Sobrien 60690075Sobrien(define_insn_and_split "*movti_internal" 60790075Sobrien [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m") 608132718Skan (match_operand:TI 1 "general_operand" "ri,m,r"))] 60990075Sobrien "ia64_move_ok (operands[0], operands[1])" 61090075Sobrien "#" 61190075Sobrien "reload_completed" 61290075Sobrien [(const_int 0)] 61390075Sobrien{ 614132718Skan ia64_split_tmode_move (operands); 61590075Sobrien DONE; 616117395Skan} 61790075Sobrien [(set_attr "itanium_class" "unknown") 61890075Sobrien (set_attr "predicable" "no")]) 61990075Sobrien 62090075Sobrien;; Floating Point Moves 62190075Sobrien;; 62290075Sobrien;; Note - Patterns for SF mode moves are compulsory, but 623117395Skan;; patterns for DF are optional, as GCC can synthesize them. 62490075Sobrien 62590075Sobrien(define_expand "movsf" 62690075Sobrien [(set (match_operand:SF 0 "general_operand" "") 62790075Sobrien (match_operand:SF 1 "general_operand" ""))] 62890075Sobrien "" 62990075Sobrien{ 630117395Skan rtx op1 = ia64_expand_move (operands[0], operands[1]); 631117395Skan if (!op1) 632117395Skan DONE; 633117395Skan operands[1] = op1; 634117395Skan}) 63590075Sobrien 63690075Sobrien(define_insn "*movsf_internal" 63790075Sobrien [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m") 63890075Sobrien (match_operand:SF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))] 63990075Sobrien "ia64_move_ok (operands[0], operands[1])" 64090075Sobrien "@ 641117395Skan mov %0 = %F1 642117395Skan ldfs %0 = %1%P1 643117395Skan stfs %0 = %F1%P0 644117395Skan getf.s %0 = %F1 645117395Skan setf.s %0 = %1 646117395Skan mov %0 = %1 647117395Skan ld4%O1 %0 = %1%P1 648117395Skan st4%Q0 %0 = %1%P0" 64990075Sobrien [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")]) 65090075Sobrien 65190075Sobrien(define_expand "movdf" 65290075Sobrien [(set (match_operand:DF 0 "general_operand" "") 65390075Sobrien (match_operand:DF 1 "general_operand" ""))] 65490075Sobrien "" 65590075Sobrien{ 656117395Skan rtx op1 = ia64_expand_move (operands[0], operands[1]); 657117395Skan if (!op1) 658117395Skan DONE; 659117395Skan operands[1] = op1; 660117395Skan}) 66190075Sobrien 66290075Sobrien(define_insn "*movdf_internal" 66390075Sobrien [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m") 66490075Sobrien (match_operand:DF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))] 66590075Sobrien "ia64_move_ok (operands[0], operands[1])" 66690075Sobrien "@ 667117395Skan mov %0 = %F1 668117395Skan ldfd %0 = %1%P1 669117395Skan stfd %0 = %F1%P0 670117395Skan getf.d %0 = %F1 671117395Skan setf.d %0 = %1 672117395Skan mov %0 = %1 673117395Skan ld8%O1 %0 = %1%P1 674117395Skan st8%Q0 %0 = %1%P0" 67590075Sobrien [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")]) 67690075Sobrien 67790075Sobrien;; With no offsettable memory references, we've got to have a scratch 67890075Sobrien;; around to play with the second word if the variable winds up in GRs. 679132718Skan(define_expand "movxf" 680132718Skan [(set (match_operand:XF 0 "general_operand" "") 681132718Skan (match_operand:XF 1 "general_operand" ""))] 682132718Skan "" 68390075Sobrien{ 684132718Skan /* We must support XFmode loads into general registers for stdarg/vararg 68590075Sobrien and unprototyped calls. We split them into DImode loads for convenience. 686132718Skan We don't need XFmode stores from general regs, because a stdarg/vararg 68790075Sobrien routine does a block store to memory of unnamed arguments. */ 68890075Sobrien if (GET_CODE (operands[0]) == REG 68990075Sobrien && GR_REGNO_P (REGNO (operands[0]))) 69090075Sobrien { 691132718Skan /* We're hoping to transform everything that deals with XFmode 69290075Sobrien quantities and GR registers early in the compiler. */ 69390075Sobrien if (no_new_pseudos) 69490075Sobrien abort (); 69590075Sobrien 69690075Sobrien /* Struct to register can just use TImode instead. */ 69790075Sobrien if ((GET_CODE (operands[1]) == SUBREG 69890075Sobrien && GET_MODE (SUBREG_REG (operands[1])) == TImode) 69990075Sobrien || (GET_CODE (operands[1]) == REG 70090075Sobrien && GR_REGNO_P (REGNO (operands[1])))) 70190075Sobrien { 70290075Sobrien emit_move_insn (gen_rtx_REG (TImode, REGNO (operands[0])), 70390075Sobrien SUBREG_REG (operands[1])); 70490075Sobrien DONE; 70590075Sobrien } 70690075Sobrien 70790075Sobrien if (GET_CODE (operands[1]) == CONST_DOUBLE) 70890075Sobrien { 70990075Sobrien emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0])), 710132718Skan operand_subword (operands[1], 0, 0, XFmode)); 71190075Sobrien emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0]) + 1), 712132718Skan operand_subword (operands[1], 1, 0, XFmode)); 71390075Sobrien DONE; 71490075Sobrien } 71590075Sobrien 71690075Sobrien /* If the quantity is in a register not known to be GR, spill it. */ 717132718Skan if (register_operand (operands[1], XFmode)) 718132718Skan operands[1] = spill_xfmode_operand (operands[1], 1); 71990075Sobrien 72090075Sobrien if (GET_CODE (operands[1]) == MEM) 72190075Sobrien { 72290075Sobrien rtx out[2]; 72390075Sobrien 72490075Sobrien out[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0])); 72590075Sobrien out[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0])+1); 72690075Sobrien 72790075Sobrien emit_move_insn (out[0], adjust_address (operands[1], DImode, 0)); 72890075Sobrien emit_move_insn (out[1], adjust_address (operands[1], DImode, 8)); 72990075Sobrien DONE; 73090075Sobrien } 73190075Sobrien 73290075Sobrien abort (); 73390075Sobrien } 73490075Sobrien 73590075Sobrien if (! reload_in_progress && ! reload_completed) 73690075Sobrien { 737132718Skan operands[0] = spill_xfmode_operand (operands[0], 0); 738132718Skan operands[1] = spill_xfmode_operand (operands[1], 0); 73990075Sobrien 74090075Sobrien if (! ia64_move_ok (operands[0], operands[1])) 741132718Skan operands[1] = force_reg (XFmode, operands[1]); 74290075Sobrien } 743117395Skan}) 74490075Sobrien 74590075Sobrien;; ??? There's no easy way to mind volatile acquire/release semantics. 74690075Sobrien 747132718Skan(define_insn "*movxf_internal" 748132718Skan [(set (match_operand:XF 0 "destination_xfmode_operand" "=f,f, m") 749132718Skan (match_operand:XF 1 "general_xfmode_operand" "fG,m,fG"))] 750132718Skan "ia64_move_ok (operands[0], operands[1])" 75190075Sobrien "@ 752117395Skan mov %0 = %F1 753117395Skan ldfe %0 = %1%P1 754117395Skan stfe %0 = %F1%P0" 75590075Sobrien [(set_attr "itanium_class" "fmisc,fld,stf")]) 756132718Skan 757132718Skan;; Better code generation via insns that deal with TFmode register pairs 758132718Skan;; directly. Same concerns apply as for TImode. 759132718Skan(define_expand "movtf" 760132718Skan [(set (match_operand:TF 0 "general_operand" "") 761132718Skan (match_operand:TF 1 "general_operand" ""))] 762132718Skan "" 763132718Skan{ 764132718Skan rtx op1 = ia64_expand_move (operands[0], operands[1]); 765132718Skan if (!op1) 766132718Skan DONE; 767132718Skan operands[1] = op1; 768132718Skan}) 769132718Skan 770132718Skan(define_insn_and_split "*movtf_internal" 771132718Skan [(set (match_operand:TF 0 "nonimmediate_operand" "=r,r,m") 772132718Skan (match_operand:TF 1 "general_operand" "ri,m,r"))] 773132718Skan "ia64_move_ok (operands[0], operands[1])" 774132718Skan "#" 775132718Skan "reload_completed" 776132718Skan [(const_int 0)] 777132718Skan{ 778132718Skan ia64_split_tmode_move (operands); 779132718Skan DONE; 780132718Skan} 781132718Skan [(set_attr "itanium_class" "unknown") 782132718Skan (set_attr "predicable" "no")]) 783132718Skan 78490075Sobrien 78590075Sobrien;; :::::::::::::::::::: 78690075Sobrien;; :: 78790075Sobrien;; :: Conversions 78890075Sobrien;; :: 78990075Sobrien;; :::::::::::::::::::: 79090075Sobrien 79190075Sobrien;; Signed conversions from a smaller integer to a larger integer 79290075Sobrien 79390075Sobrien(define_insn "extendqidi2" 79490075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 79590075Sobrien (sign_extend:DI (match_operand:QI 1 "gr_register_operand" "r")))] 79690075Sobrien "" 79790075Sobrien "sxt1 %0 = %1" 79890075Sobrien [(set_attr "itanium_class" "xtd")]) 79990075Sobrien 80090075Sobrien(define_insn "extendhidi2" 80190075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 80290075Sobrien (sign_extend:DI (match_operand:HI 1 "gr_register_operand" "r")))] 80390075Sobrien "" 80490075Sobrien "sxt2 %0 = %1" 80590075Sobrien [(set_attr "itanium_class" "xtd")]) 80690075Sobrien 80790075Sobrien(define_insn "extendsidi2" 80890075Sobrien [(set (match_operand:DI 0 "grfr_register_operand" "=r,?f") 80990075Sobrien (sign_extend:DI (match_operand:SI 1 "grfr_register_operand" "r,f")))] 81090075Sobrien "" 81190075Sobrien "@ 81290075Sobrien sxt4 %0 = %1 81390075Sobrien fsxt.r %0 = %1, %1" 81490075Sobrien [(set_attr "itanium_class" "xtd,fmisc")]) 81590075Sobrien 81690075Sobrien;; Unsigned conversions from a smaller integer to a larger integer 81790075Sobrien 81890075Sobrien(define_insn "zero_extendqidi2" 81990075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r,r") 82090075Sobrien (zero_extend:DI (match_operand:QI 1 "gr_nonimmediate_operand" "r,m")))] 82190075Sobrien "" 82290075Sobrien "@ 82390075Sobrien zxt1 %0 = %1 82490075Sobrien ld1%O1 %0 = %1%P1" 82590075Sobrien [(set_attr "itanium_class" "xtd,ld")]) 82690075Sobrien 82790075Sobrien(define_insn "zero_extendhidi2" 82890075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r,r") 82990075Sobrien (zero_extend:DI (match_operand:HI 1 "gr_nonimmediate_operand" "r,m")))] 83090075Sobrien "" 83190075Sobrien "@ 83290075Sobrien zxt2 %0 = %1 83390075Sobrien ld2%O1 %0 = %1%P1" 83490075Sobrien [(set_attr "itanium_class" "xtd,ld")]) 83590075Sobrien 83690075Sobrien(define_insn "zero_extendsidi2" 83790075Sobrien [(set (match_operand:DI 0 "grfr_register_operand" "=r,r,?f") 83890075Sobrien (zero_extend:DI 83990075Sobrien (match_operand:SI 1 "grfr_nonimmediate_operand" "r,m,f")))] 84090075Sobrien "" 84190075Sobrien "@ 84290075Sobrien zxt4 %0 = %1 84390075Sobrien ld4%O1 %0 = %1%P1 84490075Sobrien fmix.r %0 = f0, %1" 84590075Sobrien [(set_attr "itanium_class" "xtd,ld,fmisc")]) 84690075Sobrien 84790075Sobrien;; Convert between floating point types of different sizes. 84890075Sobrien 84990075Sobrien;; At first glance, it would appear that emitting fnorm for an extending 85090075Sobrien;; conversion is unnecessary. However, the stf and getf instructions work 85190075Sobrien;; correctly only if the input is properly rounded for its type. In 85290075Sobrien;; particular, we get the wrong result for getf.d/stfd if the input is a 85390075Sobrien;; denorm single. Since we don't know what the next instruction will be, we 85490075Sobrien;; have to emit an fnorm. 85590075Sobrien 85690075Sobrien;; ??? Optimization opportunity here. Get rid of the insn altogether 85790075Sobrien;; when we can. Should probably use a scheme like has been proposed 85890075Sobrien;; for ia32 in dealing with operands that match unary operators. This 85990075Sobrien;; would let combine merge the thing into adjacent insns. See also how the 86090075Sobrien;; mips port handles SIGN_EXTEND as operands to integer arithmetic insns via 86190075Sobrien;; se_register_operand. 86290075Sobrien 86390075Sobrien(define_insn "extendsfdf2" 86490075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 86590075Sobrien (float_extend:DF (match_operand:SF 1 "fr_register_operand" "f")))] 86690075Sobrien "" 86790075Sobrien "fnorm.d %0 = %1" 86890075Sobrien [(set_attr "itanium_class" "fmac")]) 86990075Sobrien 870132718Skan(define_insn "extendsfxf2" 871132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 872132718Skan (float_extend:XF (match_operand:SF 1 "fr_register_operand" "f")))] 873132718Skan "" 87490075Sobrien "fnorm %0 = %1" 87590075Sobrien [(set_attr "itanium_class" "fmac")]) 87690075Sobrien 877132718Skan(define_insn "extenddfxf2" 878132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 879132718Skan (float_extend:XF (match_operand:DF 1 "fr_register_operand" "f")))] 880132718Skan "" 88190075Sobrien "fnorm %0 = %1" 88290075Sobrien [(set_attr "itanium_class" "fmac")]) 88390075Sobrien 88490075Sobrien(define_insn "truncdfsf2" 88590075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 88690075Sobrien (float_truncate:SF (match_operand:DF 1 "fr_register_operand" "f")))] 88790075Sobrien "" 88890075Sobrien "fnorm.s %0 = %1" 88990075Sobrien [(set_attr "itanium_class" "fmac")]) 89090075Sobrien 891132718Skan(define_insn "truncxfsf2" 89290075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 893132718Skan (float_truncate:SF (match_operand:XF 1 "fr_register_operand" "f")))] 894132718Skan "" 89590075Sobrien "fnorm.s %0 = %1" 89690075Sobrien [(set_attr "itanium_class" "fmac")]) 89790075Sobrien 898132718Skan(define_insn "truncxfdf2" 89990075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 900132718Skan (float_truncate:DF (match_operand:XF 1 "fr_register_operand" "f")))] 901132718Skan "" 90290075Sobrien "fnorm.d %0 = %1" 90390075Sobrien [(set_attr "itanium_class" "fmac")]) 90490075Sobrien 90590075Sobrien;; Convert between signed integer types and floating point. 90690075Sobrien 907132718Skan(define_insn "floatdixf2" 908132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 909132718Skan (float:XF (match_operand:DI 1 "fr_register_operand" "f")))] 910132718Skan "" 91190075Sobrien "fcvt.xf %0 = %1" 91290075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 91390075Sobrien 91490075Sobrien(define_insn "fix_truncsfdi2" 91590075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 91690075Sobrien (fix:DI (match_operand:SF 1 "fr_register_operand" "f")))] 91790075Sobrien "" 91890075Sobrien "fcvt.fx.trunc %0 = %1" 91990075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 92090075Sobrien 92190075Sobrien(define_insn "fix_truncdfdi2" 92290075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 92390075Sobrien (fix:DI (match_operand:DF 1 "fr_register_operand" "f")))] 92490075Sobrien "" 92590075Sobrien "fcvt.fx.trunc %0 = %1" 92690075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 92790075Sobrien 928132718Skan(define_insn "fix_truncxfdi2" 92990075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 930132718Skan (fix:DI (match_operand:XF 1 "fr_register_operand" "f")))] 931132718Skan "" 93290075Sobrien "fcvt.fx.trunc %0 = %1" 93390075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 93490075Sobrien 935132718Skan(define_insn "fix_truncxfdi2_alts" 93690075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 937132718Skan (fix:DI (match_operand:XF 1 "fr_register_operand" "f"))) 93890075Sobrien (use (match_operand:SI 2 "const_int_operand" ""))] 939132718Skan "" 94090075Sobrien "fcvt.fx.trunc.s%2 %0 = %1" 94190075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 94290075Sobrien 94390075Sobrien;; Convert between unsigned integer types and floating point. 94490075Sobrien 94590075Sobrien(define_insn "floatunsdisf2" 94690075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 94790075Sobrien (unsigned_float:SF (match_operand:DI 1 "fr_register_operand" "f")))] 94890075Sobrien "" 94990075Sobrien "fcvt.xuf.s %0 = %1" 95090075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 95190075Sobrien 95290075Sobrien(define_insn "floatunsdidf2" 95390075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 95490075Sobrien (unsigned_float:DF (match_operand:DI 1 "fr_register_operand" "f")))] 95590075Sobrien "" 95690075Sobrien "fcvt.xuf.d %0 = %1" 95790075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 95890075Sobrien 959132718Skan(define_insn "floatunsdixf2" 960132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 961132718Skan (unsigned_float:XF (match_operand:DI 1 "fr_register_operand" "f")))] 962132718Skan "" 96390075Sobrien "fcvt.xuf %0 = %1" 96490075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 96590075Sobrien 96690075Sobrien(define_insn "fixuns_truncsfdi2" 96790075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 96890075Sobrien (unsigned_fix:DI (match_operand:SF 1 "fr_register_operand" "f")))] 96990075Sobrien "" 97090075Sobrien "fcvt.fxu.trunc %0 = %1" 97190075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 97290075Sobrien 97390075Sobrien(define_insn "fixuns_truncdfdi2" 97490075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 97590075Sobrien (unsigned_fix:DI (match_operand:DF 1 "fr_register_operand" "f")))] 97690075Sobrien "" 97790075Sobrien "fcvt.fxu.trunc %0 = %1" 97890075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 97990075Sobrien 980132718Skan(define_insn "fixuns_truncxfdi2" 98190075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 982132718Skan (unsigned_fix:DI (match_operand:XF 1 "fr_register_operand" "f")))] 983132718Skan "" 98490075Sobrien "fcvt.fxu.trunc %0 = %1" 98590075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 98690075Sobrien 987132718Skan(define_insn "fixuns_truncxfdi2_alts" 98890075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 989132718Skan (unsigned_fix:DI (match_operand:XF 1 "fr_register_operand" "f"))) 99090075Sobrien (use (match_operand:SI 2 "const_int_operand" ""))] 991132718Skan "" 99290075Sobrien "fcvt.fxu.trunc.s%2 %0 = %1" 99390075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 99490075Sobrien 99590075Sobrien;; :::::::::::::::::::: 99690075Sobrien;; :: 99790075Sobrien;; :: Bit field extraction 99890075Sobrien;; :: 99990075Sobrien;; :::::::::::::::::::: 100090075Sobrien 100190075Sobrien(define_insn "extv" 100290075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 100390075Sobrien (sign_extract:DI (match_operand:DI 1 "gr_register_operand" "r") 100490075Sobrien (match_operand:DI 2 "const_int_operand" "n") 100590075Sobrien (match_operand:DI 3 "const_int_operand" "n")))] 100690075Sobrien "" 100790075Sobrien "extr %0 = %1, %3, %2" 100890075Sobrien [(set_attr "itanium_class" "ishf")]) 100990075Sobrien 101090075Sobrien(define_insn "extzv" 101190075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 101290075Sobrien (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r") 101390075Sobrien (match_operand:DI 2 "const_int_operand" "n") 101490075Sobrien (match_operand:DI 3 "const_int_operand" "n")))] 101590075Sobrien "" 101690075Sobrien "extr.u %0 = %1, %3, %2" 101790075Sobrien [(set_attr "itanium_class" "ishf")]) 101890075Sobrien 101990075Sobrien;; Insert a bit field. 102090075Sobrien;; Can have 3 operands, source1 (inserter), source2 (insertee), dest. 102190075Sobrien;; Source1 can be 0 or -1. 102290075Sobrien;; Source2 can be 0. 102390075Sobrien 102490075Sobrien;; ??? Actual dep instruction is more powerful than what these insv 102590075Sobrien;; patterns support. Unfortunately, combine is unable to create patterns 102690075Sobrien;; where source2 != dest. 102790075Sobrien 102890075Sobrien(define_expand "insv" 102990075Sobrien [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "") 103090075Sobrien (match_operand:DI 1 "const_int_operand" "") 103190075Sobrien (match_operand:DI 2 "const_int_operand" "")) 103290075Sobrien (match_operand:DI 3 "nonmemory_operand" ""))] 103390075Sobrien "" 103490075Sobrien{ 103590075Sobrien int width = INTVAL (operands[1]); 103690075Sobrien int shift = INTVAL (operands[2]); 103790075Sobrien 103890075Sobrien /* If operand[3] is a constant, and isn't 0 or -1, then load it into a 103990075Sobrien pseudo. */ 104090075Sobrien if (! register_operand (operands[3], DImode) 104190075Sobrien && operands[3] != const0_rtx && operands[3] != constm1_rtx) 104290075Sobrien operands[3] = force_reg (DImode, operands[3]); 104390075Sobrien 104490075Sobrien /* If this is a single dep instruction, we have nothing to do. */ 104590075Sobrien if (! ((register_operand (operands[3], DImode) && width <= 16) 104690075Sobrien || operands[3] == const0_rtx || operands[3] == constm1_rtx)) 104790075Sobrien { 104890075Sobrien /* Check for cases that can be implemented with a mix instruction. */ 104990075Sobrien if (width == 32 && shift == 0) 105090075Sobrien { 105190075Sobrien /* Directly generating the mix4left instruction confuses 105290075Sobrien optimize_bit_field in function.c. Since this is performing 105390075Sobrien a useful optimization, we defer generation of the complicated 105490075Sobrien mix4left RTL to the first splitting phase. */ 105590075Sobrien rtx tmp = gen_reg_rtx (DImode); 105690075Sobrien emit_insn (gen_shift_mix4left (operands[0], operands[3], tmp)); 105790075Sobrien DONE; 105890075Sobrien } 105990075Sobrien else if (width == 32 && shift == 32) 106090075Sobrien { 106190075Sobrien emit_insn (gen_mix4right (operands[0], operands[3])); 106290075Sobrien DONE; 106390075Sobrien } 106490075Sobrien 106590075Sobrien /* We could handle remaining cases by emitting multiple dep 106690075Sobrien instructions. 106790075Sobrien 106890075Sobrien If we need more than two dep instructions then we lose. A 6 106990075Sobrien insn sequence mov mask1,mov mask2,shl;;and,and;;or is better than 107090075Sobrien mov;;dep,shr;;dep,shr;;dep. The former can be executed in 3 cycles, 107190075Sobrien the latter is 6 cycles on an Itanium (TM) processor, because there is 107290075Sobrien only one function unit that can execute dep and shr immed. 107390075Sobrien 107490075Sobrien If we only need two dep instruction, then we still lose. 107590075Sobrien mov;;dep,shr;;dep is still 4 cycles. Even if we optimize away 107690075Sobrien the unnecessary mov, this is still undesirable because it will be 107790075Sobrien hard to optimize, and it creates unnecessary pressure on the I0 107890075Sobrien function unit. */ 107990075Sobrien 108090075Sobrien FAIL; 108190075Sobrien 108290075Sobrien#if 0 108390075Sobrien /* This code may be useful for other IA-64 processors, so we leave it in 108490075Sobrien for now. */ 108590075Sobrien while (width > 16) 108690075Sobrien { 108790075Sobrien rtx tmp; 108890075Sobrien 108990075Sobrien emit_insn (gen_insv (operands[0], GEN_INT (16), GEN_INT (shift), 109090075Sobrien operands[3])); 109190075Sobrien shift += 16; 109290075Sobrien width -= 16; 109390075Sobrien tmp = gen_reg_rtx (DImode); 109490075Sobrien emit_insn (gen_lshrdi3 (tmp, operands[3], GEN_INT (16))); 109590075Sobrien operands[3] = tmp; 109690075Sobrien } 109790075Sobrien operands[1] = GEN_INT (width); 109890075Sobrien operands[2] = GEN_INT (shift); 109990075Sobrien#endif 110090075Sobrien } 1101117395Skan}) 110290075Sobrien 110390075Sobrien(define_insn "*insv_internal" 110490075Sobrien [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r") 110590075Sobrien (match_operand:DI 1 "const_int_operand" "n") 110690075Sobrien (match_operand:DI 2 "const_int_operand" "n")) 110790075Sobrien (match_operand:DI 3 "nonmemory_operand" "rP"))] 110890075Sobrien "(gr_register_operand (operands[3], DImode) && INTVAL (operands[1]) <= 16) 110990075Sobrien || operands[3] == const0_rtx || operands[3] == constm1_rtx" 111090075Sobrien "dep %0 = %3, %0, %2, %1" 111190075Sobrien [(set_attr "itanium_class" "ishf")]) 111290075Sobrien 1113117395Skan;; Combine doesn't like to create bit-field insertions into zero. 111490075Sobrien(define_insn "*depz_internal" 111590075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 111690075Sobrien (and:DI (ashift:DI (match_operand:DI 1 "gr_register_operand" "r") 111790075Sobrien (match_operand:DI 2 "const_int_operand" "n")) 111890075Sobrien (match_operand:DI 3 "const_int_operand" "n")))] 111990075Sobrien "CONST_OK_FOR_M (INTVAL (operands[2])) 112090075Sobrien && ia64_depz_field_mask (operands[3], operands[2]) > 0" 112190075Sobrien{ 112290075Sobrien operands[3] = GEN_INT (ia64_depz_field_mask (operands[3], operands[2])); 1123117395Skan return "%,dep.z %0 = %1, %2, %3"; 1124117395Skan} 112590075Sobrien [(set_attr "itanium_class" "ishf")]) 112690075Sobrien 112790075Sobrien(define_insn "shift_mix4left" 112890075Sobrien [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r") 112990075Sobrien (const_int 32) (const_int 0)) 113090075Sobrien (match_operand:DI 1 "gr_register_operand" "r")) 113190075Sobrien (clobber (match_operand:DI 2 "gr_register_operand" "=r"))] 113290075Sobrien "" 113390075Sobrien "#" 113490075Sobrien [(set_attr "itanium_class" "unknown")]) 113590075Sobrien 113690075Sobrien(define_split 113790075Sobrien [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "") 113890075Sobrien (const_int 32) (const_int 0)) 113990075Sobrien (match_operand:DI 1 "register_operand" "")) 114090075Sobrien (clobber (match_operand:DI 2 "register_operand" ""))] 114190075Sobrien "reload_completed" 114290075Sobrien [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32))) 114390075Sobrien (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0)) 114490075Sobrien (lshiftrt:DI (match_dup 3) (const_int 32)))] 114590075Sobrien "operands[3] = operands[2];") 114690075Sobrien 114790075Sobrien(define_split 114890075Sobrien [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "") 114990075Sobrien (const_int 32) (const_int 0)) 115090075Sobrien (match_operand:DI 1 "register_operand" "")) 115190075Sobrien (clobber (match_operand:DI 2 "register_operand" ""))] 115290075Sobrien "! reload_completed" 115390075Sobrien [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32))) 115490075Sobrien (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0)) 115590075Sobrien (lshiftrt:DI (match_dup 3) (const_int 32)))] 115690075Sobrien "operands[3] = operands[2];") 115790075Sobrien 115890075Sobrien(define_insn "*mix4left" 115990075Sobrien [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r") 116090075Sobrien (const_int 32) (const_int 0)) 116190075Sobrien (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r") 116290075Sobrien (const_int 32)))] 116390075Sobrien "" 116490075Sobrien "mix4.l %0 = %0, %r1" 116590075Sobrien [(set_attr "itanium_class" "mmshf")]) 116690075Sobrien 116790075Sobrien(define_insn "mix4right" 116890075Sobrien [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r") 116990075Sobrien (const_int 32) (const_int 32)) 117090075Sobrien (match_operand:DI 1 "gr_reg_or_0_operand" "rO"))] 117190075Sobrien "" 117290075Sobrien "mix4.r %0 = %r1, %0" 117390075Sobrien [(set_attr "itanium_class" "mmshf")]) 117490075Sobrien 117590075Sobrien;; This is used by the rotrsi3 pattern. 117690075Sobrien 117790075Sobrien(define_insn "*mix4right_3op" 117890075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 117990075Sobrien (ior:DI (zero_extend:DI (match_operand:SI 1 "gr_register_operand" "r")) 118090075Sobrien (ashift:DI (zero_extend:DI 118190075Sobrien (match_operand:SI 2 "gr_register_operand" "r")) 118290075Sobrien (const_int 32))))] 118390075Sobrien "" 118490075Sobrien "mix4.r %0 = %2, %1" 118590075Sobrien [(set_attr "itanium_class" "mmshf")]) 118690075Sobrien 118790075Sobrien 118890075Sobrien;; :::::::::::::::::::: 118990075Sobrien;; :: 119090075Sobrien;; :: 1 bit Integer arithmetic 119190075Sobrien;; :: 119290075Sobrien;; :::::::::::::::::::: 119390075Sobrien 119490075Sobrien(define_insn_and_split "andbi3" 119590075Sobrien [(set (match_operand:BI 0 "register_operand" "=c,c,r") 119690075Sobrien (and:BI (match_operand:BI 1 "register_operand" "%0,0,r") 119790075Sobrien (match_operand:BI 2 "register_operand" "c,r,r")))] 119890075Sobrien "" 119990075Sobrien "@ 120090075Sobrien # 120190075Sobrien tbit.nz.and.orcm %0, %I0 = %2, 0 120290075Sobrien and %0 = %2, %1" 120390075Sobrien "reload_completed 120490075Sobrien && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0])) 120590075Sobrien && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))" 120690075Sobrien [(cond_exec (eq (match_dup 2) (const_int 0)) 120790075Sobrien (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0)) 120890075Sobrien (match_dup 0))))] 120990075Sobrien "" 121090075Sobrien [(set_attr "itanium_class" "unknown,tbit,ilog")]) 121190075Sobrien 121290075Sobrien(define_insn_and_split "*andcmbi3" 121390075Sobrien [(set (match_operand:BI 0 "register_operand" "=c,c,r") 121490075Sobrien (and:BI (not:BI (match_operand:BI 1 "register_operand" "c,r,r")) 121590075Sobrien (match_operand:BI 2 "register_operand" "0,0,r")))] 121690075Sobrien "" 121790075Sobrien "@ 121890075Sobrien # 121990075Sobrien tbit.z.and.orcm %0, %I0 = %1, 0 122090075Sobrien andcm %0 = %2, %1" 122190075Sobrien "reload_completed 122290075Sobrien && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0])) 122390075Sobrien && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))" 122490075Sobrien [(cond_exec (ne (match_dup 1) (const_int 0)) 122590075Sobrien (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0)) 122690075Sobrien (match_dup 0))))] 122790075Sobrien "" 122890075Sobrien [(set_attr "itanium_class" "unknown,tbit,ilog")]) 122990075Sobrien 123090075Sobrien(define_insn_and_split "iorbi3" 123190075Sobrien [(set (match_operand:BI 0 "register_operand" "=c,c,r") 123290075Sobrien (ior:BI (match_operand:BI 1 "register_operand" "%0,0,r") 123390075Sobrien (match_operand:BI 2 "register_operand" "c,r,r")))] 123490075Sobrien "" 123590075Sobrien "@ 123690075Sobrien # 123790075Sobrien tbit.nz.or.andcm %0, %I0 = %2, 0 123890075Sobrien or %0 = %2, %1" 123990075Sobrien "reload_completed 124090075Sobrien && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0])) 124190075Sobrien && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))" 124290075Sobrien [(cond_exec (ne (match_dup 2) (const_int 0)) 124390075Sobrien (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0)) 124490075Sobrien (match_dup 0))))] 124590075Sobrien "" 124690075Sobrien [(set_attr "itanium_class" "unknown,tbit,ilog")]) 124790075Sobrien 124890075Sobrien(define_insn_and_split "*iorcmbi3" 124990075Sobrien [(set (match_operand:BI 0 "register_operand" "=c,c") 125090075Sobrien (ior:BI (not:BI (match_operand:BI 1 "register_operand" "c,r")) 125190075Sobrien (match_operand:BI 2 "register_operand" "0,0")))] 125290075Sobrien "" 125390075Sobrien "@ 125490075Sobrien # 125590075Sobrien tbit.z.or.andcm %0, %I0 = %1, 0" 125690075Sobrien "reload_completed 125790075Sobrien && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0])) 125890075Sobrien && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))" 125990075Sobrien [(cond_exec (eq (match_dup 1) (const_int 0)) 126090075Sobrien (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0)) 126190075Sobrien (match_dup 0))))] 126290075Sobrien "" 126390075Sobrien [(set_attr "itanium_class" "unknown,tbit")]) 126490075Sobrien 126590075Sobrien(define_insn "one_cmplbi2" 126690075Sobrien [(set (match_operand:BI 0 "register_operand" "=c,r,c,&c") 126790075Sobrien (not:BI (match_operand:BI 1 "register_operand" "r,r,0,c"))) 126890075Sobrien (clobber (match_scratch:BI 2 "=X,X,c,X"))] 126990075Sobrien "" 127090075Sobrien "@ 127190075Sobrien tbit.z %0, %I0 = %1, 0 127290075Sobrien xor %0 = 1, %1 127390075Sobrien # 127490075Sobrien #" 127590075Sobrien [(set_attr "itanium_class" "tbit,ilog,unknown,unknown")]) 127690075Sobrien 127790075Sobrien(define_split 127890075Sobrien [(set (match_operand:BI 0 "register_operand" "") 127990075Sobrien (not:BI (match_operand:BI 1 "register_operand" ""))) 128090075Sobrien (clobber (match_scratch:BI 2 ""))] 128190075Sobrien "reload_completed 128290075Sobrien && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0])) 128390075Sobrien && rtx_equal_p (operands[0], operands[1])" 128490075Sobrien [(set (match_dup 4) (match_dup 3)) 128590075Sobrien (set (match_dup 0) (const_int 1)) 128690075Sobrien (cond_exec (ne (match_dup 2) (const_int 0)) 128790075Sobrien (set (match_dup 0) (const_int 0))) 1288117395Skan (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))] 128990075Sobrien "operands[3] = gen_rtx_REG (CCImode, REGNO (operands[1])); 129090075Sobrien operands[4] = gen_rtx_REG (CCImode, REGNO (operands[2]));") 129190075Sobrien 129290075Sobrien(define_split 129390075Sobrien [(set (match_operand:BI 0 "register_operand" "") 129490075Sobrien (not:BI (match_operand:BI 1 "register_operand" ""))) 129590075Sobrien (clobber (match_scratch:BI 2 ""))] 129690075Sobrien "reload_completed 129790075Sobrien && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0])) 129890075Sobrien && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1])) 129990075Sobrien && ! rtx_equal_p (operands[0], operands[1])" 130090075Sobrien [(cond_exec (ne (match_dup 1) (const_int 0)) 130190075Sobrien (set (match_dup 0) (const_int 0))) 130290075Sobrien (cond_exec (eq (match_dup 1) (const_int 0)) 130390075Sobrien (set (match_dup 0) (const_int 1))) 1304117395Skan (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))] 130590075Sobrien "") 130690075Sobrien 130790075Sobrien(define_insn "*cmpsi_and_0" 130890075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 130990075Sobrien (and:BI (match_operator:BI 4 "predicate_operator" 131090075Sobrien [(match_operand:SI 2 "gr_reg_or_0_operand" "rO") 131190075Sobrien (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]) 131290075Sobrien (match_operand:BI 1 "register_operand" "0")))] 131390075Sobrien "" 131490075Sobrien "cmp4.%C4.and.orcm %0, %I0 = %3, %r2" 131590075Sobrien [(set_attr "itanium_class" "icmp")]) 131690075Sobrien 131790075Sobrien(define_insn "*cmpsi_and_1" 131890075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 131990075Sobrien (and:BI (match_operator:BI 3 "signed_inequality_operator" 132090075Sobrien [(match_operand:SI 2 "gr_register_operand" "r") 132190075Sobrien (const_int 0)]) 132290075Sobrien (match_operand:BI 1 "register_operand" "0")))] 132390075Sobrien "" 132490075Sobrien "cmp4.%C3.and.orcm %0, %I0 = r0, %2" 132590075Sobrien [(set_attr "itanium_class" "icmp")]) 132690075Sobrien 132790075Sobrien(define_insn "*cmpsi_andnot_0" 132890075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 132990075Sobrien (and:BI (not:BI (match_operator:BI 4 "predicate_operator" 133090075Sobrien [(match_operand:SI 2 "gr_reg_or_0_operand" "rO") 133190075Sobrien (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])) 133290075Sobrien (match_operand:BI 1 "register_operand" "0")))] 133390075Sobrien "" 133490075Sobrien "cmp4.%C4.or.andcm %I0, %0 = %3, %r2" 133590075Sobrien [(set_attr "itanium_class" "icmp")]) 133690075Sobrien 133790075Sobrien(define_insn "*cmpsi_andnot_1" 133890075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 133990075Sobrien (and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator" 134090075Sobrien [(match_operand:SI 2 "gr_register_operand" "r") 134190075Sobrien (const_int 0)])) 134290075Sobrien (match_operand:BI 1 "register_operand" "0")))] 134390075Sobrien "" 134490075Sobrien "cmp4.%C3.or.andcm %I0, %0 = r0, %2" 134590075Sobrien [(set_attr "itanium_class" "icmp")]) 134690075Sobrien 134790075Sobrien(define_insn "*cmpdi_and_0" 134890075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 134990075Sobrien (and:BI (match_operator:BI 4 "predicate_operator" 135090075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 135190075Sobrien (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]) 135290075Sobrien (match_operand:BI 1 "register_operand" "0")))] 135390075Sobrien "" 135490075Sobrien "cmp.%C4.and.orcm %0, %I0 = %3, %2" 135590075Sobrien [(set_attr "itanium_class" "icmp")]) 135690075Sobrien 135790075Sobrien(define_insn "*cmpdi_and_1" 135890075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 135990075Sobrien (and:BI (match_operator:BI 3 "signed_inequality_operator" 136090075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 136190075Sobrien (const_int 0)]) 136290075Sobrien (match_operand:BI 1 "register_operand" "0")))] 136390075Sobrien "" 136490075Sobrien "cmp.%C3.and.orcm %0, %I0 = r0, %2" 136590075Sobrien [(set_attr "itanium_class" "icmp")]) 136690075Sobrien 136790075Sobrien(define_insn "*cmpdi_andnot_0" 136890075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 136990075Sobrien (and:BI (not:BI (match_operator:BI 4 "predicate_operator" 137090075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 137190075Sobrien (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])) 137290075Sobrien (match_operand:BI 1 "register_operand" "0")))] 137390075Sobrien "" 137490075Sobrien "cmp.%C4.or.andcm %I0, %0 = %3, %2" 137590075Sobrien [(set_attr "itanium_class" "icmp")]) 137690075Sobrien 137790075Sobrien(define_insn "*cmpdi_andnot_1" 137890075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 137990075Sobrien (and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator" 138090075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 138190075Sobrien (const_int 0)])) 138290075Sobrien (match_operand:BI 1 "register_operand" "0")))] 138390075Sobrien "" 138490075Sobrien "cmp.%C3.or.andcm %I0, %0 = r0, %2" 138590075Sobrien [(set_attr "itanium_class" "icmp")]) 138690075Sobrien 138790075Sobrien(define_insn "*tbit_and_0" 138890075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 138990075Sobrien (and:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r") 139090075Sobrien (const_int 1)) 139190075Sobrien (const_int 0)) 139290075Sobrien (match_operand:BI 2 "register_operand" "0")))] 139390075Sobrien "" 139490075Sobrien "tbit.nz.and.orcm %0, %I0 = %1, 0" 139590075Sobrien [(set_attr "itanium_class" "tbit")]) 139690075Sobrien 139790075Sobrien(define_insn "*tbit_and_1" 139890075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 139990075Sobrien (and:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r") 140090075Sobrien (const_int 1)) 140190075Sobrien (const_int 0)) 140290075Sobrien (match_operand:BI 2 "register_operand" "0")))] 140390075Sobrien "" 140490075Sobrien "tbit.z.and.orcm %0, %I0 = %1, 0" 140590075Sobrien [(set_attr "itanium_class" "tbit")]) 140690075Sobrien 140790075Sobrien(define_insn "*tbit_and_2" 140890075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 140990075Sobrien (and:BI (ne:BI (zero_extract:DI 141090075Sobrien (match_operand:DI 1 "gr_register_operand" "r") 141190075Sobrien (const_int 1) 141290075Sobrien (match_operand:DI 2 "const_int_operand" "n")) 141390075Sobrien (const_int 0)) 141490075Sobrien (match_operand:BI 3 "register_operand" "0")))] 141590075Sobrien "" 141690075Sobrien "tbit.nz.and.orcm %0, %I0 = %1, %2" 141790075Sobrien [(set_attr "itanium_class" "tbit")]) 141890075Sobrien 141990075Sobrien(define_insn "*tbit_and_3" 142090075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 142190075Sobrien (and:BI (eq:BI (zero_extract:DI 142290075Sobrien (match_operand:DI 1 "gr_register_operand" "r") 142390075Sobrien (const_int 1) 142490075Sobrien (match_operand:DI 2 "const_int_operand" "n")) 142590075Sobrien (const_int 0)) 142690075Sobrien (match_operand:BI 3 "register_operand" "0")))] 142790075Sobrien "" 142890075Sobrien "tbit.z.and.orcm %0, %I0 = %1, %2" 142990075Sobrien [(set_attr "itanium_class" "tbit")]) 143090075Sobrien 143190075Sobrien(define_insn "*cmpsi_or_0" 143290075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 143390075Sobrien (ior:BI (match_operator:BI 4 "predicate_operator" 143490075Sobrien [(match_operand:SI 2 "gr_reg_or_0_operand" "rO") 143590075Sobrien (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]) 143690075Sobrien (match_operand:BI 1 "register_operand" "0")))] 143790075Sobrien "" 143890075Sobrien "cmp4.%C4.or.andcm %0, %I0 = %3, %r2" 143990075Sobrien [(set_attr "itanium_class" "icmp")]) 144090075Sobrien 144190075Sobrien(define_insn "*cmpsi_or_1" 144290075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 144390075Sobrien (ior:BI (match_operator:BI 3 "signed_inequality_operator" 144490075Sobrien [(match_operand:SI 2 "gr_register_operand" "r") 144590075Sobrien (const_int 0)]) 144690075Sobrien (match_operand:BI 1 "register_operand" "0")))] 144790075Sobrien "" 144890075Sobrien "cmp4.%C3.or.andcm %0, %I0 = r0, %2" 144990075Sobrien [(set_attr "itanium_class" "icmp")]) 145090075Sobrien 145190075Sobrien(define_insn "*cmpsi_orcm_0" 145290075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 145390075Sobrien (ior:BI (not:BI (match_operator:BI 4 "predicate_operator" 145490075Sobrien [(match_operand:SI 2 "gr_reg_or_0_operand" "rO") 145590075Sobrien (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])) 145690075Sobrien (match_operand:BI 1 "register_operand" "0")))] 145790075Sobrien "" 145890075Sobrien "cmp4.%C4.and.orcm %I0, %0 = %3, %r2" 145990075Sobrien [(set_attr "itanium_class" "icmp")]) 146090075Sobrien 146190075Sobrien(define_insn "*cmpsi_orcm_1" 146290075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 146390075Sobrien (ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator" 146490075Sobrien [(match_operand:SI 2 "gr_register_operand" "r") 146590075Sobrien (const_int 0)])) 146690075Sobrien (match_operand:BI 1 "register_operand" "0")))] 146790075Sobrien "" 146890075Sobrien "cmp4.%C3.and.orcm %I0, %0 = r0, %2" 146990075Sobrien [(set_attr "itanium_class" "icmp")]) 147090075Sobrien 147190075Sobrien(define_insn "*cmpdi_or_0" 147290075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 147390075Sobrien (ior:BI (match_operator:BI 4 "predicate_operator" 147490075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 147590075Sobrien (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]) 147690075Sobrien (match_operand:BI 1 "register_operand" "0")))] 147790075Sobrien "" 147890075Sobrien "cmp.%C4.or.andcm %0, %I0 = %3, %2" 147990075Sobrien [(set_attr "itanium_class" "icmp")]) 148090075Sobrien 148190075Sobrien(define_insn "*cmpdi_or_1" 148290075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 148390075Sobrien (ior:BI (match_operator:BI 3 "signed_inequality_operator" 148490075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 148590075Sobrien (const_int 0)]) 148690075Sobrien (match_operand:BI 1 "register_operand" "0")))] 148790075Sobrien "" 148890075Sobrien "cmp.%C3.or.andcm %0, %I0 = r0, %2" 148990075Sobrien [(set_attr "itanium_class" "icmp")]) 149090075Sobrien 149190075Sobrien(define_insn "*cmpdi_orcm_0" 149290075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 149390075Sobrien (ior:BI (not:BI (match_operator:BI 4 "predicate_operator" 149490075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 149590075Sobrien (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])) 149690075Sobrien (match_operand:BI 1 "register_operand" "0")))] 149790075Sobrien "" 149890075Sobrien "cmp.%C4.and.orcm %I0, %0 = %3, %2" 149990075Sobrien [(set_attr "itanium_class" "icmp")]) 150090075Sobrien 150190075Sobrien(define_insn "*cmpdi_orcm_1" 150290075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 150390075Sobrien (ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator" 150490075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 150590075Sobrien (const_int 0)])) 150690075Sobrien (match_operand:BI 1 "register_operand" "0")))] 150790075Sobrien "" 150890075Sobrien "cmp.%C3.and.orcm %I0, %0 = r0, %2" 150990075Sobrien [(set_attr "itanium_class" "icmp")]) 151090075Sobrien 151190075Sobrien(define_insn "*tbit_or_0" 151290075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 151390075Sobrien (ior:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r") 151490075Sobrien (const_int 1)) 151590075Sobrien (const_int 0)) 151690075Sobrien (match_operand:BI 2 "register_operand" "0")))] 151790075Sobrien "" 151890075Sobrien "tbit.nz.or.andcm %0, %I0 = %1, 0" 151990075Sobrien [(set_attr "itanium_class" "tbit")]) 152090075Sobrien 152190075Sobrien(define_insn "*tbit_or_1" 152290075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 152390075Sobrien (ior:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r") 152490075Sobrien (const_int 1)) 152590075Sobrien (const_int 0)) 152690075Sobrien (match_operand:BI 2 "register_operand" "0")))] 152790075Sobrien "" 152890075Sobrien "tbit.z.or.andcm %0, %I0 = %1, 0" 152990075Sobrien [(set_attr "itanium_class" "tbit")]) 153090075Sobrien 153190075Sobrien(define_insn "*tbit_or_2" 153290075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 153390075Sobrien (ior:BI (ne:BI (zero_extract:DI 153490075Sobrien (match_operand:DI 1 "gr_register_operand" "r") 153590075Sobrien (const_int 1) 153690075Sobrien (match_operand:DI 2 "const_int_operand" "n")) 153790075Sobrien (const_int 0)) 153890075Sobrien (match_operand:BI 3 "register_operand" "0")))] 153990075Sobrien "" 154090075Sobrien "tbit.nz.or.andcm %0, %I0 = %1, %2" 154190075Sobrien [(set_attr "itanium_class" "tbit")]) 154290075Sobrien 154390075Sobrien(define_insn "*tbit_or_3" 154490075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 154590075Sobrien (ior:BI (eq:BI (zero_extract:DI 154690075Sobrien (match_operand:DI 1 "gr_register_operand" "r") 154790075Sobrien (const_int 1) 154890075Sobrien (match_operand:DI 2 "const_int_operand" "n")) 154990075Sobrien (const_int 0)) 155090075Sobrien (match_operand:BI 3 "register_operand" "0")))] 155190075Sobrien "" 155290075Sobrien "tbit.z.or.andcm %0, %I0 = %1, %2" 155390075Sobrien [(set_attr "itanium_class" "tbit")]) 155490075Sobrien 155590075Sobrien;; Transform test of and/or of setcc into parallel comparisons. 155690075Sobrien 155790075Sobrien(define_split 155890075Sobrien [(set (match_operand:BI 0 "register_operand" "") 155990075Sobrien (ne:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "") 156090075Sobrien (const_int 0)) 156190075Sobrien (match_operand:DI 3 "register_operand" "")) 156290075Sobrien (const_int 0)))] 156390075Sobrien "" 156490075Sobrien [(set (match_dup 0) 156590075Sobrien (and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0)) 156690075Sobrien (match_dup 2)))] 156790075Sobrien "") 156890075Sobrien 156990075Sobrien(define_split 157090075Sobrien [(set (match_operand:BI 0 "register_operand" "") 157190075Sobrien (eq:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "") 157290075Sobrien (const_int 0)) 157390075Sobrien (match_operand:DI 3 "register_operand" "")) 157490075Sobrien (const_int 0)))] 157590075Sobrien "" 157690075Sobrien [(set (match_dup 0) 157790075Sobrien (and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0)) 157890075Sobrien (match_dup 2))) 157990075Sobrien (parallel [(set (match_dup 0) (not:BI (match_dup 0))) 158090075Sobrien (clobber (scratch))])] 158190075Sobrien "") 158290075Sobrien 158390075Sobrien(define_split 158490075Sobrien [(set (match_operand:BI 0 "register_operand" "") 158590075Sobrien (ne:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "") 158690075Sobrien (const_int 0)) 158790075Sobrien (match_operand:DI 3 "register_operand" "")) 158890075Sobrien (const_int 0)))] 158990075Sobrien "" 159090075Sobrien [(set (match_dup 0) 159190075Sobrien (ior:BI (ne:BI (match_dup 3) (const_int 0)) 159290075Sobrien (match_dup 2)))] 159390075Sobrien "") 159490075Sobrien 159590075Sobrien(define_split 159690075Sobrien [(set (match_operand:BI 0 "register_operand" "") 159790075Sobrien (eq:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "") 159890075Sobrien (const_int 0)) 159990075Sobrien (match_operand:DI 3 "register_operand" "")) 160090075Sobrien (const_int 0)))] 160190075Sobrien "" 160290075Sobrien [(set (match_dup 0) 160390075Sobrien (ior:BI (ne:BI (match_dup 3) (const_int 0)) 160490075Sobrien (match_dup 2))) 160590075Sobrien (parallel [(set (match_dup 0) (not:BI (match_dup 0))) 160690075Sobrien (clobber (scratch))])] 160790075Sobrien "") 160890075Sobrien 160990075Sobrien;; ??? Incredibly hackish. Either need four proper patterns with all 161090075Sobrien;; the alternatives, or rely on sched1 to split the insn and hope that 161190075Sobrien;; nothing bad happens to the comparisons in the meantime. 161290075Sobrien;; 161390075Sobrien;; Alternately, adjust combine to allow 2->2 and 3->3 splits, assuming 161490075Sobrien;; that we're doing height reduction. 161590075Sobrien; 161690075Sobrien;(define_insn_and_split "" 161790075Sobrien; [(set (match_operand:BI 0 "register_operand" "=c") 161890075Sobrien; (and:BI (and:BI (match_operator:BI 1 "comparison_operator" 161990075Sobrien; [(match_operand 2 "" "") 162090075Sobrien; (match_operand 3 "" "")]) 162190075Sobrien; (match_operator:BI 4 "comparison_operator" 162290075Sobrien; [(match_operand 5 "" "") 162390075Sobrien; (match_operand 6 "" "")])) 162490075Sobrien; (match_dup 0)))] 162590075Sobrien; "flag_schedule_insns" 162690075Sobrien; "#" 162790075Sobrien; "" 162890075Sobrien; [(set (match_dup 0) (and:BI (match_dup 1) (match_dup 0))) 162990075Sobrien; (set (match_dup 0) (and:BI (match_dup 4) (match_dup 0)))] 163090075Sobrien; "") 163190075Sobrien; 163290075Sobrien;(define_insn_and_split "" 163390075Sobrien; [(set (match_operand:BI 0 "register_operand" "=c") 163490075Sobrien; (ior:BI (ior:BI (match_operator:BI 1 "comparison_operator" 163590075Sobrien; [(match_operand 2 "" "") 163690075Sobrien; (match_operand 3 "" "")]) 163790075Sobrien; (match_operator:BI 4 "comparison_operator" 163890075Sobrien; [(match_operand 5 "" "") 163990075Sobrien; (match_operand 6 "" "")])) 164090075Sobrien; (match_dup 0)))] 164190075Sobrien; "flag_schedule_insns" 164290075Sobrien; "#" 164390075Sobrien; "" 164490075Sobrien; [(set (match_dup 0) (ior:BI (match_dup 1) (match_dup 0))) 164590075Sobrien; (set (match_dup 0) (ior:BI (match_dup 4) (match_dup 0)))] 164690075Sobrien; "") 164790075Sobrien; 164890075Sobrien;(define_split 164990075Sobrien; [(set (match_operand:BI 0 "register_operand" "") 165090075Sobrien; (and:BI (and:BI (match_operator:BI 1 "comparison_operator" 165190075Sobrien; [(match_operand 2 "" "") 165290075Sobrien; (match_operand 3 "" "")]) 165390075Sobrien; (match_operand:BI 7 "register_operand" "")) 165490075Sobrien; (and:BI (match_operator:BI 4 "comparison_operator" 165590075Sobrien; [(match_operand 5 "" "") 165690075Sobrien; (match_operand 6 "" "")]) 165790075Sobrien; (match_operand:BI 8 "register_operand" ""))))] 165890075Sobrien; "" 165990075Sobrien; [(set (match_dup 0) (and:BI (match_dup 7) (match_dup 8))) 166090075Sobrien; (set (match_dup 0) (and:BI (and:BI (match_dup 1) (match_dup 4)) 166190075Sobrien; (match_dup 0)))] 166290075Sobrien; "") 166390075Sobrien; 166490075Sobrien;(define_split 166590075Sobrien; [(set (match_operand:BI 0 "register_operand" "") 166690075Sobrien; (ior:BI (ior:BI (match_operator:BI 1 "comparison_operator" 166790075Sobrien; [(match_operand 2 "" "") 166890075Sobrien; (match_operand 3 "" "")]) 166990075Sobrien; (match_operand:BI 7 "register_operand" "")) 167090075Sobrien; (ior:BI (match_operator:BI 4 "comparison_operator" 167190075Sobrien; [(match_operand 5 "" "") 167290075Sobrien; (match_operand 6 "" "")]) 167390075Sobrien; (match_operand:BI 8 "register_operand" ""))))] 167490075Sobrien; "" 167590075Sobrien; [(set (match_dup 0) (ior:BI (match_dup 7) (match_dup 8))) 167690075Sobrien; (set (match_dup 0) (ior:BI (ior:BI (match_dup 1) (match_dup 4)) 167790075Sobrien; (match_dup 0)))] 167890075Sobrien; "") 167990075Sobrien 168090075Sobrien;; Try harder to avoid predicate copies by duplicating compares. 168190075Sobrien;; Note that we'll have already split the predicate copy, which 168290075Sobrien;; is kind of a pain, but oh well. 168390075Sobrien 168490075Sobrien(define_peephole2 168590075Sobrien [(set (match_operand:BI 0 "register_operand" "") 168690075Sobrien (match_operand:BI 1 "comparison_operator" "")) 168790075Sobrien (set (match_operand:CCI 2 "register_operand" "") 168890075Sobrien (match_operand:CCI 3 "register_operand" "")) 168990075Sobrien (set (match_operand:CCI 4 "register_operand" "") 169090075Sobrien (match_operand:CCI 5 "register_operand" "")) 169190075Sobrien (set (match_operand:BI 6 "register_operand" "") 1692117395Skan (unspec:BI [(match_dup 6)] UNSPEC_PRED_REL_MUTEX))] 169390075Sobrien "REGNO (operands[3]) == REGNO (operands[0]) 169490075Sobrien && REGNO (operands[4]) == REGNO (operands[0]) + 1 169590075Sobrien && REGNO (operands[4]) == REGNO (operands[2]) + 1 169690075Sobrien && REGNO (operands[6]) == REGNO (operands[2])" 169790075Sobrien [(set (match_dup 0) (match_dup 1)) 169890075Sobrien (set (match_dup 6) (match_dup 7))] 169990075Sobrien "operands[7] = copy_rtx (operands[1]);") 170090075Sobrien 170190075Sobrien;; :::::::::::::::::::: 170290075Sobrien;; :: 170390075Sobrien;; :: 16 bit Integer arithmetic 170490075Sobrien;; :: 170590075Sobrien;; :::::::::::::::::::: 170690075Sobrien 170790075Sobrien(define_insn "mulhi3" 170890075Sobrien [(set (match_operand:HI 0 "gr_register_operand" "=r") 170990075Sobrien (mult:HI (match_operand:HI 1 "gr_register_operand" "r") 171090075Sobrien (match_operand:HI 2 "gr_register_operand" "r")))] 171190075Sobrien "" 171290075Sobrien "pmpy2.r %0 = %1, %2" 171390075Sobrien [(set_attr "itanium_class" "mmmul")]) 171490075Sobrien 171590075Sobrien 171690075Sobrien;; :::::::::::::::::::: 171790075Sobrien;; :: 171890075Sobrien;; :: 32 bit Integer arithmetic 171990075Sobrien;; :: 172090075Sobrien;; :::::::::::::::::::: 172190075Sobrien 172290075Sobrien(define_insn "addsi3" 172390075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r") 172490075Sobrien (plus:SI (match_operand:SI 1 "gr_register_operand" "%r,r,a") 172590075Sobrien (match_operand:SI 2 "gr_reg_or_22bit_operand" "r,I,J")))] 172690075Sobrien "" 172790075Sobrien "@ 1728117395Skan add %0 = %1, %2 1729117395Skan adds %0 = %2, %1 1730117395Skan addl %0 = %2, %1" 173190075Sobrien [(set_attr "itanium_class" "ialu")]) 173290075Sobrien 173390075Sobrien(define_insn "*addsi3_plus1" 173490075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 173590075Sobrien (plus:SI (plus:SI (match_operand:SI 1 "gr_register_operand" "r") 173690075Sobrien (match_operand:SI 2 "gr_register_operand" "r")) 173790075Sobrien (const_int 1)))] 173890075Sobrien "" 173990075Sobrien "add %0 = %1, %2, 1" 174090075Sobrien [(set_attr "itanium_class" "ialu")]) 174190075Sobrien 174290075Sobrien(define_insn "*addsi3_plus1_alt" 174390075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 174490075Sobrien (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r") 174590075Sobrien (const_int 2)) 174690075Sobrien (const_int 1)))] 174790075Sobrien "" 174890075Sobrien "add %0 = %1, %1, 1" 174990075Sobrien [(set_attr "itanium_class" "ialu")]) 175090075Sobrien 175190075Sobrien(define_insn "*addsi3_shladd" 175290075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 175390075Sobrien (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r") 175490075Sobrien (match_operand:SI 2 "shladd_operand" "n")) 175590075Sobrien (match_operand:SI 3 "gr_register_operand" "r")))] 175690075Sobrien "" 175790075Sobrien "shladd %0 = %1, %S2, %3" 175890075Sobrien [(set_attr "itanium_class" "ialu")]) 175990075Sobrien 176090075Sobrien(define_insn "subsi3" 176190075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 176290075Sobrien (minus:SI (match_operand:SI 1 "gr_reg_or_8bit_operand" "rK") 176390075Sobrien (match_operand:SI 2 "gr_register_operand" "r")))] 176490075Sobrien "" 176590075Sobrien "sub %0 = %1, %2" 176690075Sobrien [(set_attr "itanium_class" "ialu")]) 176790075Sobrien 176890075Sobrien(define_insn "*subsi3_minus1" 176990075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 177090075Sobrien (plus:SI (not:SI (match_operand:SI 1 "gr_register_operand" "r")) 177190075Sobrien (match_operand:SI 2 "gr_register_operand" "r")))] 177290075Sobrien "" 177390075Sobrien "sub %0 = %2, %1, 1" 177490075Sobrien [(set_attr "itanium_class" "ialu")]) 177590075Sobrien 177690075Sobrien;; ??? Could add maddsi3 patterns patterned after the madddi3 patterns. 177790075Sobrien 177890075Sobrien(define_insn "mulsi3" 177990075Sobrien [(set (match_operand:SI 0 "fr_register_operand" "=f") 178090075Sobrien (mult:SI (match_operand:SI 1 "grfr_register_operand" "f") 178190075Sobrien (match_operand:SI 2 "grfr_register_operand" "f")))] 178290075Sobrien "" 178390075Sobrien "xmpy.l %0 = %1, %2" 178490075Sobrien [(set_attr "itanium_class" "xmpy")]) 178590075Sobrien 178690075Sobrien(define_insn "maddsi4" 178790075Sobrien [(set (match_operand:SI 0 "fr_register_operand" "=f") 178890075Sobrien (plus:SI (mult:SI (match_operand:SI 1 "grfr_register_operand" "f") 178990075Sobrien (match_operand:SI 2 "grfr_register_operand" "f")) 179090075Sobrien (match_operand:SI 3 "grfr_register_operand" "f")))] 179190075Sobrien "" 179290075Sobrien "xma.l %0 = %1, %2, %3" 179390075Sobrien [(set_attr "itanium_class" "xmpy")]) 179490075Sobrien 179590075Sobrien(define_insn "negsi2" 179690075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 179790075Sobrien (neg:SI (match_operand:SI 1 "gr_register_operand" "r")))] 179890075Sobrien "" 179990075Sobrien "sub %0 = r0, %1" 180090075Sobrien [(set_attr "itanium_class" "ialu")]) 180190075Sobrien 180290075Sobrien(define_expand "abssi2" 180390075Sobrien [(set (match_dup 2) 180490075Sobrien (ge:BI (match_operand:SI 1 "gr_register_operand" "") (const_int 0))) 180590075Sobrien (set (match_operand:SI 0 "gr_register_operand" "") 180690075Sobrien (if_then_else:SI (eq (match_dup 2) (const_int 0)) 180790075Sobrien (neg:SI (match_dup 1)) 180890075Sobrien (match_dup 1)))] 180990075Sobrien "" 1810117395Skan { operands[2] = gen_reg_rtx (BImode); }) 181190075Sobrien 181290075Sobrien(define_expand "sminsi3" 181390075Sobrien [(set (match_dup 3) 181490075Sobrien (ge:BI (match_operand:SI 1 "gr_register_operand" "") 181590075Sobrien (match_operand:SI 2 "gr_register_operand" ""))) 181690075Sobrien (set (match_operand:SI 0 "gr_register_operand" "") 181790075Sobrien (if_then_else:SI (ne (match_dup 3) (const_int 0)) 181890075Sobrien (match_dup 2) (match_dup 1)))] 181990075Sobrien "" 1820117395Skan { operands[3] = gen_reg_rtx (BImode); }) 182190075Sobrien 182290075Sobrien(define_expand "smaxsi3" 182390075Sobrien [(set (match_dup 3) 182490075Sobrien (ge:BI (match_operand:SI 1 "gr_register_operand" "") 182590075Sobrien (match_operand:SI 2 "gr_register_operand" ""))) 182690075Sobrien (set (match_operand:SI 0 "gr_register_operand" "") 182790075Sobrien (if_then_else:SI (ne (match_dup 3) (const_int 0)) 182890075Sobrien (match_dup 1) (match_dup 2)))] 182990075Sobrien "" 1830117395Skan { operands[3] = gen_reg_rtx (BImode); }) 183190075Sobrien 183290075Sobrien(define_expand "uminsi3" 183390075Sobrien [(set (match_dup 3) 183490075Sobrien (geu:BI (match_operand:SI 1 "gr_register_operand" "") 183590075Sobrien (match_operand:SI 2 "gr_register_operand" ""))) 183690075Sobrien (set (match_operand:SI 0 "gr_register_operand" "") 183790075Sobrien (if_then_else:SI (ne (match_dup 3) (const_int 0)) 183890075Sobrien (match_dup 2) (match_dup 1)))] 183990075Sobrien "" 1840117395Skan { operands[3] = gen_reg_rtx (BImode); }) 184190075Sobrien 184290075Sobrien(define_expand "umaxsi3" 184390075Sobrien [(set (match_dup 3) 184490075Sobrien (geu:BI (match_operand:SI 1 "gr_register_operand" "") 184590075Sobrien (match_operand:SI 2 "gr_register_operand" ""))) 184690075Sobrien (set (match_operand:SI 0 "gr_register_operand" "") 184790075Sobrien (if_then_else:SI (ne (match_dup 3) (const_int 0)) 184890075Sobrien (match_dup 1) (match_dup 2)))] 184990075Sobrien "" 1850117395Skan { operands[3] = gen_reg_rtx (BImode); }) 185190075Sobrien 185290075Sobrien(define_expand "divsi3" 185390075Sobrien [(set (match_operand:SI 0 "register_operand" "") 185490075Sobrien (div:SI (match_operand:SI 1 "general_operand" "") 185590075Sobrien (match_operand:SI 2 "general_operand" "")))] 1856132718Skan "TARGET_INLINE_INT_DIV" 185790075Sobrien{ 1858132718Skan rtx op1_xf, op2_xf, op0_xf, op0_di, twon34; 1859117395Skan REAL_VALUE_TYPE twon34_r; 186090075Sobrien 1861132718Skan op0_xf = gen_reg_rtx (XFmode); 186290075Sobrien op0_di = gen_reg_rtx (DImode); 186390075Sobrien 186490075Sobrien if (CONSTANT_P (operands[1])) 186590075Sobrien operands[1] = force_reg (SImode, operands[1]); 1866132718Skan op1_xf = gen_reg_rtx (XFmode); 1867132718Skan expand_float (op1_xf, operands[1], 0); 186890075Sobrien 186990075Sobrien if (CONSTANT_P (operands[2])) 187090075Sobrien operands[2] = force_reg (SImode, operands[2]); 1871132718Skan op2_xf = gen_reg_rtx (XFmode); 1872132718Skan expand_float (op2_xf, operands[2], 0); 187390075Sobrien 187490075Sobrien /* 2^-34 */ 1875117395Skan real_2expN (&twon34_r, -34); 1876132718Skan twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, XFmode); 1877132718Skan twon34 = force_reg (XFmode, twon34); 187890075Sobrien 1879132718Skan emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34)); 188090075Sobrien 1881132718Skan emit_insn (gen_fix_truncxfdi2_alts (op0_di, op0_xf, const1_rtx)); 188290075Sobrien emit_move_insn (operands[0], gen_lowpart (SImode, op0_di)); 188390075Sobrien DONE; 1884117395Skan}) 188590075Sobrien 188690075Sobrien(define_expand "modsi3" 188790075Sobrien [(set (match_operand:SI 0 "register_operand" "") 188890075Sobrien (mod:SI (match_operand:SI 1 "general_operand" "") 188990075Sobrien (match_operand:SI 2 "general_operand" "")))] 1890132718Skan "TARGET_INLINE_INT_DIV" 189190075Sobrien{ 189290075Sobrien rtx op2_neg, op1_di, div; 189390075Sobrien 189490075Sobrien div = gen_reg_rtx (SImode); 189590075Sobrien emit_insn (gen_divsi3 (div, operands[1], operands[2])); 189690075Sobrien 189790075Sobrien op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0); 189890075Sobrien 189990075Sobrien /* This is a trick to get us to reuse the value that we're sure to 190090075Sobrien have already copied to the FP regs. */ 190190075Sobrien op1_di = gen_reg_rtx (DImode); 190290075Sobrien convert_move (op1_di, operands[1], 0); 190390075Sobrien 190490075Sobrien emit_insn (gen_maddsi4 (operands[0], div, op2_neg, 190590075Sobrien gen_lowpart (SImode, op1_di))); 190690075Sobrien DONE; 1907117395Skan}) 190890075Sobrien 190990075Sobrien(define_expand "udivsi3" 191090075Sobrien [(set (match_operand:SI 0 "register_operand" "") 191190075Sobrien (udiv:SI (match_operand:SI 1 "general_operand" "") 191290075Sobrien (match_operand:SI 2 "general_operand" "")))] 1913132718Skan "TARGET_INLINE_INT_DIV" 191490075Sobrien{ 1915132718Skan rtx op1_xf, op2_xf, op0_xf, op0_di, twon34; 1916117395Skan REAL_VALUE_TYPE twon34_r; 191790075Sobrien 1918132718Skan op0_xf = gen_reg_rtx (XFmode); 191990075Sobrien op0_di = gen_reg_rtx (DImode); 192090075Sobrien 192190075Sobrien if (CONSTANT_P (operands[1])) 192290075Sobrien operands[1] = force_reg (SImode, operands[1]); 1923132718Skan op1_xf = gen_reg_rtx (XFmode); 1924132718Skan expand_float (op1_xf, operands[1], 1); 192590075Sobrien 192690075Sobrien if (CONSTANT_P (operands[2])) 192790075Sobrien operands[2] = force_reg (SImode, operands[2]); 1928132718Skan op2_xf = gen_reg_rtx (XFmode); 1929132718Skan expand_float (op2_xf, operands[2], 1); 193090075Sobrien 193190075Sobrien /* 2^-34 */ 1932117395Skan real_2expN (&twon34_r, -34); 1933132718Skan twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, XFmode); 1934132718Skan twon34 = force_reg (XFmode, twon34); 193590075Sobrien 1936132718Skan emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34)); 193790075Sobrien 1938132718Skan emit_insn (gen_fixuns_truncxfdi2_alts (op0_di, op0_xf, const1_rtx)); 193990075Sobrien emit_move_insn (operands[0], gen_lowpart (SImode, op0_di)); 194090075Sobrien DONE; 1941117395Skan}) 194290075Sobrien 194390075Sobrien(define_expand "umodsi3" 194490075Sobrien [(set (match_operand:SI 0 "register_operand" "") 194590075Sobrien (umod:SI (match_operand:SI 1 "general_operand" "") 194690075Sobrien (match_operand:SI 2 "general_operand" "")))] 1947132718Skan "TARGET_INLINE_INT_DIV" 194890075Sobrien{ 194990075Sobrien rtx op2_neg, op1_di, div; 195090075Sobrien 195190075Sobrien div = gen_reg_rtx (SImode); 195290075Sobrien emit_insn (gen_udivsi3 (div, operands[1], operands[2])); 195390075Sobrien 195490075Sobrien op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0); 195590075Sobrien 195690075Sobrien /* This is a trick to get us to reuse the value that we're sure to 195790075Sobrien have already copied to the FP regs. */ 195890075Sobrien op1_di = gen_reg_rtx (DImode); 195990075Sobrien convert_move (op1_di, operands[1], 1); 196090075Sobrien 196190075Sobrien emit_insn (gen_maddsi4 (operands[0], div, op2_neg, 196290075Sobrien gen_lowpart (SImode, op1_di))); 196390075Sobrien DONE; 1964117395Skan}) 196590075Sobrien 196690075Sobrien(define_insn_and_split "divsi3_internal" 1967132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=&f") 1968132718Skan (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f") 1969132718Skan (match_operand:XF 2 "fr_register_operand" "f")))) 1970132718Skan (clobber (match_scratch:XF 4 "=&f")) 1971132718Skan (clobber (match_scratch:XF 5 "=&f")) 197290075Sobrien (clobber (match_scratch:BI 6 "=c")) 1973132718Skan (use (match_operand:XF 3 "fr_register_operand" "f"))] 1974132718Skan "TARGET_INLINE_INT_DIV" 197590075Sobrien "#" 197690075Sobrien "&& reload_completed" 1977132718Skan [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2))) 1978117395Skan (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)] 1979117395Skan UNSPEC_FR_RECIP_APPROX)) 198090075Sobrien (use (const_int 1))]) 198190075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 1982132718Skan (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0))) 198390075Sobrien (use (const_int 1))])) 198490075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 198590075Sobrien (parallel [(set (match_dup 5) 1986132718Skan (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0))) 198790075Sobrien (match_dup 7))) 198890075Sobrien (use (const_int 1))])) 198990075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 199090075Sobrien (parallel [(set (match_dup 4) 1991132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 4)) 199290075Sobrien (match_dup 4))) 199390075Sobrien (use (const_int 1))])) 199490075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 199590075Sobrien (parallel [(set (match_dup 5) 1996132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 5)) 199790075Sobrien (match_dup 3))) 199890075Sobrien (use (const_int 1))])) 199990075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 200090075Sobrien (parallel [(set (match_dup 0) 2001132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 4)) 200290075Sobrien (match_dup 4))) 200390075Sobrien (use (const_int 1))])) 200490075Sobrien ] 2005132718Skan "operands[7] = CONST1_RTX (XFmode);" 200690075Sobrien [(set_attr "predicable" "no")]) 200790075Sobrien 200890075Sobrien;; :::::::::::::::::::: 200990075Sobrien;; :: 201090075Sobrien;; :: 64 bit Integer arithmetic 201190075Sobrien;; :: 201290075Sobrien;; :::::::::::::::::::: 201390075Sobrien 201490075Sobrien(define_insn "adddi3" 201590075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r") 201690075Sobrien (plus:DI (match_operand:DI 1 "gr_register_operand" "%r,r,a") 201790075Sobrien (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))] 201890075Sobrien "" 201990075Sobrien "@ 2020117395Skan add %0 = %1, %2 2021117395Skan adds %0 = %2, %1 2022117395Skan addl %0 = %2, %1" 202390075Sobrien [(set_attr "itanium_class" "ialu")]) 202490075Sobrien 202590075Sobrien(define_insn "*adddi3_plus1" 202690075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 202790075Sobrien (plus:DI (plus:DI (match_operand:DI 1 "gr_register_operand" "r") 202890075Sobrien (match_operand:DI 2 "gr_register_operand" "r")) 202990075Sobrien (const_int 1)))] 203090075Sobrien "" 203190075Sobrien "add %0 = %1, %2, 1" 203290075Sobrien [(set_attr "itanium_class" "ialu")]) 203390075Sobrien 203490075Sobrien;; This has some of the same problems as shladd. We let the shladd 203590075Sobrien;; eliminator hack handle it, which results in the 1 being forced into 203690075Sobrien;; a register, but not more ugliness here. 203790075Sobrien(define_insn "*adddi3_plus1_alt" 203890075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 203990075Sobrien (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r") 204090075Sobrien (const_int 2)) 204190075Sobrien (const_int 1)))] 204290075Sobrien "" 204390075Sobrien "add %0 = %1, %1, 1" 204490075Sobrien [(set_attr "itanium_class" "ialu")]) 204590075Sobrien 204690075Sobrien(define_insn "subdi3" 204790075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 204890075Sobrien (minus:DI (match_operand:DI 1 "gr_reg_or_8bit_operand" "rK") 204990075Sobrien (match_operand:DI 2 "gr_register_operand" "r")))] 205090075Sobrien "" 205190075Sobrien "sub %0 = %1, %2" 205290075Sobrien [(set_attr "itanium_class" "ialu")]) 205390075Sobrien 205490075Sobrien(define_insn "*subdi3_minus1" 205590075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 205690075Sobrien (plus:DI (not:DI (match_operand:DI 1 "gr_register_operand" "r")) 205790075Sobrien (match_operand:DI 2 "gr_register_operand" "r")))] 205890075Sobrien "" 205990075Sobrien "sub %0 = %2, %1, 1" 206090075Sobrien [(set_attr "itanium_class" "ialu")]) 206190075Sobrien 206290075Sobrien;; ??? Use grfr instead of fr because of virtual register elimination 206390075Sobrien;; and silly test cases multiplying by the frame pointer. 206490075Sobrien(define_insn "muldi3" 206590075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 206690075Sobrien (mult:DI (match_operand:DI 1 "grfr_register_operand" "f") 206790075Sobrien (match_operand:DI 2 "grfr_register_operand" "f")))] 206890075Sobrien "" 206990075Sobrien "xmpy.l %0 = %1, %2" 207090075Sobrien [(set_attr "itanium_class" "xmpy")]) 207190075Sobrien 207290075Sobrien;; ??? If operand 3 is an eliminable reg, then register elimination causes the 207390075Sobrien;; same problem that we have with shladd below. Unfortunately, this case is 207490075Sobrien;; much harder to fix because the multiply puts the result in an FP register, 207590075Sobrien;; but the add needs inputs from a general register. We add a spurious clobber 207690075Sobrien;; here so that it will be present just in case register elimination gives us 207790075Sobrien;; the funny result. 207890075Sobrien 207990075Sobrien;; ??? Maybe validate_changes should try adding match_scratch clobbers? 208090075Sobrien 208190075Sobrien;; ??? Maybe we should change how adds are canonicalized. 208290075Sobrien 208390075Sobrien(define_insn "madddi4" 208490075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 208590075Sobrien (plus:DI (mult:DI (match_operand:DI 1 "grfr_register_operand" "f") 208690075Sobrien (match_operand:DI 2 "grfr_register_operand" "f")) 208790075Sobrien (match_operand:DI 3 "grfr_register_operand" "f"))) 208890075Sobrien (clobber (match_scratch:DI 4 "=X"))] 208990075Sobrien "" 209090075Sobrien "xma.l %0 = %1, %2, %3" 209190075Sobrien [(set_attr "itanium_class" "xmpy")]) 209290075Sobrien 209390075Sobrien;; This can be created by register elimination if operand3 of shladd is an 209490075Sobrien;; eliminable register or has reg_equiv_constant set. 209590075Sobrien 209690075Sobrien;; We have to use nonmemory_operand for operand 4, to ensure that the 209790075Sobrien;; validate_changes call inside eliminate_regs will always succeed. If it 209890075Sobrien;; doesn't succeed, then this remain a madddi4 pattern, and will be reloaded 209990075Sobrien;; incorrectly. 210090075Sobrien 210190075Sobrien(define_insn "*madddi4_elim" 210290075Sobrien [(set (match_operand:DI 0 "register_operand" "=&r") 210390075Sobrien (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "f") 210490075Sobrien (match_operand:DI 2 "register_operand" "f")) 210590075Sobrien (match_operand:DI 3 "register_operand" "f")) 210690075Sobrien (match_operand:DI 4 "nonmemory_operand" "rI"))) 210790075Sobrien (clobber (match_scratch:DI 5 "=f"))] 210890075Sobrien "reload_in_progress" 210990075Sobrien "#" 211090075Sobrien [(set_attr "itanium_class" "unknown")]) 211190075Sobrien 211290075Sobrien(define_split 211390075Sobrien [(set (match_operand:DI 0 "register_operand" "") 211490075Sobrien (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "") 211590075Sobrien (match_operand:DI 2 "register_operand" "")) 211690075Sobrien (match_operand:DI 3 "register_operand" "")) 211790075Sobrien (match_operand:DI 4 "gr_reg_or_14bit_operand" ""))) 211890075Sobrien (clobber (match_scratch:DI 5 ""))] 211990075Sobrien "reload_completed" 212090075Sobrien [(parallel [(set (match_dup 5) (plus:DI (mult:DI (match_dup 1) (match_dup 2)) 212190075Sobrien (match_dup 3))) 212290075Sobrien (clobber (match_dup 0))]) 212390075Sobrien (set (match_dup 0) (match_dup 5)) 212490075Sobrien (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))] 212590075Sobrien "") 212690075Sobrien 212790075Sobrien;; ??? There are highpart multiply and add instructions, but we have no way 212890075Sobrien;; to generate them. 212990075Sobrien 213090075Sobrien(define_insn "smuldi3_highpart" 213190075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 213290075Sobrien (truncate:DI 213390075Sobrien (lshiftrt:TI 213490075Sobrien (mult:TI (sign_extend:TI 213590075Sobrien (match_operand:DI 1 "fr_register_operand" "f")) 213690075Sobrien (sign_extend:TI 213790075Sobrien (match_operand:DI 2 "fr_register_operand" "f"))) 213890075Sobrien (const_int 64))))] 213990075Sobrien "" 214090075Sobrien "xmpy.h %0 = %1, %2" 214190075Sobrien [(set_attr "itanium_class" "xmpy")]) 214290075Sobrien 214390075Sobrien(define_insn "umuldi3_highpart" 214490075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 214590075Sobrien (truncate:DI 214690075Sobrien (lshiftrt:TI 214790075Sobrien (mult:TI (zero_extend:TI 214890075Sobrien (match_operand:DI 1 "fr_register_operand" "f")) 214990075Sobrien (zero_extend:TI 215090075Sobrien (match_operand:DI 2 "fr_register_operand" "f"))) 215190075Sobrien (const_int 64))))] 215290075Sobrien "" 215390075Sobrien "xmpy.hu %0 = %1, %2" 215490075Sobrien [(set_attr "itanium_class" "xmpy")]) 215590075Sobrien 215690075Sobrien(define_insn "negdi2" 215790075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 215890075Sobrien (neg:DI (match_operand:DI 1 "gr_register_operand" "r")))] 215990075Sobrien "" 216090075Sobrien "sub %0 = r0, %1" 216190075Sobrien [(set_attr "itanium_class" "ialu")]) 216290075Sobrien 216390075Sobrien(define_expand "absdi2" 216490075Sobrien [(set (match_dup 2) 216590075Sobrien (ge:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0))) 216690075Sobrien (set (match_operand:DI 0 "gr_register_operand" "") 216790075Sobrien (if_then_else:DI (eq (match_dup 2) (const_int 0)) 216890075Sobrien (neg:DI (match_dup 1)) 216990075Sobrien (match_dup 1)))] 217090075Sobrien "" 2171117395Skan { operands[2] = gen_reg_rtx (BImode); }) 217290075Sobrien 217390075Sobrien(define_expand "smindi3" 217490075Sobrien [(set (match_dup 3) 217590075Sobrien (ge:BI (match_operand:DI 1 "gr_register_operand" "") 217690075Sobrien (match_operand:DI 2 "gr_register_operand" ""))) 217790075Sobrien (set (match_operand:DI 0 "gr_register_operand" "") 217890075Sobrien (if_then_else:DI (ne (match_dup 3) (const_int 0)) 217990075Sobrien (match_dup 2) (match_dup 1)))] 218090075Sobrien "" 2181117395Skan { operands[3] = gen_reg_rtx (BImode); }) 218290075Sobrien 218390075Sobrien(define_expand "smaxdi3" 218490075Sobrien [(set (match_dup 3) 218590075Sobrien (ge:BI (match_operand:DI 1 "gr_register_operand" "") 218690075Sobrien (match_operand:DI 2 "gr_register_operand" ""))) 218790075Sobrien (set (match_operand:DI 0 "gr_register_operand" "") 218890075Sobrien (if_then_else:DI (ne (match_dup 3) (const_int 0)) 218990075Sobrien (match_dup 1) (match_dup 2)))] 219090075Sobrien "" 2191117395Skan { operands[3] = gen_reg_rtx (BImode); }) 219290075Sobrien 219390075Sobrien(define_expand "umindi3" 219490075Sobrien [(set (match_dup 3) 219590075Sobrien (geu:BI (match_operand:DI 1 "gr_register_operand" "") 219690075Sobrien (match_operand:DI 2 "gr_register_operand" ""))) 219790075Sobrien (set (match_operand:DI 0 "gr_register_operand" "") 219890075Sobrien (if_then_else:DI (ne (match_dup 3) (const_int 0)) 219990075Sobrien (match_dup 2) (match_dup 1)))] 220090075Sobrien "" 2201117395Skan { operands[3] = gen_reg_rtx (BImode); }) 220290075Sobrien 220390075Sobrien(define_expand "umaxdi3" 220490075Sobrien [(set (match_dup 3) 220590075Sobrien (geu:BI (match_operand:DI 1 "gr_register_operand" "") 220690075Sobrien (match_operand:DI 2 "gr_register_operand" ""))) 220790075Sobrien (set (match_operand:DI 0 "gr_register_operand" "") 220890075Sobrien (if_then_else:DI (ne (match_dup 3) (const_int 0)) 220990075Sobrien (match_dup 1) (match_dup 2)))] 221090075Sobrien "" 2211117395Skan { operands[3] = gen_reg_rtx (BImode); }) 221290075Sobrien 221390075Sobrien(define_expand "ffsdi2" 221490075Sobrien [(set (match_dup 6) 221590075Sobrien (eq:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0))) 221690075Sobrien (set (match_dup 2) (plus:DI (match_dup 1) (const_int -1))) 221790075Sobrien (set (match_dup 5) (const_int 0)) 221890075Sobrien (set (match_dup 3) (xor:DI (match_dup 1) (match_dup 2))) 2219132718Skan (set (match_dup 4) (popcount:DI (match_dup 3))) 222090075Sobrien (set (match_operand:DI 0 "gr_register_operand" "") 222190075Sobrien (if_then_else:DI (ne (match_dup 6) (const_int 0)) 222290075Sobrien (match_dup 5) (match_dup 4)))] 222390075Sobrien "" 222490075Sobrien{ 222590075Sobrien operands[2] = gen_reg_rtx (DImode); 222690075Sobrien operands[3] = gen_reg_rtx (DImode); 222790075Sobrien operands[4] = gen_reg_rtx (DImode); 222890075Sobrien operands[5] = gen_reg_rtx (DImode); 222990075Sobrien operands[6] = gen_reg_rtx (BImode); 2230117395Skan}) 223190075Sobrien 2232132718Skan(define_expand "ctzdi2" 2233132718Skan [(set (match_dup 2) (plus:DI (match_operand:DI 1 "gr_register_operand" "") 2234132718Skan (const_int -1))) 2235132718Skan (set (match_dup 3) (not:DI (match_dup 1))) 2236132718Skan (set (match_dup 4) (and:DI (match_dup 2) (match_dup 3))) 2237132718Skan (set (match_operand:DI 0 "gr_register_operand" "") 2238132718Skan (popcount:DI (match_dup 4)))] 2239132718Skan "" 2240132718Skan{ 2241132718Skan operands[2] = gen_reg_rtx (DImode); 2242132718Skan operands[3] = gen_reg_rtx (DImode); 2243132718Skan operands[4] = gen_reg_rtx (DImode); 2244132718Skan}) 2245132718Skan 2246132718Skan;; Note the computation here is op0 = 63 - (exp - 0xffff). 2247132718Skan(define_expand "clzdi2" 2248132718Skan [(set (match_dup 2) 2249132718Skan (unsigned_float:XF (match_operand:DI 1 "fr_register_operand" ""))) 2250132718Skan (set (match_dup 3) 2251132718Skan (unspec:DI [(match_dup 2)] UNSPEC_GETF_EXP)) 2252132718Skan (set (match_dup 4) (const_int 65598)) 2253132718Skan (set (match_operand:DI 0 "gr_register_operand" "") 2254132718Skan (minus:DI (match_dup 4) (match_dup 3)))] 2255132718Skan "" 2256132718Skan{ 2257132718Skan operands[2] = gen_reg_rtx (XFmode); 2258132718Skan operands[3] = gen_reg_rtx (DImode); 2259132718Skan operands[4] = gen_reg_rtx (DImode); 2260132718Skan}) 2261132718Skan 2262132718Skan(define_insn "popcountdi2" 226390075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 2264132718Skan (popcount:DI (match_operand:DI 1 "gr_register_operand" "r")))] 226590075Sobrien "" 226690075Sobrien "popcnt %0 = %1" 226790075Sobrien [(set_attr "itanium_class" "mmmul")]) 226890075Sobrien 2269132718Skan(define_insn "*getf_exp_xf" 2270132718Skan [(set (match_operand:DI 0 "gr_register_operand" "=r") 2271132718Skan (unspec:DI [(match_operand:XF 1 "fr_register_operand" "f")] 2272132718Skan UNSPEC_GETF_EXP))] 2273132718Skan "" 2274132718Skan "getf.exp %0 = %1" 2275132718Skan [(set_attr "itanium_class" "frfr")]) 2276132718Skan 227790075Sobrien(define_expand "divdi3" 227890075Sobrien [(set (match_operand:DI 0 "register_operand" "") 227990075Sobrien (div:DI (match_operand:DI 1 "general_operand" "") 228090075Sobrien (match_operand:DI 2 "general_operand" "")))] 2281132718Skan "TARGET_INLINE_INT_DIV" 228290075Sobrien{ 2283132718Skan rtx op1_xf, op2_xf, op0_xf; 228490075Sobrien 2285132718Skan op0_xf = gen_reg_rtx (XFmode); 228690075Sobrien 228790075Sobrien if (CONSTANT_P (operands[1])) 228890075Sobrien operands[1] = force_reg (DImode, operands[1]); 2289132718Skan op1_xf = gen_reg_rtx (XFmode); 2290132718Skan expand_float (op1_xf, operands[1], 0); 229190075Sobrien 229290075Sobrien if (CONSTANT_P (operands[2])) 229390075Sobrien operands[2] = force_reg (DImode, operands[2]); 2294132718Skan op2_xf = gen_reg_rtx (XFmode); 2295132718Skan expand_float (op2_xf, operands[2], 0); 229690075Sobrien 2297117395Skan if (TARGET_INLINE_INT_DIV_LAT) 2298132718Skan emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf)); 229990075Sobrien else 2300132718Skan emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf)); 230190075Sobrien 2302132718Skan emit_insn (gen_fix_truncxfdi2_alts (operands[0], op0_xf, const1_rtx)); 230390075Sobrien DONE; 2304117395Skan}) 230590075Sobrien 230690075Sobrien(define_expand "moddi3" 230790075Sobrien [(set (match_operand:DI 0 "register_operand" "") 230890075Sobrien (mod:SI (match_operand:DI 1 "general_operand" "") 230990075Sobrien (match_operand:DI 2 "general_operand" "")))] 2310132718Skan "TARGET_INLINE_INT_DIV" 231190075Sobrien{ 231290075Sobrien rtx op2_neg, div; 231390075Sobrien 231490075Sobrien div = gen_reg_rtx (DImode); 231590075Sobrien emit_insn (gen_divdi3 (div, operands[1], operands[2])); 231690075Sobrien 231790075Sobrien op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0); 231890075Sobrien 231990075Sobrien emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1])); 232090075Sobrien DONE; 2321117395Skan}) 232290075Sobrien 232390075Sobrien(define_expand "udivdi3" 232490075Sobrien [(set (match_operand:DI 0 "register_operand" "") 232590075Sobrien (udiv:DI (match_operand:DI 1 "general_operand" "") 232690075Sobrien (match_operand:DI 2 "general_operand" "")))] 2327132718Skan "TARGET_INLINE_INT_DIV" 232890075Sobrien{ 2329132718Skan rtx op1_xf, op2_xf, op0_xf; 233090075Sobrien 2331132718Skan op0_xf = gen_reg_rtx (XFmode); 233290075Sobrien 233390075Sobrien if (CONSTANT_P (operands[1])) 233490075Sobrien operands[1] = force_reg (DImode, operands[1]); 2335132718Skan op1_xf = gen_reg_rtx (XFmode); 2336132718Skan expand_float (op1_xf, operands[1], 1); 233790075Sobrien 233890075Sobrien if (CONSTANT_P (operands[2])) 233990075Sobrien operands[2] = force_reg (DImode, operands[2]); 2340132718Skan op2_xf = gen_reg_rtx (XFmode); 2341132718Skan expand_float (op2_xf, operands[2], 1); 234290075Sobrien 2343117395Skan if (TARGET_INLINE_INT_DIV_LAT) 2344132718Skan emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf)); 234590075Sobrien else 2346132718Skan emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf)); 234790075Sobrien 2348132718Skan emit_insn (gen_fixuns_truncxfdi2_alts (operands[0], op0_xf, const1_rtx)); 234990075Sobrien DONE; 2350117395Skan}) 235190075Sobrien 235290075Sobrien(define_expand "umoddi3" 235390075Sobrien [(set (match_operand:DI 0 "register_operand" "") 235490075Sobrien (umod:DI (match_operand:DI 1 "general_operand" "") 235590075Sobrien (match_operand:DI 2 "general_operand" "")))] 2356132718Skan "TARGET_INLINE_INT_DIV" 235790075Sobrien{ 235890075Sobrien rtx op2_neg, div; 235990075Sobrien 236090075Sobrien div = gen_reg_rtx (DImode); 236190075Sobrien emit_insn (gen_udivdi3 (div, operands[1], operands[2])); 236290075Sobrien 236390075Sobrien op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0); 236490075Sobrien 236590075Sobrien emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1])); 236690075Sobrien DONE; 2367117395Skan}) 236890075Sobrien 236990075Sobrien(define_insn_and_split "divdi3_internal_lat" 2370132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=&f") 2371132718Skan (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f") 2372132718Skan (match_operand:XF 2 "fr_register_operand" "f")))) 2373132718Skan (clobber (match_scratch:XF 3 "=&f")) 2374132718Skan (clobber (match_scratch:XF 4 "=&f")) 2375132718Skan (clobber (match_scratch:XF 5 "=&f")) 237690075Sobrien (clobber (match_scratch:BI 6 "=c"))] 2377132718Skan "TARGET_INLINE_INT_DIV_LAT" 237890075Sobrien "#" 237990075Sobrien "&& reload_completed" 2380132718Skan [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2))) 2381117395Skan (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)] 2382117395Skan UNSPEC_FR_RECIP_APPROX)) 238390075Sobrien (use (const_int 1))]) 238490075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 238590075Sobrien (parallel [(set (match_dup 3) 2386132718Skan (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0))) 238790075Sobrien (match_dup 7))) 238890075Sobrien (use (const_int 1))])) 238990075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 2390132718Skan (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0))) 239190075Sobrien (use (const_int 1))])) 239290075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 2393132718Skan (parallel [(set (match_dup 5) (mult:XF (match_dup 3) (match_dup 3))) 239490075Sobrien (use (const_int 1))])) 239590075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 239690075Sobrien (parallel [(set (match_dup 4) 2397132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 4)) 239890075Sobrien (match_dup 4))) 239990075Sobrien (use (const_int 1))])) 240090075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 240190075Sobrien (parallel [(set (match_dup 0) 2402132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 0)) 240390075Sobrien (match_dup 0))) 240490075Sobrien (use (const_int 1))])) 240590075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 240690075Sobrien (parallel [(set (match_dup 3) 2407132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 4)) 240890075Sobrien (match_dup 4))) 240990075Sobrien (use (const_int 1))])) 241090075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 241190075Sobrien (parallel [(set (match_dup 0) 2412132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 0)) 241390075Sobrien (match_dup 0))) 241490075Sobrien (use (const_int 1))])) 241590075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 241690075Sobrien (parallel [(set (match_dup 4) 2417132718Skan (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3))) 241890075Sobrien (match_dup 1))) 241990075Sobrien (use (const_int 1))])) 242090075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 242190075Sobrien (parallel [(set (match_dup 0) 2422132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 0)) 242390075Sobrien (match_dup 3))) 242490075Sobrien (use (const_int 1))])) 242590075Sobrien ] 2426132718Skan "operands[7] = CONST1_RTX (XFmode);" 242790075Sobrien [(set_attr "predicable" "no")]) 242890075Sobrien 242990075Sobrien(define_insn_and_split "divdi3_internal_thr" 2430132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=&f") 2431132718Skan (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f") 2432132718Skan (match_operand:XF 2 "fr_register_operand" "f")))) 2433132718Skan (clobber (match_scratch:XF 3 "=&f")) 2434132718Skan (clobber (match_scratch:XF 4 "=f")) 243590075Sobrien (clobber (match_scratch:BI 5 "=c"))] 2436132718Skan "TARGET_INLINE_INT_DIV_THR" 243790075Sobrien "#" 243890075Sobrien "&& reload_completed" 2439132718Skan [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2))) 2440117395Skan (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)] 2441117395Skan UNSPEC_FR_RECIP_APPROX)) 244290075Sobrien (use (const_int 1))]) 244390075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 244490075Sobrien (parallel [(set (match_dup 3) 2445132718Skan (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0))) 244690075Sobrien (match_dup 6))) 244790075Sobrien (use (const_int 1))])) 244890075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 244990075Sobrien (parallel [(set (match_dup 0) 2450132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 0)) 245190075Sobrien (match_dup 0))) 245290075Sobrien (use (const_int 1))])) 245390075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 2454132718Skan (parallel [(set (match_dup 3) (mult:XF (match_dup 3) (match_dup 3))) 245590075Sobrien (use (const_int 1))])) 245690075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 245790075Sobrien (parallel [(set (match_dup 0) 2458132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 0)) 245990075Sobrien (match_dup 0))) 246090075Sobrien (use (const_int 1))])) 246190075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 2462132718Skan (parallel [(set (match_dup 3) (mult:XF (match_dup 0) (match_dup 1))) 246390075Sobrien (use (const_int 1))])) 246490075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 246590075Sobrien (parallel [(set (match_dup 4) 2466132718Skan (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3))) 246790075Sobrien (match_dup 1))) 246890075Sobrien (use (const_int 1))])) 246990075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 247090075Sobrien (parallel [(set (match_dup 0) 2471132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 0)) 247290075Sobrien (match_dup 3))) 247390075Sobrien (use (const_int 1))])) 247490075Sobrien ] 2475132718Skan "operands[6] = CONST1_RTX (XFmode);" 247690075Sobrien [(set_attr "predicable" "no")]) 247790075Sobrien 247890075Sobrien;; :::::::::::::::::::: 247990075Sobrien;; :: 248090075Sobrien;; :: 32 bit floating point arithmetic 248190075Sobrien;; :: 248290075Sobrien;; :::::::::::::::::::: 248390075Sobrien 248490075Sobrien(define_insn "addsf3" 248590075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 248690075Sobrien (plus:SF (match_operand:SF 1 "fr_register_operand" "%f") 248790075Sobrien (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))] 248890075Sobrien "" 248990075Sobrien "fadd.s %0 = %1, %F2" 249090075Sobrien [(set_attr "itanium_class" "fmac")]) 249190075Sobrien 249290075Sobrien(define_insn "subsf3" 249390075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 249490075Sobrien (minus:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG") 249590075Sobrien (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))] 249690075Sobrien "" 249790075Sobrien "fsub.s %0 = %F1, %F2" 249890075Sobrien [(set_attr "itanium_class" "fmac")]) 249990075Sobrien 250090075Sobrien(define_insn "mulsf3" 250190075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 250290075Sobrien (mult:SF (match_operand:SF 1 "fr_register_operand" "%f") 250390075Sobrien (match_operand:SF 2 "fr_register_operand" "f")))] 250490075Sobrien "" 250590075Sobrien "fmpy.s %0 = %1, %2" 250690075Sobrien [(set_attr "itanium_class" "fmac")]) 250790075Sobrien 250890075Sobrien(define_insn "abssf2" 250990075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 251090075Sobrien (abs:SF (match_operand:SF 1 "fr_register_operand" "f")))] 251190075Sobrien "" 251290075Sobrien "fabs %0 = %1" 251390075Sobrien [(set_attr "itanium_class" "fmisc")]) 251490075Sobrien 251590075Sobrien(define_insn "negsf2" 251690075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 251790075Sobrien (neg:SF (match_operand:SF 1 "fr_register_operand" "f")))] 251890075Sobrien "" 251990075Sobrien "fneg %0 = %1" 252090075Sobrien [(set_attr "itanium_class" "fmisc")]) 252190075Sobrien 252290075Sobrien(define_insn "*nabssf2" 252390075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 252490075Sobrien (neg:SF (abs:SF (match_operand:SF 1 "fr_register_operand" "f"))))] 252590075Sobrien "" 252690075Sobrien "fnegabs %0 = %1" 252790075Sobrien [(set_attr "itanium_class" "fmisc")]) 252890075Sobrien 252990075Sobrien(define_insn "minsf3" 253090075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 253190075Sobrien (smin:SF (match_operand:SF 1 "fr_register_operand" "f") 253290075Sobrien (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))] 253390075Sobrien "" 253490075Sobrien "fmin %0 = %1, %F2" 253590075Sobrien [(set_attr "itanium_class" "fmisc")]) 253690075Sobrien 253790075Sobrien(define_insn "maxsf3" 253890075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 253990075Sobrien (smax:SF (match_operand:SF 1 "fr_register_operand" "f") 254090075Sobrien (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))] 254190075Sobrien "" 254290075Sobrien "fmax %0 = %1, %F2" 254390075Sobrien [(set_attr "itanium_class" "fmisc")]) 254490075Sobrien 254590075Sobrien(define_insn "*maddsf4" 254690075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 254790075Sobrien (plus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f") 254890075Sobrien (match_operand:SF 2 "fr_register_operand" "f")) 254990075Sobrien (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))] 255090075Sobrien "" 255190075Sobrien "fma.s %0 = %1, %2, %F3" 255290075Sobrien [(set_attr "itanium_class" "fmac")]) 255390075Sobrien 255490075Sobrien(define_insn "*msubsf4" 255590075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 255690075Sobrien (minus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f") 255790075Sobrien (match_operand:SF 2 "fr_register_operand" "f")) 255890075Sobrien (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))] 255990075Sobrien "" 256090075Sobrien "fms.s %0 = %1, %2, %F3" 256190075Sobrien [(set_attr "itanium_class" "fmac")]) 256290075Sobrien 256390075Sobrien(define_insn "*nmulsf3" 256490075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 256590075Sobrien (neg:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f") 256690075Sobrien (match_operand:SF 2 "fr_register_operand" "f"))))] 256790075Sobrien "" 256890075Sobrien "fnmpy.s %0 = %1, %2" 256990075Sobrien [(set_attr "itanium_class" "fmac")]) 257090075Sobrien 257190075Sobrien;; ??? Is it possible to canonicalize this as (minus (reg) (mult))? 257290075Sobrien 257390075Sobrien(define_insn "*nmaddsf4" 257490075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 257590075Sobrien (plus:SF (neg:SF (mult:SF 257690075Sobrien (match_operand:SF 1 "fr_register_operand" "f") 257790075Sobrien (match_operand:SF 2 "fr_register_operand" "f"))) 257890075Sobrien (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))] 257990075Sobrien "" 258090075Sobrien "fnma.s %0 = %1, %2, %F3" 258190075Sobrien [(set_attr "itanium_class" "fmac")]) 258290075Sobrien 258390075Sobrien(define_expand "divsf3" 258490075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "") 258590075Sobrien (div:SF (match_operand:SF 1 "fr_register_operand" "") 258690075Sobrien (match_operand:SF 2 "fr_register_operand" "")))] 2587132718Skan "TARGET_INLINE_FLOAT_DIV" 258890075Sobrien{ 258990075Sobrien rtx insn; 2590117395Skan if (TARGET_INLINE_FLOAT_DIV_LAT) 259190075Sobrien insn = gen_divsf3_internal_lat (operands[0], operands[1], operands[2]); 259290075Sobrien else 259390075Sobrien insn = gen_divsf3_internal_thr (operands[0], operands[1], operands[2]); 259490075Sobrien emit_insn (insn); 259590075Sobrien DONE; 2596117395Skan}) 259790075Sobrien 259890075Sobrien(define_insn_and_split "divsf3_internal_lat" 259990075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=&f") 260090075Sobrien (div:SF (match_operand:SF 1 "fr_register_operand" "f") 260190075Sobrien (match_operand:SF 2 "fr_register_operand" "f"))) 2602132718Skan (clobber (match_scratch:XF 3 "=&f")) 2603132718Skan (clobber (match_scratch:XF 4 "=f")) 260490075Sobrien (clobber (match_scratch:BI 5 "=c"))] 2605132718Skan "TARGET_INLINE_FLOAT_DIV_LAT" 260690075Sobrien "#" 260790075Sobrien "&& reload_completed" 2608132718Skan [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8))) 2609117395Skan (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)] 2610117395Skan UNSPEC_FR_RECIP_APPROX)) 261190075Sobrien (use (const_int 1))]) 261290075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 2613132718Skan (parallel [(set (match_dup 3) (mult:XF (match_dup 7) (match_dup 6))) 261490075Sobrien (use (const_int 1))])) 261590075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 261690075Sobrien (parallel [(set (match_dup 4) 2617132718Skan (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 6))) 261890075Sobrien (match_dup 10))) 261990075Sobrien (use (const_int 1))])) 262090075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 262190075Sobrien (parallel [(set (match_dup 3) 2622132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 3)) 262390075Sobrien (match_dup 3))) 262490075Sobrien (use (const_int 1))])) 262590075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 2626132718Skan (parallel [(set (match_dup 4) (mult:XF (match_dup 4) (match_dup 4))) 262790075Sobrien (use (const_int 1))])) 262890075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 262990075Sobrien (parallel [(set (match_dup 3) 2630132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 3)) 263190075Sobrien (match_dup 3))) 263290075Sobrien (use (const_int 1))])) 263390075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 2634132718Skan (parallel [(set (match_dup 4) (mult:XF (match_dup 4) (match_dup 4))) 263590075Sobrien (use (const_int 1))])) 263690075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 263790075Sobrien (parallel [(set (match_dup 9) 263890075Sobrien (float_truncate:DF 2639132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 3)) 264090075Sobrien (match_dup 3)))) 264190075Sobrien (use (const_int 1))])) 264290075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 264390075Sobrien (set (match_dup 0) 264490075Sobrien (float_truncate:SF (match_dup 6)))) 264590075Sobrien ] 2646117395Skan{ 2647132718Skan operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0])); 2648132718Skan operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1])); 2649132718Skan operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2])); 2650117395Skan operands[9] = gen_rtx_REG (DFmode, REGNO (operands[0])); 2651132718Skan operands[10] = CONST1_RTX (XFmode); 2652117395Skan} 265390075Sobrien [(set_attr "predicable" "no")]) 265490075Sobrien 265590075Sobrien(define_insn_and_split "divsf3_internal_thr" 265690075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=&f") 265790075Sobrien (div:SF (match_operand:SF 1 "fr_register_operand" "f") 265890075Sobrien (match_operand:SF 2 "fr_register_operand" "f"))) 2659132718Skan (clobber (match_scratch:XF 3 "=&f")) 2660132718Skan (clobber (match_scratch:XF 4 "=f")) 266190075Sobrien (clobber (match_scratch:BI 5 "=c"))] 2662132718Skan "TARGET_INLINE_FLOAT_DIV_THR" 266390075Sobrien "#" 266490075Sobrien "&& reload_completed" 2665132718Skan [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8))) 2666117395Skan (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)] 2667117395Skan UNSPEC_FR_RECIP_APPROX)) 266890075Sobrien (use (const_int 1))]) 266990075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 267090075Sobrien (parallel [(set (match_dup 3) 2671132718Skan (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 6))) 267290075Sobrien (match_dup 10))) 267390075Sobrien (use (const_int 1))])) 267490075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 267590075Sobrien (parallel [(set (match_dup 3) 2676132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 3)) 267790075Sobrien (match_dup 3))) 267890075Sobrien (use (const_int 1))])) 267990075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 268090075Sobrien (parallel [(set (match_dup 6) 2681132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 6)) 268290075Sobrien (match_dup 6))) 268390075Sobrien (use (const_int 1))])) 268490075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 268590075Sobrien (parallel [(set (match_dup 9) 268690075Sobrien (float_truncate:SF 2687132718Skan (mult:XF (match_dup 7) (match_dup 6)))) 268890075Sobrien (use (const_int 1))])) 268990075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 269090075Sobrien (parallel [(set (match_dup 4) 2691132718Skan (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 3))) 269290075Sobrien (match_dup 7))) 269390075Sobrien (use (const_int 1))])) 269490075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 269590075Sobrien (set (match_dup 0) 269690075Sobrien (float_truncate:SF 2697132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 6)) 269890075Sobrien (match_dup 3))))) 269990075Sobrien ] 2700117395Skan{ 2701132718Skan operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0])); 2702132718Skan operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1])); 2703132718Skan operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2])); 2704117395Skan operands[9] = gen_rtx_REG (SFmode, REGNO (operands[3])); 2705132718Skan operands[10] = CONST1_RTX (XFmode); 2706117395Skan} 270790075Sobrien [(set_attr "predicable" "no")]) 2708132718Skan 2709132718Skan;; Inline square root. 2710132718Skan 2711132718Skan(define_insn "*sqrt_approx" 2712132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 2713132718Skan (div:XF (const_int 1) 2714132718Skan (sqrt:XF (match_operand:XF 2 "fr_register_operand" "f")))) 2715132718Skan (set (match_operand:BI 1 "register_operand" "=c") 2716132718Skan (unspec:BI [(match_dup 2)] UNSPEC_FR_SQRT_RECIP_APPROX)) 2717132718Skan (use (match_operand:SI 3 "const_int_operand" "")) ] 2718132718Skan "" 2719132718Skan "frsqrta.s%3 %0, %1 = %2" 2720132718Skan [(set_attr "itanium_class" "fmisc") 2721132718Skan (set_attr "predicable" "no")]) 2722132718Skan 2723132718Skan(define_insn "*setf_exp_xf" 2724132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 2725132718Skan (unspec:XF [(match_operand:DI 1 "register_operand" "r")] 2726132718Skan UNSPEC_SETF_EXP))] 2727132718Skan "" 2728132718Skan "setf.exp %0 = %1" 2729132718Skan [(set_attr "itanium_class" "frfr")]) 2730132718Skan 2731132718Skan(define_expand "sqrtsf2" 2732132718Skan [(set (match_operand:SF 0 "fr_register_operand" "=&f") 2733132718Skan (sqrt:SF (match_operand:SF 1 "fr_register_operand" "f")))] 2734132718Skan "TARGET_INLINE_SQRT" 2735132718Skan{ 2736132718Skan rtx insn; 2737132718Skan if (TARGET_INLINE_SQRT_LAT) 2738132718Skan#if 0 2739132718Skan insn = gen_sqrtsf2_internal_lat (operands[0], operands[1]); 2740132718Skan#else 2741132718Skan abort (); 2742132718Skan#endif 2743132718Skan else 2744132718Skan insn = gen_sqrtsf2_internal_thr (operands[0], operands[1]); 2745132718Skan emit_insn (insn); 2746132718Skan DONE; 2747132718Skan}) 2748132718Skan 2749132718Skan;; Latency-optimized square root. 2750132718Skan;; FIXME: Implement. 2751132718Skan 2752132718Skan;; Throughput-optimized square root. 2753132718Skan 2754132718Skan(define_insn_and_split "sqrtsf2_internal_thr" 2755132718Skan [(set (match_operand:SF 0 "fr_register_operand" "=&f") 2756132718Skan (sqrt:SF (match_operand:SF 1 "fr_register_operand" "f"))) 2757132718Skan ;; Register r2 in optimization guide. 2758132718Skan (clobber (match_scratch:DI 2 "=r")) 2759132718Skan ;; Register f8 in optimization guide 2760132718Skan (clobber (match_scratch:XF 3 "=&f")) 2761132718Skan ;; Register f9 in optimization guide 2762132718Skan (clobber (match_scratch:XF 4 "=&f")) 2763132718Skan ;; Register f10 in optimization guide 2764132718Skan (clobber (match_scratch:XF 5 "=&f")) 2765132718Skan ;; Register p6 in optimization guide. 2766132718Skan (clobber (match_scratch:BI 6 "=c"))] 2767132718Skan "TARGET_INLINE_SQRT_THR" 2768132718Skan "#" 2769132718Skan "&& reload_completed" 2770132718Skan [ ;; exponent of +1/2 in r2 2771132718Skan (set (match_dup 2) (const_int 65534)) 2772132718Skan ;; +1/2 in f8 2773132718Skan (set (match_dup 3) 2774132718Skan (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP)) 2775132718Skan ;; Step 1 2776132718Skan ;; y0 = 1/sqrt(a) in f7 2777132718Skan (parallel [(set (match_dup 7) 2778132718Skan (div:XF (const_int 1) 2779132718Skan (sqrt:XF (match_dup 8)))) 2780132718Skan (set (match_dup 6) 2781132718Skan (unspec:BI [(match_dup 8)] 2782132718Skan UNSPEC_FR_SQRT_RECIP_APPROX)) 2783132718Skan (use (const_int 0))]) 2784132718Skan ;; Step 2 2785132718Skan ;; H0 = 1/2 * y0 in f9 2786132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 2787132718Skan (parallel [(set (match_dup 4) 2788132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 7)) 2789132718Skan (match_dup 9))) 2790132718Skan (use (const_int 1))])) 2791132718Skan ;; Step 3 2792132718Skan ;; S0 = a * y0 in f7 2793132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 2794132718Skan (parallel [(set (match_dup 7) 2795132718Skan (plus:XF (mult:XF (match_dup 8) (match_dup 7)) 2796132718Skan (match_dup 9))) 2797132718Skan (use (const_int 1))])) 2798132718Skan ;; Step 4 2799132718Skan ;; d = 1/2 - S0 * H0 in f10 2800132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 2801132718Skan (parallel [(set (match_dup 5) 2802132718Skan (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 4))) 2803132718Skan (match_dup 3))) 2804132718Skan (use (const_int 1))])) 2805132718Skan ;; Step 5 2806132718Skan ;; d' = d + 1/2 * d in f8 2807132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 2808132718Skan (parallel [(set (match_dup 3) 2809132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 5)) 2810132718Skan (match_dup 5))) 2811132718Skan (use (const_int 1))])) 2812132718Skan ;; Step 6 2813132718Skan ;; e = d + d * d' in f8 2814132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 2815132718Skan (parallel [(set (match_dup 3) 2816132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 3)) 2817132718Skan (match_dup 5))) 2818132718Skan (use (const_int 1))])) 2819132718Skan ;; Step 7 2820132718Skan ;; S1 = S0 + e * S0 in f7 2821132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 2822132718Skan (parallel [(set (match_dup 0) 2823132718Skan (float_truncate:SF 2824132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 7)) 2825132718Skan (match_dup 7)))) 2826132718Skan (use (const_int 1))])) 2827132718Skan ;; Step 8 2828132718Skan ;; H1 = H0 + e * H0 in f8 2829132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 2830132718Skan (parallel [(set (match_dup 3) 2831132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 4)) 2832132718Skan (match_dup 4))) 2833132718Skan (use (const_int 1))])) 2834132718Skan ;; Step 9 2835132718Skan ;; d1 = a - S1 * S1 in f9 2836132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 2837132718Skan (parallel [(set (match_dup 4) 2838132718Skan (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 7))) 2839132718Skan (match_dup 8))) 2840132718Skan (use (const_int 1))])) 2841132718Skan ;; Step 10 2842132718Skan ;; S = S1 + d1 * H1 in f7 2843132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 2844132718Skan (parallel [(set (match_dup 0) 2845132718Skan (float_truncate:SF 2846132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 3)) 2847132718Skan (match_dup 7)))) 2848132718Skan (use (const_int 0))]))] 2849132718Skan{ 2850132718Skan /* Generate 82-bit versions of the input and output operands. */ 2851132718Skan operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0])); 2852132718Skan operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1])); 2853132718Skan /* Generate required floating-point constants. */ 2854132718Skan operands[9] = CONST0_RTX (XFmode); 2855132718Skan} 2856132718Skan [(set_attr "predicable" "no")]) 285790075Sobrien 285890075Sobrien;; :::::::::::::::::::: 285990075Sobrien;; :: 286090075Sobrien;; :: 64 bit floating point arithmetic 286190075Sobrien;; :: 286290075Sobrien;; :::::::::::::::::::: 286390075Sobrien 286490075Sobrien(define_insn "adddf3" 286590075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 286690075Sobrien (plus:DF (match_operand:DF 1 "fr_register_operand" "%f") 286790075Sobrien (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))] 286890075Sobrien "" 286990075Sobrien "fadd.d %0 = %1, %F2" 287090075Sobrien [(set_attr "itanium_class" "fmac")]) 287190075Sobrien 287290075Sobrien(define_insn "*adddf3_trunc" 287390075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 287490075Sobrien (float_truncate:SF 287590075Sobrien (plus:DF (match_operand:DF 1 "fr_register_operand" "%f") 287690075Sobrien (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))] 287790075Sobrien "" 287890075Sobrien "fadd.s %0 = %1, %F2" 287990075Sobrien [(set_attr "itanium_class" "fmac")]) 288090075Sobrien 288190075Sobrien(define_insn "subdf3" 288290075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 288390075Sobrien (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG") 288490075Sobrien (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))] 288590075Sobrien "" 288690075Sobrien "fsub.d %0 = %F1, %F2" 288790075Sobrien [(set_attr "itanium_class" "fmac")]) 288890075Sobrien 288990075Sobrien(define_insn "*subdf3_trunc" 289090075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 289190075Sobrien (float_truncate:SF 289290075Sobrien (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG") 289390075Sobrien (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))] 289490075Sobrien "" 289590075Sobrien "fsub.s %0 = %F1, %F2" 289690075Sobrien [(set_attr "itanium_class" "fmac")]) 289790075Sobrien 289890075Sobrien(define_insn "muldf3" 289990075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 290090075Sobrien (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 290190075Sobrien (match_operand:DF 2 "fr_register_operand" "f")))] 290290075Sobrien "" 290390075Sobrien "fmpy.d %0 = %1, %2" 290490075Sobrien [(set_attr "itanium_class" "fmac")]) 290590075Sobrien 290690075Sobrien(define_insn "*muldf3_trunc" 290790075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 290890075Sobrien (float_truncate:SF 290990075Sobrien (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 291090075Sobrien (match_operand:DF 2 "fr_register_operand" "f"))))] 291190075Sobrien "" 291290075Sobrien "fmpy.s %0 = %1, %2" 291390075Sobrien [(set_attr "itanium_class" "fmac")]) 291490075Sobrien 291590075Sobrien(define_insn "absdf2" 291690075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 291790075Sobrien (abs:DF (match_operand:DF 1 "fr_register_operand" "f")))] 291890075Sobrien "" 291990075Sobrien "fabs %0 = %1" 292090075Sobrien [(set_attr "itanium_class" "fmisc")]) 292190075Sobrien 292290075Sobrien(define_insn "negdf2" 292390075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 292490075Sobrien (neg:DF (match_operand:DF 1 "fr_register_operand" "f")))] 292590075Sobrien "" 292690075Sobrien "fneg %0 = %1" 292790075Sobrien [(set_attr "itanium_class" "fmisc")]) 292890075Sobrien 292990075Sobrien(define_insn "*nabsdf2" 293090075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 293190075Sobrien (neg:DF (abs:DF (match_operand:DF 1 "fr_register_operand" "f"))))] 293290075Sobrien "" 293390075Sobrien "fnegabs %0 = %1" 293490075Sobrien [(set_attr "itanium_class" "fmisc")]) 293590075Sobrien 293690075Sobrien(define_insn "mindf3" 293790075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 293890075Sobrien (smin:DF (match_operand:DF 1 "fr_register_operand" "f") 293990075Sobrien (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))] 294090075Sobrien "" 294190075Sobrien "fmin %0 = %1, %F2" 294290075Sobrien [(set_attr "itanium_class" "fmisc")]) 294390075Sobrien 294490075Sobrien(define_insn "maxdf3" 294590075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 294690075Sobrien (smax:DF (match_operand:DF 1 "fr_register_operand" "f") 294790075Sobrien (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))] 294890075Sobrien "" 294990075Sobrien "fmax %0 = %1, %F2" 295090075Sobrien [(set_attr "itanium_class" "fmisc")]) 295190075Sobrien 295290075Sobrien(define_insn "*madddf4" 295390075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 295490075Sobrien (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 295590075Sobrien (match_operand:DF 2 "fr_register_operand" "f")) 295690075Sobrien (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))] 295790075Sobrien "" 295890075Sobrien "fma.d %0 = %1, %2, %F3" 295990075Sobrien [(set_attr "itanium_class" "fmac")]) 296090075Sobrien 296190075Sobrien(define_insn "*madddf4_trunc" 296290075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 296390075Sobrien (float_truncate:SF 296490075Sobrien (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 296590075Sobrien (match_operand:DF 2 "fr_register_operand" "f")) 296690075Sobrien (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))] 296790075Sobrien "" 296890075Sobrien "fma.s %0 = %1, %2, %F3" 296990075Sobrien [(set_attr "itanium_class" "fmac")]) 297090075Sobrien 297190075Sobrien(define_insn "*msubdf4" 297290075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 297390075Sobrien (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 297490075Sobrien (match_operand:DF 2 "fr_register_operand" "f")) 297590075Sobrien (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))] 297690075Sobrien "" 297790075Sobrien "fms.d %0 = %1, %2, %F3" 297890075Sobrien [(set_attr "itanium_class" "fmac")]) 297990075Sobrien 298090075Sobrien(define_insn "*msubdf4_trunc" 298190075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 298290075Sobrien (float_truncate:SF 298390075Sobrien (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 298490075Sobrien (match_operand:DF 2 "fr_register_operand" "f")) 298590075Sobrien (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))] 298690075Sobrien "" 298790075Sobrien "fms.s %0 = %1, %2, %F3" 298890075Sobrien [(set_attr "itanium_class" "fmac")]) 298990075Sobrien 299090075Sobrien(define_insn "*nmuldf3" 299190075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 299290075Sobrien (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 299390075Sobrien (match_operand:DF 2 "fr_register_operand" "f"))))] 299490075Sobrien "" 299590075Sobrien "fnmpy.d %0 = %1, %2" 299690075Sobrien [(set_attr "itanium_class" "fmac")]) 299790075Sobrien 299890075Sobrien(define_insn "*nmuldf3_trunc" 299990075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 300090075Sobrien (float_truncate:SF 300190075Sobrien (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 300290075Sobrien (match_operand:DF 2 "fr_register_operand" "f")))))] 300390075Sobrien "" 300490075Sobrien "fnmpy.s %0 = %1, %2" 300590075Sobrien [(set_attr "itanium_class" "fmac")]) 300690075Sobrien 300790075Sobrien;; ??? Is it possible to canonicalize this as (minus (reg) (mult))? 300890075Sobrien 300990075Sobrien(define_insn "*nmadddf4" 301090075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 301190075Sobrien (plus:DF (neg:DF (mult:DF 301290075Sobrien (match_operand:DF 1 "fr_register_operand" "f") 301390075Sobrien (match_operand:DF 2 "fr_register_operand" "f"))) 301490075Sobrien (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))] 301590075Sobrien "" 301690075Sobrien "fnma.d %0 = %1, %2, %F3" 301790075Sobrien [(set_attr "itanium_class" "fmac")]) 301890075Sobrien 301990075Sobrien(define_insn "*nmadddf4_alts" 302090075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 302190075Sobrien (plus:DF (neg:DF (mult:DF 302290075Sobrien (match_operand:DF 1 "fr_register_operand" "f") 302390075Sobrien (match_operand:DF 2 "fr_register_operand" "f"))) 302490075Sobrien (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))) 302590075Sobrien (use (match_operand:SI 4 "const_int_operand" ""))] 302690075Sobrien "" 302790075Sobrien "fnma.d.s%4 %0 = %1, %2, %F3" 302890075Sobrien [(set_attr "itanium_class" "fmac")]) 302990075Sobrien 303090075Sobrien(define_insn "*nmadddf4_trunc" 303190075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 303290075Sobrien (float_truncate:SF 303390075Sobrien (plus:DF (neg:DF (mult:DF 303490075Sobrien (match_operand:DF 1 "fr_register_operand" "f") 303590075Sobrien (match_operand:DF 2 "fr_register_operand" "f"))) 303690075Sobrien (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))] 303790075Sobrien "" 303890075Sobrien "fnma.s %0 = %1, %2, %F3" 303990075Sobrien [(set_attr "itanium_class" "fmac")]) 304090075Sobrien 304190075Sobrien(define_expand "divdf3" 304290075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "") 304390075Sobrien (div:DF (match_operand:DF 1 "fr_register_operand" "") 304490075Sobrien (match_operand:DF 2 "fr_register_operand" "")))] 3045132718Skan "TARGET_INLINE_FLOAT_DIV" 304690075Sobrien{ 304790075Sobrien rtx insn; 3048117395Skan if (TARGET_INLINE_FLOAT_DIV_LAT) 304990075Sobrien insn = gen_divdf3_internal_lat (operands[0], operands[1], operands[2]); 305090075Sobrien else 305190075Sobrien insn = gen_divdf3_internal_thr (operands[0], operands[1], operands[2]); 305290075Sobrien emit_insn (insn); 305390075Sobrien DONE; 3054117395Skan}) 305590075Sobrien 305690075Sobrien(define_insn_and_split "divdf3_internal_lat" 305790075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=&f") 305890075Sobrien (div:DF (match_operand:DF 1 "fr_register_operand" "f") 305990075Sobrien (match_operand:DF 2 "fr_register_operand" "f"))) 3060132718Skan (clobber (match_scratch:XF 3 "=&f")) 3061132718Skan (clobber (match_scratch:XF 4 "=&f")) 3062132718Skan (clobber (match_scratch:XF 5 "=&f")) 306390075Sobrien (clobber (match_scratch:BI 6 "=c"))] 3064132718Skan "TARGET_INLINE_FLOAT_DIV_LAT" 306590075Sobrien "#" 306690075Sobrien "&& reload_completed" 3067132718Skan [(parallel [(set (match_dup 7) (div:XF (const_int 1) (match_dup 9))) 3068117395Skan (set (match_dup 6) (unspec:BI [(match_dup 8) (match_dup 9)] 3069117395Skan UNSPEC_FR_RECIP_APPROX)) 307090075Sobrien (use (const_int 1))]) 307190075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 3072132718Skan (parallel [(set (match_dup 3) (mult:XF (match_dup 8) (match_dup 7))) 307390075Sobrien (use (const_int 1))])) 307490075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 307590075Sobrien (parallel [(set (match_dup 4) 3076132718Skan (plus:XF (neg:XF (mult:XF (match_dup 9) (match_dup 7))) 307790075Sobrien (match_dup 12))) 307890075Sobrien (use (const_int 1))])) 307990075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 308090075Sobrien (parallel [(set (match_dup 3) 3081132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 3)) 308290075Sobrien (match_dup 3))) 308390075Sobrien (use (const_int 1))])) 308490075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 3085132718Skan (parallel [(set (match_dup 5) (mult:XF (match_dup 4) (match_dup 4))) 308690075Sobrien (use (const_int 1))])) 308790075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 308890075Sobrien (parallel [(set (match_dup 7) 3089132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 7)) 309090075Sobrien (match_dup 7))) 309190075Sobrien (use (const_int 1))])) 309290075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 309390075Sobrien (parallel [(set (match_dup 3) 3094132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 3)) 309590075Sobrien (match_dup 3))) 309690075Sobrien (use (const_int 1))])) 309790075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 3098132718Skan (parallel [(set (match_dup 4) (mult:XF (match_dup 5) (match_dup 5))) 309990075Sobrien (use (const_int 1))])) 310090075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 310190075Sobrien (parallel [(set (match_dup 7) 3102132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 7)) 310390075Sobrien (match_dup 7))) 310490075Sobrien (use (const_int 1))])) 310590075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 310690075Sobrien (parallel [(set (match_dup 10) 310790075Sobrien (float_truncate:DF 3108132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 3)) 310990075Sobrien (match_dup 3)))) 311090075Sobrien (use (const_int 1))])) 311190075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 311290075Sobrien (parallel [(set (match_dup 7) 3113132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 7)) 311490075Sobrien (match_dup 7))) 311590075Sobrien (use (const_int 1))])) 311690075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 311790075Sobrien (parallel [(set (match_dup 11) 311890075Sobrien (float_truncate:DF 3119132718Skan (plus:XF (neg:XF (mult:XF (match_dup 9) (match_dup 3))) 312090075Sobrien (match_dup 8)))) 312190075Sobrien (use (const_int 1))])) 312290075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 312390075Sobrien (set (match_dup 0) 3124132718Skan (float_truncate:DF (plus:XF (mult:XF (match_dup 5) (match_dup 7)) 312590075Sobrien (match_dup 3))))) 312690075Sobrien ] 3127117395Skan{ 3128132718Skan operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0])); 3129132718Skan operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1])); 3130132718Skan operands[9] = gen_rtx_REG (XFmode, REGNO (operands[2])); 3131117395Skan operands[10] = gen_rtx_REG (DFmode, REGNO (operands[3])); 3132117395Skan operands[11] = gen_rtx_REG (DFmode, REGNO (operands[5])); 3133132718Skan operands[12] = CONST1_RTX (XFmode); 3134117395Skan} 313590075Sobrien [(set_attr "predicable" "no")]) 313690075Sobrien 313790075Sobrien(define_insn_and_split "divdf3_internal_thr" 313890075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=&f") 313990075Sobrien (div:DF (match_operand:DF 1 "fr_register_operand" "f") 314090075Sobrien (match_operand:DF 2 "fr_register_operand" "f"))) 3141132718Skan (clobber (match_scratch:XF 3 "=&f")) 314290075Sobrien (clobber (match_scratch:DF 4 "=f")) 314390075Sobrien (clobber (match_scratch:BI 5 "=c"))] 3144132718Skan "TARGET_INLINE_FLOAT_DIV_THR" 314590075Sobrien "#" 314690075Sobrien "&& reload_completed" 3147132718Skan [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8))) 3148117395Skan (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)] 3149117395Skan UNSPEC_FR_RECIP_APPROX)) 315090075Sobrien (use (const_int 1))]) 315190075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 315290075Sobrien (parallel [(set (match_dup 3) 3153132718Skan (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 6))) 315490075Sobrien (match_dup 10))) 315590075Sobrien (use (const_int 1))])) 315690075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 315790075Sobrien (parallel [(set (match_dup 6) 3158132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 6)) 315990075Sobrien (match_dup 6))) 316090075Sobrien (use (const_int 1))])) 316190075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 316290075Sobrien (parallel [(set (match_dup 3) 3163132718Skan (mult:XF (match_dup 3) (match_dup 3))) 316490075Sobrien (use (const_int 1))])) 316590075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 316690075Sobrien (parallel [(set (match_dup 6) 3167132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 6)) 316890075Sobrien (match_dup 6))) 316990075Sobrien (use (const_int 1))])) 317090075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 317190075Sobrien (parallel [(set (match_dup 3) 3172132718Skan (mult:XF (match_dup 3) (match_dup 3))) 317390075Sobrien (use (const_int 1))])) 317490075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 317590075Sobrien (parallel [(set (match_dup 6) 3176132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 6)) 317790075Sobrien (match_dup 6))) 317890075Sobrien (use (const_int 1))])) 317990075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 318090075Sobrien (parallel [(set (match_dup 9) 318190075Sobrien (float_truncate:DF 3182132718Skan (mult:XF (match_dup 7) (match_dup 3)))) 318390075Sobrien (use (const_int 1))])) 318490075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 318590075Sobrien (parallel [(set (match_dup 4) 318690075Sobrien (plus:DF (neg:DF (mult:DF (match_dup 2) (match_dup 9))) 318790075Sobrien (match_dup 1))) 318890075Sobrien (use (const_int 1))])) 318990075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 319090075Sobrien (set (match_dup 0) 319190075Sobrien (plus:DF (mult:DF (match_dup 4) (match_dup 0)) 319290075Sobrien (match_dup 9)))) 319390075Sobrien ] 3194117395Skan{ 3195132718Skan operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0])); 3196132718Skan operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1])); 3197132718Skan operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2])); 3198117395Skan operands[9] = gen_rtx_REG (DFmode, REGNO (operands[3])); 3199132718Skan operands[10] = CONST1_RTX (XFmode); 3200117395Skan} 320190075Sobrien [(set_attr "predicable" "no")]) 3202132718Skan 3203132718Skan;; Inline square root. 3204132718Skan 3205132718Skan(define_expand "sqrtdf2" 3206132718Skan [(set (match_operand:DF 0 "fr_register_operand" "=&f") 3207132718Skan (sqrt:DF (match_operand:DF 1 "fr_register_operand" "f")))] 3208132718Skan "TARGET_INLINE_SQRT" 3209132718Skan{ 3210132718Skan rtx insn; 3211132718Skan if (TARGET_INLINE_SQRT_LAT) 3212132718Skan#if 0 3213132718Skan insn = gen_sqrtdf2_internal_lat (operands[0], operands[1]); 3214132718Skan#else 3215132718Skan abort (); 3216132718Skan#endif 3217132718Skan else 3218132718Skan insn = gen_sqrtdf2_internal_thr (operands[0], operands[1]); 3219132718Skan emit_insn (insn); 3220132718Skan DONE; 3221132718Skan}) 3222132718Skan 3223132718Skan;; Latency-optimized square root. 3224132718Skan;; FIXME: Implement. 3225132718Skan 3226132718Skan;; Throughput-optimized square root. 3227132718Skan 3228132718Skan(define_insn_and_split "sqrtdf2_internal_thr" 3229132718Skan [(set (match_operand:DF 0 "fr_register_operand" "=&f") 3230132718Skan (sqrt:DF (match_operand:DF 1 "fr_register_operand" "f"))) 3231132718Skan ;; Register r2 in optimization guide. 3232132718Skan (clobber (match_scratch:DI 2 "=r")) 3233132718Skan ;; Register f8 in optimization guide 3234132718Skan (clobber (match_scratch:XF 3 "=&f")) 3235132718Skan ;; Register f9 in optimization guide 3236132718Skan (clobber (match_scratch:XF 4 "=&f")) 3237132718Skan ;; Register f10 in optimization guide 3238132718Skan (clobber (match_scratch:XF 5 "=&f")) 3239132718Skan ;; Register p6 in optimization guide. 3240132718Skan (clobber (match_scratch:BI 6 "=c"))] 3241132718Skan "TARGET_INLINE_SQRT_THR" 3242132718Skan "#" 3243132718Skan "&& reload_completed" 3244132718Skan [ ;; exponent of +1/2 in r2 3245132718Skan (set (match_dup 2) (const_int 65534)) 3246132718Skan ;; +1/2 in f10 3247132718Skan (set (match_dup 5) 3248132718Skan (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP)) 3249132718Skan ;; Step 1 3250132718Skan ;; y0 = 1/sqrt(a) in f7 3251132718Skan (parallel [(set (match_dup 7) 3252132718Skan (div:XF (const_int 1) 3253132718Skan (sqrt:XF (match_dup 8)))) 3254132718Skan (set (match_dup 6) 3255132718Skan (unspec:BI [(match_dup 8)] 3256132718Skan UNSPEC_FR_SQRT_RECIP_APPROX)) 3257132718Skan (use (const_int 0))]) 3258132718Skan ;; Step 2 3259132718Skan ;; H0 = 1/2 * y0 in f8 3260132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3261132718Skan (parallel [(set (match_dup 3) 3262132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 7)) 3263132718Skan (match_dup 9))) 3264132718Skan (use (const_int 1))])) 3265132718Skan ;; Step 3 3266132718Skan ;; G0 = a * y0 in f7 3267132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3268132718Skan (parallel [(set (match_dup 7) 3269132718Skan (plus:XF (mult:XF (match_dup 8) (match_dup 7)) 3270132718Skan (match_dup 9))) 3271132718Skan (use (const_int 1))])) 3272132718Skan ;; Step 4 3273132718Skan ;; r0 = 1/2 - G0 * H0 in f9 3274132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3275132718Skan (parallel [(set (match_dup 4) 3276132718Skan (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 3))) 3277132718Skan (match_dup 5))) 3278132718Skan (use (const_int 1))])) 3279132718Skan ;; Step 5 3280132718Skan ;; H1 = H0 + r0 * H0 in f8 3281132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3282132718Skan (parallel [(set (match_dup 3) 3283132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 3)) 3284132718Skan (match_dup 3))) 3285132718Skan (use (const_int 1))])) 3286132718Skan ;; Step 6 3287132718Skan ;; G1 = G0 + r0 * G0 in f7 3288132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3289132718Skan (parallel [(set (match_dup 7) 3290132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 7)) 3291132718Skan (match_dup 7))) 3292132718Skan (use (const_int 1))])) 3293132718Skan ;; Step 7 3294132718Skan ;; r1 = 1/2 - G1 * H1 in f9 3295132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3296132718Skan (parallel [(set (match_dup 4) 3297132718Skan (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 3))) 3298132718Skan (match_dup 5))) 3299132718Skan (use (const_int 1))])) 3300132718Skan ;; Step 8 3301132718Skan ;; H2 = H1 + r1 * H1 in f8 3302132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3303132718Skan (parallel [(set (match_dup 3) 3304132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 3)) 3305132718Skan (match_dup 3))) 3306132718Skan (use (const_int 1))])) 3307132718Skan ;; Step 9 3308132718Skan ;; G2 = G1 + r1 * G1 in f7 3309132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3310132718Skan (parallel [(set (match_dup 7) 3311132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 7)) 3312132718Skan (match_dup 7))) 3313132718Skan (use (const_int 1))])) 3314132718Skan ;; Step 10 3315132718Skan ;; d2 = a - G2 * G2 in f9 3316132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3317132718Skan (parallel [(set (match_dup 4) 3318132718Skan (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 7))) 3319132718Skan (match_dup 8))) 3320132718Skan (use (const_int 1))])) 3321132718Skan ;; Step 11 3322132718Skan ;; G3 = G2 + d2 * H2 in f7 3323132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3324132718Skan (parallel [(set (match_dup 7) 3325132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 3)) 3326132718Skan (match_dup 7))) 3327132718Skan (use (const_int 1))])) 3328132718Skan ;; Step 12 3329132718Skan ;; d3 = a - G3 * G3 in f9 3330132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3331132718Skan (parallel [(set (match_dup 4) 3332132718Skan (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 7))) 3333132718Skan (match_dup 8))) 3334132718Skan (use (const_int 1))])) 3335132718Skan ;; Step 13 3336132718Skan ;; S = G3 + d3 * H2 in f7 3337132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3338132718Skan (parallel [(set (match_dup 0) 3339132718Skan (float_truncate:DF 3340132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 3)) 3341132718Skan (match_dup 7)))) 3342132718Skan (use (const_int 0))]))] 3343132718Skan{ 3344132718Skan /* Generate 82-bit versions of the input and output operands. */ 3345132718Skan operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0])); 3346132718Skan operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1])); 3347132718Skan /* Generate required floating-point constants. */ 3348132718Skan operands[9] = CONST0_RTX (XFmode); 3349132718Skan} 3350132718Skan [(set_attr "predicable" "no")]) 335190075Sobrien 335290075Sobrien;; :::::::::::::::::::: 335390075Sobrien;; :: 335490075Sobrien;; :: 80 bit floating point arithmetic 335590075Sobrien;; :: 335690075Sobrien;; :::::::::::::::::::: 335790075Sobrien 3358132718Skan(define_insn "addxf3" 3359132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3360132718Skan (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3361132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))] 3362132718Skan "" 336390075Sobrien "fadd %0 = %F1, %F2" 336490075Sobrien [(set_attr "itanium_class" "fmac")]) 336590075Sobrien 3366132718Skan(define_insn "*addxf3_truncsf" 336790075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 336890075Sobrien (float_truncate:SF 3369132718Skan (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3370132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))] 3371132718Skan "" 337290075Sobrien "fadd.s %0 = %F1, %F2" 337390075Sobrien [(set_attr "itanium_class" "fmac")]) 337490075Sobrien 3375132718Skan(define_insn "*addxf3_truncdf" 337690075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 337790075Sobrien (float_truncate:DF 3378132718Skan (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3379132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))] 3380132718Skan "" 338190075Sobrien "fadd.d %0 = %F1, %F2" 338290075Sobrien [(set_attr "itanium_class" "fmac")]) 338390075Sobrien 3384132718Skan(define_insn "subxf3" 3385132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3386132718Skan (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3387132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))] 3388132718Skan "" 338990075Sobrien "fsub %0 = %F1, %F2" 339090075Sobrien [(set_attr "itanium_class" "fmac")]) 339190075Sobrien 3392132718Skan(define_insn "*subxf3_truncsf" 339390075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 339490075Sobrien (float_truncate:SF 3395132718Skan (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3396132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))] 3397132718Skan "" 339890075Sobrien "fsub.s %0 = %F1, %F2" 339990075Sobrien [(set_attr "itanium_class" "fmac")]) 340090075Sobrien 3401132718Skan(define_insn "*subxf3_truncdf" 340290075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 340390075Sobrien (float_truncate:DF 3404132718Skan (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3405132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))] 3406132718Skan "" 340790075Sobrien "fsub.d %0 = %F1, %F2" 340890075Sobrien [(set_attr "itanium_class" "fmac")]) 340990075Sobrien 3410132718Skan(define_insn "mulxf3" 3411132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3412132718Skan (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3413132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))] 3414132718Skan "" 341590075Sobrien "fmpy %0 = %F1, %F2" 341690075Sobrien [(set_attr "itanium_class" "fmac")]) 341790075Sobrien 3418132718Skan(define_insn "*mulxf3_truncsf" 341990075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 342090075Sobrien (float_truncate:SF 3421132718Skan (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3422132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))] 3423132718Skan "" 342490075Sobrien "fmpy.s %0 = %F1, %F2" 342590075Sobrien [(set_attr "itanium_class" "fmac")]) 342690075Sobrien 3427132718Skan(define_insn "*mulxf3_truncdf" 342890075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 342990075Sobrien (float_truncate:DF 3430132718Skan (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3431132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))] 3432132718Skan "" 343390075Sobrien "fmpy.d %0 = %F1, %F2" 343490075Sobrien [(set_attr "itanium_class" "fmac")]) 343590075Sobrien 3436132718Skan(define_insn "*mulxf3_alts" 3437132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3438132718Skan (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3439132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))) 344090075Sobrien (use (match_operand:SI 3 "const_int_operand" ""))] 3441132718Skan "" 344290075Sobrien "fmpy.s%3 %0 = %F1, %F2" 344390075Sobrien [(set_attr "itanium_class" "fmac")]) 344490075Sobrien 3445132718Skan(define_insn "*mulxf3_truncsf_alts" 344690075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 344790075Sobrien (float_truncate:SF 3448132718Skan (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3449132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))) 345090075Sobrien (use (match_operand:SI 3 "const_int_operand" ""))] 3451132718Skan "" 345290075Sobrien "fmpy.s.s%3 %0 = %F1, %F2" 345390075Sobrien [(set_attr "itanium_class" "fmac")]) 345490075Sobrien 3455132718Skan(define_insn "*mulxf3_truncdf_alts" 345690075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 345790075Sobrien (float_truncate:DF 3458132718Skan (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3459132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))) 346090075Sobrien (use (match_operand:SI 3 "const_int_operand" ""))] 3461132718Skan "" 346290075Sobrien "fmpy.d.s%3 %0 = %F1, %F2" 346390075Sobrien [(set_attr "itanium_class" "fmac")]) 346490075Sobrien 3465132718Skan(define_insn "absxf2" 3466132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3467132718Skan (abs:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")))] 3468132718Skan "" 346990075Sobrien "fabs %0 = %F1" 347090075Sobrien [(set_attr "itanium_class" "fmisc")]) 347190075Sobrien 3472132718Skan(define_insn "negxf2" 3473132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3474132718Skan (neg:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")))] 3475132718Skan "" 347690075Sobrien "fneg %0 = %F1" 347790075Sobrien [(set_attr "itanium_class" "fmisc")]) 347890075Sobrien 3479132718Skan(define_insn "*nabsxf2" 3480132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3481132718Skan (neg:XF (abs:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG"))))] 3482132718Skan "" 348390075Sobrien "fnegabs %0 = %F1" 348490075Sobrien [(set_attr "itanium_class" "fmisc")]) 348590075Sobrien 3486132718Skan(define_insn "minxf3" 3487132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3488132718Skan (smin:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3489132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))] 3490132718Skan "" 349190075Sobrien "fmin %0 = %F1, %F2" 349290075Sobrien [(set_attr "itanium_class" "fmisc")]) 349390075Sobrien 3494132718Skan(define_insn "maxxf3" 3495132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3496132718Skan (smax:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3497132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))] 3498132718Skan "" 349990075Sobrien "fmax %0 = %F1, %F2" 350090075Sobrien [(set_attr "itanium_class" "fmisc")]) 350190075Sobrien 3502132718Skan(define_insn "*maddxf4" 3503132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3504132718Skan (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3505132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) 3506132718Skan (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))] 3507132718Skan "" 350890075Sobrien "fma %0 = %F1, %F2, %F3" 350990075Sobrien [(set_attr "itanium_class" "fmac")]) 351090075Sobrien 3511132718Skan(define_insn "*maddxf4_truncsf" 351290075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 351390075Sobrien (float_truncate:SF 3514132718Skan (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3515132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) 3516132718Skan (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))] 3517132718Skan "" 351890075Sobrien "fma.s %0 = %F1, %F2, %F3" 351990075Sobrien [(set_attr "itanium_class" "fmac")]) 352090075Sobrien 3521132718Skan(define_insn "*maddxf4_truncdf" 352290075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 352390075Sobrien (float_truncate:DF 3524132718Skan (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3525132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) 3526132718Skan (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))] 3527132718Skan "" 352890075Sobrien "fma.d %0 = %F1, %F2, %F3" 352990075Sobrien [(set_attr "itanium_class" "fmac")]) 353090075Sobrien 3531132718Skan(define_insn "*maddxf4_alts" 3532132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3533132718Skan (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3534132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) 3535132718Skan (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))) 353690075Sobrien (use (match_operand:SI 4 "const_int_operand" ""))] 3537132718Skan "" 353890075Sobrien "fma.s%4 %0 = %F1, %F2, %F3" 353990075Sobrien [(set_attr "itanium_class" "fmac")]) 354090075Sobrien 3541132718Skan(define_insn "*maddxf4_alts_truncsf" 3542132718Skan [(set (match_operand:SF 0 "fr_register_operand" "=f") 3543132718Skan (float_truncate:SF 3544132718Skan (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3545132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) 3546132718Skan (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))) 3547132718Skan (use (match_operand:SI 4 "const_int_operand" ""))] 3548132718Skan "" 3549132718Skan "fma.s.s%4 %0 = %F1, %F2, %F3" 3550132718Skan [(set_attr "itanium_class" "fmac")]) 3551132718Skan 3552132718Skan(define_insn "*maddxf4_alts_truncdf" 355390075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 355490075Sobrien (float_truncate:DF 3555132718Skan (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3556132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) 3557132718Skan (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))) 355890075Sobrien (use (match_operand:SI 4 "const_int_operand" ""))] 3559132718Skan "" 356090075Sobrien "fma.d.s%4 %0 = %F1, %F2, %F3" 356190075Sobrien [(set_attr "itanium_class" "fmac")]) 356290075Sobrien 3563132718Skan(define_insn "*msubxf4" 3564132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3565132718Skan (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3566132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) 3567132718Skan (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))] 3568132718Skan "" 356990075Sobrien "fms %0 = %F1, %F2, %F3" 357090075Sobrien [(set_attr "itanium_class" "fmac")]) 357190075Sobrien 3572132718Skan(define_insn "*msubxf4_truncsf" 357390075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 357490075Sobrien (float_truncate:SF 3575132718Skan (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3576132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) 3577132718Skan (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))] 3578132718Skan "" 357990075Sobrien "fms.s %0 = %F1, %F2, %F3" 358090075Sobrien [(set_attr "itanium_class" "fmac")]) 358190075Sobrien 3582132718Skan(define_insn "*msubxf4_truncdf" 358390075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 358490075Sobrien (float_truncate:DF 3585132718Skan (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3586132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) 3587132718Skan (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))] 3588132718Skan "" 358990075Sobrien "fms.d %0 = %F1, %F2, %F3" 359090075Sobrien [(set_attr "itanium_class" "fmac")]) 359190075Sobrien 3592132718Skan(define_insn "*nmulxf3" 3593132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3594132718Skan (neg:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3595132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))] 3596132718Skan "" 359790075Sobrien "fnmpy %0 = %F1, %F2" 359890075Sobrien [(set_attr "itanium_class" "fmac")]) 359990075Sobrien 3600132718Skan(define_insn "*nmulxf3_truncsf" 360190075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 360290075Sobrien (float_truncate:SF 3603132718Skan (neg:XF (mult:XF 3604132718Skan (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3605132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))))] 3606132718Skan "" 360790075Sobrien "fnmpy.s %0 = %F1, %F2" 360890075Sobrien [(set_attr "itanium_class" "fmac")]) 360990075Sobrien 3610132718Skan(define_insn "*nmulxf3_truncdf" 361190075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 361290075Sobrien (float_truncate:DF 3613132718Skan (neg:XF (mult:XF 3614132718Skan (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3615132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))))] 3616132718Skan "" 361790075Sobrien "fnmpy.d %0 = %F1, %F2" 361890075Sobrien [(set_attr "itanium_class" "fmac")]) 361990075Sobrien 362090075Sobrien;; ??? Is it possible to canonicalize this as (minus (reg) (mult))? 362190075Sobrien 3622132718Skan(define_insn "*nmaddxf4" 3623132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3624132718Skan (plus:XF (neg:XF (mult:XF 3625132718Skan (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3626132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))) 3627132718Skan (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))] 3628132718Skan "" 362990075Sobrien "fnma %0 = %F1, %F2, %F3" 363090075Sobrien [(set_attr "itanium_class" "fmac")]) 363190075Sobrien 3632132718Skan(define_insn "*nmaddxf4_truncsf" 363390075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 363490075Sobrien (float_truncate:SF 3635132718Skan (plus:XF (neg:XF (mult:XF 3636132718Skan (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3637132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))) 3638132718Skan (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))] 3639132718Skan "" 364090075Sobrien "fnma.s %0 = %F1, %F2, %F3" 364190075Sobrien [(set_attr "itanium_class" "fmac")]) 364290075Sobrien 3643132718Skan(define_insn "*nmaddxf4_truncdf" 364490075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 364590075Sobrien (float_truncate:DF 3646132718Skan (plus:XF (neg:XF (mult:XF 3647132718Skan (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3648132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))) 3649132718Skan (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))] 3650132718Skan "" 365190075Sobrien "fnma.d %0 = %F1, %F2, %F3" 365290075Sobrien [(set_attr "itanium_class" "fmac")]) 365390075Sobrien 3654132718Skan(define_insn "*nmaddxf4_alts" 3655132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3656132718Skan (plus:XF (neg:XF (mult:XF 3657132718Skan (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3658132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))) 3659132718Skan (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))) 366090075Sobrien (use (match_operand:SI 4 "const_int_operand" ""))] 3661132718Skan "" 366290075Sobrien "fnma.s%4 %0 = %F1, %F2, %F3" 366390075Sobrien [(set_attr "itanium_class" "fmac")]) 366490075Sobrien 3665132718Skan(define_insn "*nmaddxf4_truncdf_alts" 366690075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 366790075Sobrien (float_truncate:DF 3668132718Skan (plus:XF (neg:XF 3669132718Skan (mult:XF 3670132718Skan (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3671132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))) 3672132718Skan (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))) 367390075Sobrien (use (match_operand:SI 4 "const_int_operand" ""))] 3674132718Skan "" 367590075Sobrien "fnma.d.s%4 %0 = %F1, %F2, %F3" 367690075Sobrien [(set_attr "itanium_class" "fmac")]) 367790075Sobrien 3678132718Skan(define_expand "divxf3" 3679132718Skan [(set (match_operand:XF 0 "fr_register_operand" "") 3680132718Skan (div:XF (match_operand:XF 1 "fr_register_operand" "") 3681132718Skan (match_operand:XF 2 "fr_register_operand" "")))] 3682132718Skan "TARGET_INLINE_FLOAT_DIV" 368390075Sobrien{ 368490075Sobrien rtx insn; 3685117395Skan if (TARGET_INLINE_FLOAT_DIV_LAT) 3686132718Skan insn = gen_divxf3_internal_lat (operands[0], operands[1], operands[2]); 368790075Sobrien else 3688132718Skan insn = gen_divxf3_internal_thr (operands[0], operands[1], operands[2]); 368990075Sobrien emit_insn (insn); 369090075Sobrien DONE; 3691117395Skan}) 369290075Sobrien 3693132718Skan(define_insn_and_split "divxf3_internal_lat" 3694132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=&f") 3695132718Skan (div:XF (match_operand:XF 1 "fr_register_operand" "f") 3696132718Skan (match_operand:XF 2 "fr_register_operand" "f"))) 3697132718Skan (clobber (match_scratch:XF 3 "=&f")) 3698132718Skan (clobber (match_scratch:XF 4 "=&f")) 3699132718Skan (clobber (match_scratch:XF 5 "=&f")) 3700132718Skan (clobber (match_scratch:XF 6 "=&f")) 370190075Sobrien (clobber (match_scratch:BI 7 "=c"))] 3702132718Skan "TARGET_INLINE_FLOAT_DIV_LAT" 370390075Sobrien "#" 370490075Sobrien "&& reload_completed" 3705132718Skan [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2))) 3706117395Skan (set (match_dup 7) (unspec:BI [(match_dup 1) (match_dup 2)] 3707117395Skan UNSPEC_FR_RECIP_APPROX)) 370890075Sobrien (use (const_int 1))]) 370990075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 371090075Sobrien (parallel [(set (match_dup 3) 3711132718Skan (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0))) 371290075Sobrien (match_dup 8))) 371390075Sobrien (use (const_int 1))])) 371490075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 3715132718Skan (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0))) 371690075Sobrien (use (const_int 1))])) 371790075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 3718132718Skan (parallel [(set (match_dup 5) (mult:XF (match_dup 3) (match_dup 3))) 371990075Sobrien (use (const_int 1))])) 372090075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 372190075Sobrien (parallel [(set (match_dup 6) 3722132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 3)) 372390075Sobrien (match_dup 3))) 372490075Sobrien (use (const_int 1))])) 372590075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 372690075Sobrien (parallel [(set (match_dup 3) 3727132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 5)) 372890075Sobrien (match_dup 3))) 372990075Sobrien (use (const_int 1))])) 373090075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 373190075Sobrien (parallel [(set (match_dup 5) 3732132718Skan (plus:XF (mult:XF (match_dup 6) (match_dup 0)) 373390075Sobrien (match_dup 0))) 373490075Sobrien (use (const_int 1))])) 373590075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 373690075Sobrien (parallel [(set (match_dup 0) 3737132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 3)) 373890075Sobrien (match_dup 0))) 373990075Sobrien (use (const_int 1))])) 374090075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 374190075Sobrien (parallel [(set (match_dup 4) 3742132718Skan (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 4))) 374390075Sobrien (match_dup 1))) 374490075Sobrien (use (const_int 1))])) 374590075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 374690075Sobrien (parallel [(set (match_dup 3) 3747132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 0)) 374890075Sobrien (match_dup 4))) 374990075Sobrien (use (const_int 1))])) 375090075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 375190075Sobrien (parallel [(set (match_dup 5) 3752132718Skan (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0))) 375390075Sobrien (match_dup 8))) 375490075Sobrien (use (const_int 1))])) 375590075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 375690075Sobrien (parallel [(set (match_dup 0) 3757132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 0)) 375890075Sobrien (match_dup 0))) 375990075Sobrien (use (const_int 1))])) 376090075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 376190075Sobrien (parallel [(set (match_dup 4) 3762132718Skan (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3))) 376390075Sobrien (match_dup 1))) 376490075Sobrien (use (const_int 1))])) 376590075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 376690075Sobrien (set (match_dup 0) 3767132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 0)) 376890075Sobrien (match_dup 3)))) 376990075Sobrien ] 3770132718Skan "operands[8] = CONST1_RTX (XFmode);" 377190075Sobrien [(set_attr "predicable" "no")]) 377290075Sobrien 3773132718Skan(define_insn_and_split "divxf3_internal_thr" 3774132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=&f") 3775132718Skan (div:XF (match_operand:XF 1 "fr_register_operand" "f") 3776132718Skan (match_operand:XF 2 "fr_register_operand" "f"))) 3777132718Skan (clobber (match_scratch:XF 3 "=&f")) 3778132718Skan (clobber (match_scratch:XF 4 "=&f")) 377990075Sobrien (clobber (match_scratch:BI 5 "=c"))] 3780132718Skan "TARGET_INLINE_FLOAT_DIV_THR" 378190075Sobrien "#" 378290075Sobrien "&& reload_completed" 3783132718Skan [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2))) 3784117395Skan (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)] 3785117395Skan UNSPEC_FR_RECIP_APPROX)) 378690075Sobrien (use (const_int 1))]) 378790075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 378890075Sobrien (parallel [(set (match_dup 3) 3789132718Skan (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0))) 379090075Sobrien (match_dup 6))) 379190075Sobrien (use (const_int 1))])) 379290075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 379390075Sobrien (parallel [(set (match_dup 4) 3794132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 0)) 379590075Sobrien (match_dup 0))) 379690075Sobrien (use (const_int 1))])) 379790075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 3798132718Skan (parallel [(set (match_dup 3) (mult:XF (match_dup 3) (match_dup 3))) 379990075Sobrien (use (const_int 1))])) 380090075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 380190075Sobrien (parallel [(set (match_dup 3) 3802132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 4)) 380390075Sobrien (match_dup 4))) 380490075Sobrien (use (const_int 1))])) 380590075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 3806132718Skan (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0))) 380790075Sobrien (use (const_int 1))])) 380890075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 380990075Sobrien (parallel [(set (match_dup 0) 3810132718Skan (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3))) 381190075Sobrien (match_dup 6))) 381290075Sobrien (use (const_int 1))])) 381390075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 381490075Sobrien (parallel [(set (match_dup 0) 3815132718Skan (plus:XF (mult:XF (match_dup 0) (match_dup 3)) 381690075Sobrien (match_dup 3))) 381790075Sobrien (use (const_int 1))])) 381890075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 381990075Sobrien (parallel [(set (match_dup 3) 3820132718Skan (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 4))) 382190075Sobrien (match_dup 1))) 382290075Sobrien (use (const_int 1))])) 382390075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 382490075Sobrien (parallel [(set (match_dup 3) 3825132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 0)) 382690075Sobrien (match_dup 4))) 382790075Sobrien (use (const_int 1))])) 382890075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 382990075Sobrien (parallel [(set (match_dup 4) 3830132718Skan (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0))) 383190075Sobrien (match_dup 6))) 383290075Sobrien (use (const_int 1))])) 383390075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 383490075Sobrien (parallel [(set (match_dup 0) 3835132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 0)) 383690075Sobrien (match_dup 0))) 383790075Sobrien (use (const_int 1))])) 383890075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 383990075Sobrien (parallel [(set (match_dup 4) 3840132718Skan (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3))) 384190075Sobrien (match_dup 1))) 384290075Sobrien (use (const_int 1))])) 384390075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 384490075Sobrien (set (match_dup 0) 3845132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 0)) 384690075Sobrien (match_dup 3)))) 384790075Sobrien ] 3848132718Skan "operands[6] = CONST1_RTX (XFmode);" 384990075Sobrien [(set_attr "predicable" "no")]) 385090075Sobrien 3851132718Skan;; Inline square root. 3852132718Skan 3853132718Skan(define_expand "sqrtxf2" 3854132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=&f") 3855132718Skan (sqrt:XF (match_operand:XF 1 "fr_register_operand" "f")))] 3856132718Skan "TARGET_INLINE_SQRT" 3857132718Skan{ 3858132718Skan rtx insn; 3859132718Skan if (TARGET_INLINE_SQRT_LAT) 3860132718Skan#if 0 3861132718Skan insn = gen_sqrtxf2_internal_lat (operands[0], operands[1]); 3862132718Skan#else 3863132718Skan abort (); 3864132718Skan#endif 3865132718Skan else 3866132718Skan insn = gen_sqrtxf2_internal_thr (operands[0], operands[1]); 3867132718Skan emit_insn (insn); 3868132718Skan DONE; 3869132718Skan}) 3870132718Skan 3871132718Skan;; Latency-optimized square root. 3872132718Skan;; FIXME: Implement. 3873132718Skan 3874132718Skan;; Throughput-optimized square root. 3875132718Skan 3876132718Skan(define_insn_and_split "sqrtxf2_internal_thr" 3877132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=&f") 3878132718Skan (sqrt:XF (match_operand:XF 1 "fr_register_operand" "f"))) 3879132718Skan ;; Register r2 in optimization guide. 3880132718Skan (clobber (match_scratch:DI 2 "=r")) 3881132718Skan ;; Register f8 in optimization guide 3882132718Skan (clobber (match_scratch:XF 3 "=&f")) 3883132718Skan ;; Register f9 in optimization guide 3884132718Skan (clobber (match_scratch:XF 4 "=&f")) 3885132718Skan ;; Register f10 in optimization guide 3886132718Skan (clobber (match_scratch:XF 5 "=&f")) 3887132718Skan ;; Register f11 in optimization guide 3888132718Skan (clobber (match_scratch:XF 6 "=&f")) 3889132718Skan ;; Register p6 in optimization guide. 3890132718Skan (clobber (match_scratch:BI 7 "=c"))] 3891132718Skan "TARGET_INLINE_SQRT_THR" 3892132718Skan "#" 3893132718Skan "&& reload_completed" 3894132718Skan [ ;; exponent of +1/2 in r2 3895132718Skan (set (match_dup 2) (const_int 65534)) 3896132718Skan ;; +1/2 in f8. The Intel manual mistakenly specifies f10. 3897132718Skan (set (match_dup 3) 3898132718Skan (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP)) 3899132718Skan ;; Step 1 3900132718Skan ;; y0 = 1/sqrt(a) in f7 3901132718Skan (parallel [(set (match_dup 8) 3902132718Skan (div:XF (const_int 1) 3903132718Skan (sqrt:XF (match_dup 9)))) 3904132718Skan (set (match_dup 7) 3905132718Skan (unspec:BI [(match_dup 9)] 3906132718Skan UNSPEC_FR_SQRT_RECIP_APPROX)) 3907132718Skan (use (const_int 0))]) 3908132718Skan ;; Step 2 3909132718Skan ;; H0 = 1/2 * y0 in f9 3910132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 3911132718Skan (parallel [(set (match_dup 4) 3912132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 8)) 3913132718Skan (match_dup 10))) 3914132718Skan (use (const_int 1))])) 3915132718Skan ;; Step 3 3916132718Skan ;; S0 = a * y0 in f7 3917132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 3918132718Skan (parallel [(set (match_dup 8) 3919132718Skan (plus:XF (mult:XF (match_dup 9) (match_dup 8)) 3920132718Skan (match_dup 10))) 3921132718Skan (use (const_int 1))])) 3922132718Skan ;; Step 4 3923132718Skan ;; d0 = 1/2 - S0 * H0 in f10 3924132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 3925132718Skan (parallel [(set (match_dup 5) 3926132718Skan (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 4))) 3927132718Skan (match_dup 3))) 3928132718Skan (use (const_int 1))])) 3929132718Skan ;; Step 5 3930132718Skan ;; H1 = H0 + d0 * H0 in f9 3931132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 3932132718Skan (parallel [(set (match_dup 4) 3933132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 4)) 3934132718Skan (match_dup 4))) 3935132718Skan (use (const_int 1))])) 3936132718Skan ;; Step 6 3937132718Skan ;; S1 = S0 + d0 * S0 in f7 3938132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 3939132718Skan (parallel [(set (match_dup 8) 3940132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 8)) 3941132718Skan (match_dup 8))) 3942132718Skan (use (const_int 1))])) 3943132718Skan ;; Step 7 3944132718Skan ;; d1 = 1/2 - S1 * H1 in f10 3945132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 3946132718Skan (parallel [(set (match_dup 5) 3947132718Skan (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 4))) 3948132718Skan (match_dup 3))) 3949132718Skan (use (const_int 1))])) 3950132718Skan ;; Step 8 3951132718Skan ;; H2 = H1 + d1 * H1 in f9 3952132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 3953132718Skan (parallel [(set (match_dup 4) 3954132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 4)) 3955132718Skan (match_dup 4))) 3956132718Skan (use (const_int 1))])) 3957132718Skan ;; Step 9 3958132718Skan ;; S2 = S1 + d1 * S1 in f7 3959132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 3960132718Skan (parallel [(set (match_dup 8) 3961132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 8)) 3962132718Skan (match_dup 8))) 3963132718Skan (use (const_int 1))])) 3964132718Skan ;; Step 10 3965132718Skan ;; d2 = 1/2 - S2 * H2 in f10 3966132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 3967132718Skan (parallel [(set (match_dup 5) 3968132718Skan (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 4))) 3969132718Skan (match_dup 3))) 3970132718Skan (use (const_int 1))])) 3971132718Skan ;; Step 11 3972132718Skan ;; e2 = a - S2 * S2 in f8 3973132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 3974132718Skan (parallel [(set (match_dup 3) 3975132718Skan (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 8))) 3976132718Skan (match_dup 9))) 3977132718Skan (use (const_int 1))])) 3978132718Skan ;; Step 12 3979132718Skan ;; S3 = S2 + e2 * H2 in f7 3980132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 3981132718Skan (parallel [(set (match_dup 8) 3982132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 4)) 3983132718Skan (match_dup 8))) 3984132718Skan (use (const_int 1))])) 3985132718Skan ;; Step 13 3986132718Skan ;; H3 = H2 + d2 * H2 in f9 3987132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 3988132718Skan (parallel [(set (match_dup 4) 3989132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 4)) 3990132718Skan (match_dup 4))) 3991132718Skan (use (const_int 1))])) 3992132718Skan ;; Step 14 3993132718Skan ;; e3 = a - S3 * S3 in f8 3994132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 3995132718Skan (parallel [(set (match_dup 3) 3996132718Skan (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 8))) 3997132718Skan (match_dup 9))) 3998132718Skan (use (const_int 1))])) 3999132718Skan ;; Step 15 4000132718Skan ;; S = S3 + e3 * H3 in f7 4001132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 4002132718Skan (parallel [(set (match_dup 0) 4003132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 4)) 4004132718Skan (match_dup 8))) 4005132718Skan (use (const_int 0))]))] 4006132718Skan{ 4007132718Skan /* Generate 82-bit versions of the input and output operands. */ 4008132718Skan operands[8] = gen_rtx_REG (XFmode, REGNO (operands[0])); 4009132718Skan operands[9] = gen_rtx_REG (XFmode, REGNO (operands[1])); 4010132718Skan /* Generate required floating-point constants. */ 4011132718Skan operands[10] = CONST0_RTX (XFmode); 4012132718Skan} 4013132718Skan [(set_attr "predicable" "no")]) 4014132718Skan 401590075Sobrien;; ??? frcpa works like cmp.foo.unc. 401690075Sobrien 401790075Sobrien(define_insn "*recip_approx" 4018132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 4019132718Skan (div:XF (const_int 1) 4020132718Skan (match_operand:XF 3 "fr_register_operand" "f"))) 402190075Sobrien (set (match_operand:BI 1 "register_operand" "=c") 4022132718Skan (unspec:BI [(match_operand:XF 2 "fr_register_operand" "f") 4023117395Skan (match_dup 3)] UNSPEC_FR_RECIP_APPROX)) 402490075Sobrien (use (match_operand:SI 4 "const_int_operand" ""))] 4025132718Skan "" 402690075Sobrien "frcpa.s%4 %0, %1 = %2, %3" 402790075Sobrien [(set_attr "itanium_class" "fmisc") 402890075Sobrien (set_attr "predicable" "no")]) 402990075Sobrien 403090075Sobrien;; :::::::::::::::::::: 403190075Sobrien;; :: 403290075Sobrien;; :: 32 bit Integer Shifts and Rotates 403390075Sobrien;; :: 403490075Sobrien;; :::::::::::::::::::: 403590075Sobrien 403690075Sobrien(define_expand "ashlsi3" 403790075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "") 403890075Sobrien (ashift:SI (match_operand:SI 1 "gr_register_operand" "") 403990075Sobrien (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))] 404090075Sobrien "" 404190075Sobrien{ 404290075Sobrien if (GET_CODE (operands[2]) != CONST_INT) 404390075Sobrien { 404490075Sobrien /* Why oh why didn't Intel arrange for SHIFT_COUNT_TRUNCATED? Now 404590075Sobrien we've got to get rid of stray bits outside the SImode register. */ 404690075Sobrien rtx subshift = gen_reg_rtx (DImode); 404790075Sobrien emit_insn (gen_zero_extendsidi2 (subshift, operands[2])); 404890075Sobrien operands[2] = subshift; 404990075Sobrien } 4050117395Skan}) 405190075Sobrien 405290075Sobrien(define_insn "*ashlsi3_internal" 405390075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r") 405490075Sobrien (ashift:SI (match_operand:SI 1 "gr_register_operand" "r,r,r") 405590075Sobrien (match_operand:DI 2 "gr_reg_or_5bit_operand" "R,n,r")))] 405690075Sobrien "" 405790075Sobrien "@ 405890075Sobrien shladd %0 = %1, %2, r0 405990075Sobrien dep.z %0 = %1, %2, %E2 406090075Sobrien shl %0 = %1, %2" 406190075Sobrien [(set_attr "itanium_class" "ialu,ishf,mmshf")]) 406290075Sobrien 406390075Sobrien(define_expand "ashrsi3" 406490075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "") 406590075Sobrien (ashiftrt:SI (match_operand:SI 1 "gr_register_operand" "") 406690075Sobrien (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))] 406790075Sobrien "" 406890075Sobrien{ 406990075Sobrien rtx subtarget = gen_reg_rtx (DImode); 407090075Sobrien if (GET_CODE (operands[2]) == CONST_INT) 407190075Sobrien emit_insn (gen_extv (subtarget, gen_lowpart (DImode, operands[1]), 407290075Sobrien GEN_INT (32 - INTVAL (operands[2])), operands[2])); 407390075Sobrien else 407490075Sobrien { 407590075Sobrien rtx subshift = gen_reg_rtx (DImode); 407690075Sobrien emit_insn (gen_extendsidi2 (subtarget, operands[1])); 407790075Sobrien emit_insn (gen_zero_extendsidi2 (subshift, operands[2])); 407890075Sobrien emit_insn (gen_ashrdi3 (subtarget, subtarget, subshift)); 407990075Sobrien } 408090075Sobrien emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget); 408190075Sobrien DONE; 4082117395Skan}) 408390075Sobrien 408490075Sobrien(define_expand "lshrsi3" 408590075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "") 408690075Sobrien (lshiftrt:SI (match_operand:SI 1 "gr_register_operand" "") 408790075Sobrien (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))] 408890075Sobrien "" 408990075Sobrien{ 409090075Sobrien rtx subtarget = gen_reg_rtx (DImode); 409190075Sobrien if (GET_CODE (operands[2]) == CONST_INT) 409290075Sobrien emit_insn (gen_extzv (subtarget, gen_lowpart (DImode, operands[1]), 409390075Sobrien GEN_INT (32 - INTVAL (operands[2])), operands[2])); 409490075Sobrien else 409590075Sobrien { 409690075Sobrien rtx subshift = gen_reg_rtx (DImode); 409790075Sobrien emit_insn (gen_zero_extendsidi2 (subtarget, operands[1])); 409890075Sobrien emit_insn (gen_zero_extendsidi2 (subshift, operands[2])); 409990075Sobrien emit_insn (gen_lshrdi3 (subtarget, subtarget, subshift)); 410090075Sobrien } 410190075Sobrien emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget); 410290075Sobrien DONE; 4103117395Skan}) 410490075Sobrien 410590075Sobrien;; Use mix4.r/shr to implement rotrsi3. We only get 32 bits of valid result 410690075Sobrien;; here, instead of 64 like the patterns above. Keep the pattern together 410790075Sobrien;; until after combine; otherwise it won't get matched often. 410890075Sobrien 410990075Sobrien(define_expand "rotrsi3" 411090075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "") 411190075Sobrien (rotatert:SI (match_operand:SI 1 "gr_register_operand" "") 411290075Sobrien (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))] 411390075Sobrien "" 411490075Sobrien{ 411590075Sobrien if (GET_MODE (operands[2]) != VOIDmode) 411690075Sobrien { 411790075Sobrien rtx tmp = gen_reg_rtx (DImode); 411890075Sobrien emit_insn (gen_zero_extendsidi2 (tmp, operands[2])); 411990075Sobrien operands[2] = tmp; 412090075Sobrien } 4121117395Skan}) 412290075Sobrien 412390075Sobrien(define_insn_and_split "*rotrsi3_internal" 412490075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=&r") 412590075Sobrien (rotatert:SI (match_operand:SI 1 "gr_register_operand" "r") 412690075Sobrien (match_operand:DI 2 "gr_reg_or_5bit_operand" "rM")))] 412790075Sobrien "" 412890075Sobrien "#" 412990075Sobrien "reload_completed" 413090075Sobrien [(set (match_dup 3) 413190075Sobrien (ior:DI (zero_extend:DI (match_dup 1)) 413290075Sobrien (ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32)))) 413390075Sobrien (set (match_dup 3) 413490075Sobrien (lshiftrt:DI (match_dup 3) (match_dup 2)))] 413590075Sobrien "operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));") 413690075Sobrien 413790075Sobrien(define_expand "rotlsi3" 413890075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "") 413990075Sobrien (rotate:SI (match_operand:SI 1 "gr_register_operand" "") 414090075Sobrien (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))] 414190075Sobrien "" 414290075Sobrien{ 414390075Sobrien if (! shift_32bit_count_operand (operands[2], SImode)) 414490075Sobrien { 414590075Sobrien rtx tmp = gen_reg_rtx (SImode); 414690075Sobrien emit_insn (gen_subsi3 (tmp, GEN_INT (32), operands[2])); 414790075Sobrien emit_insn (gen_rotrsi3 (operands[0], operands[1], tmp)); 414890075Sobrien DONE; 414990075Sobrien } 4150117395Skan}) 415190075Sobrien 415290075Sobrien(define_insn_and_split "*rotlsi3_internal" 415390075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 415490075Sobrien (rotate:SI (match_operand:SI 1 "gr_register_operand" "r") 415590075Sobrien (match_operand:SI 2 "shift_32bit_count_operand" "n")))] 415690075Sobrien "" 415790075Sobrien "#" 415890075Sobrien "reload_completed" 415990075Sobrien [(set (match_dup 3) 416090075Sobrien (ior:DI (zero_extend:DI (match_dup 1)) 416190075Sobrien (ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32)))) 416290075Sobrien (set (match_dup 3) 416390075Sobrien (lshiftrt:DI (match_dup 3) (match_dup 2)))] 4164117395Skan{ 4165117395Skan operands[3] = gen_rtx_REG (DImode, REGNO (operands[0])); 4166117395Skan operands[2] = GEN_INT (32 - INTVAL (operands[2])); 4167117395Skan}) 416890075Sobrien 416990075Sobrien;; :::::::::::::::::::: 417090075Sobrien;; :: 417190075Sobrien;; :: 64 bit Integer Shifts and Rotates 417290075Sobrien;; :: 417390075Sobrien;; :::::::::::::::::::: 417490075Sobrien 417590075Sobrien(define_insn "ashldi3" 417690075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r") 417790075Sobrien (ashift:DI (match_operand:DI 1 "gr_register_operand" "r,r,r") 417890075Sobrien (match_operand:DI 2 "gr_reg_or_6bit_operand" "R,r,rM")))] 417990075Sobrien "" 418090075Sobrien "@ 418190075Sobrien shladd %0 = %1, %2, r0 418290075Sobrien shl %0 = %1, %2 418390075Sobrien shl %0 = %1, %2" 418490075Sobrien [(set_attr "itanium_class" "ialu,mmshf,mmshfi")]) 418590075Sobrien 418690075Sobrien;; ??? Maybe combine this with the multiply and add instruction? 418790075Sobrien 418890075Sobrien(define_insn "*shladd" 418990075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 419090075Sobrien (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r") 419190075Sobrien (match_operand:DI 2 "shladd_operand" "n")) 419290075Sobrien (match_operand:DI 3 "gr_register_operand" "r")))] 419390075Sobrien "" 419490075Sobrien "shladd %0 = %1, %S2, %3" 419590075Sobrien [(set_attr "itanium_class" "ialu")]) 419690075Sobrien 419790075Sobrien;; This can be created by register elimination if operand3 of shladd is an 419890075Sobrien;; eliminable register or has reg_equiv_constant set. 419990075Sobrien 420090075Sobrien;; We have to use nonmemory_operand for operand 4, to ensure that the 420190075Sobrien;; validate_changes call inside eliminate_regs will always succeed. If it 420290075Sobrien;; doesn't succeed, then this remain a shladd pattern, and will be reloaded 420390075Sobrien;; incorrectly. 420490075Sobrien 420590075Sobrien(define_insn_and_split "*shladd_elim" 420690075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=&r") 420790075Sobrien (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r") 420890075Sobrien (match_operand:DI 2 "shladd_operand" "n")) 420990075Sobrien (match_operand:DI 3 "nonmemory_operand" "r")) 421090075Sobrien (match_operand:DI 4 "nonmemory_operand" "rI")))] 421190075Sobrien "reload_in_progress" 421290075Sobrien "* abort ();" 421390075Sobrien "reload_completed" 421490075Sobrien [(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (match_dup 2)) 421590075Sobrien (match_dup 3))) 421690075Sobrien (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))] 421790075Sobrien "" 421890075Sobrien [(set_attr "itanium_class" "unknown")]) 421990075Sobrien 422090075Sobrien(define_insn "ashrdi3" 422190075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r,r") 422290075Sobrien (ashiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r") 422390075Sobrien (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))] 422490075Sobrien "" 422590075Sobrien "@ 422690075Sobrien shr %0 = %1, %2 422790075Sobrien shr %0 = %1, %2" 422890075Sobrien [(set_attr "itanium_class" "mmshf,mmshfi")]) 422990075Sobrien 423090075Sobrien(define_insn "lshrdi3" 423190075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r,r") 423290075Sobrien (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r") 423390075Sobrien (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))] 423490075Sobrien "" 423590075Sobrien "@ 423690075Sobrien shr.u %0 = %1, %2 423790075Sobrien shr.u %0 = %1, %2" 423890075Sobrien [(set_attr "itanium_class" "mmshf,mmshfi")]) 423990075Sobrien 424090075Sobrien;; Using a predicate that accepts only constants doesn't work, because optabs 424190075Sobrien;; will load the operand into a register and call the pattern if the predicate 424290075Sobrien;; did not accept it on the first try. So we use nonmemory_operand and then 424390075Sobrien;; verify that we have an appropriate constant in the expander. 424490075Sobrien 424590075Sobrien(define_expand "rotrdi3" 424690075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") 424790075Sobrien (rotatert:DI (match_operand:DI 1 "gr_register_operand" "") 424890075Sobrien (match_operand:DI 2 "nonmemory_operand" "")))] 424990075Sobrien "" 425090075Sobrien{ 425190075Sobrien if (! shift_count_operand (operands[2], DImode)) 425290075Sobrien FAIL; 4253117395Skan}) 425490075Sobrien 425590075Sobrien(define_insn "*rotrdi3_internal" 425690075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 425790075Sobrien (rotatert:DI (match_operand:DI 1 "gr_register_operand" "r") 425890075Sobrien (match_operand:DI 2 "shift_count_operand" "M")))] 425990075Sobrien "" 426090075Sobrien "shrp %0 = %1, %1, %2" 426190075Sobrien [(set_attr "itanium_class" "ishf")]) 426290075Sobrien 426390075Sobrien(define_expand "rotldi3" 426490075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") 426590075Sobrien (rotate:DI (match_operand:DI 1 "gr_register_operand" "") 426690075Sobrien (match_operand:DI 2 "nonmemory_operand" "")))] 426790075Sobrien "" 426890075Sobrien{ 426990075Sobrien if (! shift_count_operand (operands[2], DImode)) 427090075Sobrien FAIL; 4271117395Skan}) 427290075Sobrien 427390075Sobrien(define_insn "*rotldi3_internal" 427490075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 427590075Sobrien (rotate:DI (match_operand:DI 1 "gr_register_operand" "r") 427690075Sobrien (match_operand:DI 2 "shift_count_operand" "M")))] 427790075Sobrien "" 427890075Sobrien "shrp %0 = %1, %1, %e2" 427990075Sobrien [(set_attr "itanium_class" "ishf")]) 428090075Sobrien 428190075Sobrien;; :::::::::::::::::::: 428290075Sobrien;; :: 428390075Sobrien;; :: 32 bit Integer Logical operations 428490075Sobrien;; :: 428590075Sobrien;; :::::::::::::::::::: 428690075Sobrien 428790075Sobrien;; We don't seem to need any other 32-bit logical operations, because gcc 428890075Sobrien;; generates zero-extend;zero-extend;DImode-op, which combine optimizes to 428990075Sobrien;; DImode-op;zero-extend, and then we can optimize away the zero-extend. 429090075Sobrien;; This doesn't work for unary logical operations, because we don't call 429190075Sobrien;; apply_distributive_law for them. 429290075Sobrien 429390075Sobrien;; ??? Likewise, this doesn't work for andnot, which isn't handled by 429490075Sobrien;; apply_distributive_law. We get inefficient code for 429590075Sobrien;; int sub4 (int i, int j) { return i & ~j; } 429690075Sobrien;; We could convert (and (not (sign_extend A)) (sign_extend B)) to 429790075Sobrien;; (zero_extend (and (not A) B)) in combine. 429890075Sobrien;; Or maybe fix this by adding andsi3/iorsi3/xorsi3 patterns like the 429990075Sobrien;; one_cmplsi2 pattern. 430090075Sobrien 430190075Sobrien(define_insn "one_cmplsi2" 430290075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 430390075Sobrien (not:SI (match_operand:SI 1 "gr_register_operand" "r")))] 430490075Sobrien "" 430590075Sobrien "andcm %0 = -1, %1" 430690075Sobrien [(set_attr "itanium_class" "ilog")]) 430790075Sobrien 430890075Sobrien;; :::::::::::::::::::: 430990075Sobrien;; :: 431090075Sobrien;; :: 64 bit Integer Logical operations 431190075Sobrien;; :: 431290075Sobrien;; :::::::::::::::::::: 431390075Sobrien 431490075Sobrien(define_insn "anddi3" 431590075Sobrien [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f") 431690075Sobrien (and:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f") 431790075Sobrien (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))] 431890075Sobrien "" 431990075Sobrien "@ 432090075Sobrien and %0 = %2, %1 432190075Sobrien fand %0 = %2, %1" 432290075Sobrien [(set_attr "itanium_class" "ilog,fmisc")]) 432390075Sobrien 432490075Sobrien(define_insn "*andnot" 432590075Sobrien [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f") 432690075Sobrien (and:DI (not:DI (match_operand:DI 1 "grfr_register_operand" "r,*f")) 432790075Sobrien (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))] 432890075Sobrien "" 432990075Sobrien "@ 433090075Sobrien andcm %0 = %2, %1 433190075Sobrien fandcm %0 = %2, %1" 433290075Sobrien [(set_attr "itanium_class" "ilog,fmisc")]) 433390075Sobrien 433490075Sobrien(define_insn "iordi3" 433590075Sobrien [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f") 433690075Sobrien (ior:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f") 433790075Sobrien (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))] 433890075Sobrien "" 433990075Sobrien "@ 434090075Sobrien or %0 = %2, %1 434190075Sobrien for %0 = %2, %1" 434290075Sobrien [(set_attr "itanium_class" "ilog,fmisc")]) 434390075Sobrien 434490075Sobrien(define_insn "xordi3" 434590075Sobrien [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f") 434690075Sobrien (xor:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f") 434790075Sobrien (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))] 434890075Sobrien "" 434990075Sobrien "@ 435090075Sobrien xor %0 = %2, %1 435190075Sobrien fxor %0 = %2, %1" 435290075Sobrien [(set_attr "itanium_class" "ilog,fmisc")]) 435390075Sobrien 435490075Sobrien(define_insn "one_cmpldi2" 435590075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 435690075Sobrien (not:DI (match_operand:DI 1 "gr_register_operand" "r")))] 435790075Sobrien "" 435890075Sobrien "andcm %0 = -1, %1" 435990075Sobrien [(set_attr "itanium_class" "ilog")]) 436090075Sobrien 436190075Sobrien;; :::::::::::::::::::: 436290075Sobrien;; :: 436390075Sobrien;; :: Comparisons 436490075Sobrien;; :: 436590075Sobrien;; :::::::::::::::::::: 436690075Sobrien 436790075Sobrien(define_expand "cmpbi" 436890075Sobrien [(set (cc0) 436990075Sobrien (compare (match_operand:BI 0 "register_operand" "") 437090075Sobrien (match_operand:BI 1 "const_int_operand" "")))] 437190075Sobrien "" 437290075Sobrien{ 437390075Sobrien ia64_compare_op0 = operands[0]; 437490075Sobrien ia64_compare_op1 = operands[1]; 437590075Sobrien DONE; 4376117395Skan}) 437790075Sobrien 437890075Sobrien(define_expand "cmpsi" 437990075Sobrien [(set (cc0) 438090075Sobrien (compare (match_operand:SI 0 "gr_register_operand" "") 438190075Sobrien (match_operand:SI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))] 438290075Sobrien "" 438390075Sobrien{ 438490075Sobrien ia64_compare_op0 = operands[0]; 438590075Sobrien ia64_compare_op1 = operands[1]; 438690075Sobrien DONE; 4387117395Skan}) 438890075Sobrien 438990075Sobrien(define_expand "cmpdi" 439090075Sobrien [(set (cc0) 439190075Sobrien (compare (match_operand:DI 0 "gr_register_operand" "") 439290075Sobrien (match_operand:DI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))] 439390075Sobrien "" 439490075Sobrien{ 439590075Sobrien ia64_compare_op0 = operands[0]; 439690075Sobrien ia64_compare_op1 = operands[1]; 439790075Sobrien DONE; 4398117395Skan}) 439990075Sobrien 440090075Sobrien(define_expand "cmpsf" 440190075Sobrien [(set (cc0) 440290075Sobrien (compare (match_operand:SF 0 "fr_reg_or_fp01_operand" "") 440390075Sobrien (match_operand:SF 1 "fr_reg_or_fp01_operand" "")))] 440490075Sobrien "" 440590075Sobrien{ 440690075Sobrien ia64_compare_op0 = operands[0]; 440790075Sobrien ia64_compare_op1 = operands[1]; 440890075Sobrien DONE; 4409117395Skan}) 441090075Sobrien 441190075Sobrien(define_expand "cmpdf" 441290075Sobrien [(set (cc0) 441390075Sobrien (compare (match_operand:DF 0 "fr_reg_or_fp01_operand" "") 441490075Sobrien (match_operand:DF 1 "fr_reg_or_fp01_operand" "")))] 441590075Sobrien "" 441690075Sobrien{ 441790075Sobrien ia64_compare_op0 = operands[0]; 441890075Sobrien ia64_compare_op1 = operands[1]; 441990075Sobrien DONE; 4420117395Skan}) 442190075Sobrien 4422132718Skan(define_expand "cmpxf" 4423132718Skan [(set (cc0) 4424132718Skan (compare (match_operand:XF 0 "xfreg_or_fp01_operand" "") 4425132718Skan (match_operand:XF 1 "xfreg_or_fp01_operand" "")))] 4426132718Skan "" 4427132718Skan{ 4428132718Skan ia64_compare_op0 = operands[0]; 4429132718Skan ia64_compare_op1 = operands[1]; 4430132718Skan DONE; 4431132718Skan}) 4432132718Skan 443390075Sobrien(define_expand "cmptf" 443490075Sobrien [(set (cc0) 4435132718Skan (compare (match_operand:TF 0 "gr_register_operand" "") 4436132718Skan (match_operand:TF 1 "gr_register_operand" "")))] 4437132718Skan "TARGET_HPUX" 443890075Sobrien{ 443990075Sobrien ia64_compare_op0 = operands[0]; 444090075Sobrien ia64_compare_op1 = operands[1]; 444190075Sobrien DONE; 4442117395Skan}) 444390075Sobrien 444490075Sobrien(define_insn "*cmpsi_normal" 444590075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 444690075Sobrien (match_operator:BI 1 "normal_comparison_operator" 444790075Sobrien [(match_operand:SI 2 "gr_register_operand" "r") 444890075Sobrien (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))] 444990075Sobrien "" 445090075Sobrien "cmp4.%C1 %0, %I0 = %3, %2" 445190075Sobrien [(set_attr "itanium_class" "icmp")]) 445290075Sobrien 445390075Sobrien;; We use %r3 because it is possible for us to match a 0, and two of the 445490075Sobrien;; unsigned comparisons don't accept immediate operands of zero. 445590075Sobrien 445690075Sobrien(define_insn "*cmpsi_adjusted" 445790075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 445890075Sobrien (match_operator:BI 1 "adjusted_comparison_operator" 445990075Sobrien [(match_operand:SI 2 "gr_register_operand" "r") 446090075Sobrien (match_operand:SI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))] 446190075Sobrien "" 446290075Sobrien "cmp4.%C1 %0, %I0 = %r3, %2" 446390075Sobrien [(set_attr "itanium_class" "icmp")]) 446490075Sobrien 446590075Sobrien(define_insn "*cmpdi_normal" 446690075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 446790075Sobrien (match_operator:BI 1 "normal_comparison_operator" 446890075Sobrien [(match_operand:DI 2 "gr_reg_or_0_operand" "rO") 446990075Sobrien (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))] 447090075Sobrien "" 447190075Sobrien "cmp.%C1 %0, %I0 = %3, %r2" 447290075Sobrien [(set_attr "itanium_class" "icmp")]) 447390075Sobrien 447490075Sobrien;; We use %r3 because it is possible for us to match a 0, and two of the 447590075Sobrien;; unsigned comparisons don't accept immediate operands of zero. 447690075Sobrien 447790075Sobrien(define_insn "*cmpdi_adjusted" 447890075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 447990075Sobrien (match_operator:BI 1 "adjusted_comparison_operator" 448090075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 448190075Sobrien (match_operand:DI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))] 448290075Sobrien "" 448390075Sobrien "cmp.%C1 %0, %I0 = %r3, %2" 448490075Sobrien [(set_attr "itanium_class" "icmp")]) 448590075Sobrien 448690075Sobrien(define_insn "*cmpsf_internal" 448790075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 448890075Sobrien (match_operator:BI 1 "comparison_operator" 448990075Sobrien [(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG") 449090075Sobrien (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")]))] 449190075Sobrien "" 449290075Sobrien "fcmp.%D1 %0, %I0 = %F2, %F3" 449390075Sobrien [(set_attr "itanium_class" "fcmp")]) 449490075Sobrien 449590075Sobrien(define_insn "*cmpdf_internal" 449690075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 449790075Sobrien (match_operator:BI 1 "comparison_operator" 449890075Sobrien [(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG") 449990075Sobrien (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")]))] 450090075Sobrien "" 450190075Sobrien "fcmp.%D1 %0, %I0 = %F2, %F3" 450290075Sobrien [(set_attr "itanium_class" "fcmp")]) 450390075Sobrien 4504132718Skan(define_insn "*cmpxf_internal" 450590075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 450690075Sobrien (match_operator:BI 1 "comparison_operator" 4507132718Skan [(match_operand:XF 2 "xfreg_or_fp01_operand" "fG") 4508132718Skan (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")]))] 4509132718Skan "" 451090075Sobrien "fcmp.%D1 %0, %I0 = %F2, %F3" 451190075Sobrien [(set_attr "itanium_class" "fcmp")]) 451290075Sobrien 451390075Sobrien;; ??? Can this pattern be generated? 451490075Sobrien 451590075Sobrien(define_insn "*bit_zero" 451690075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 451790075Sobrien (eq:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r") 451890075Sobrien (const_int 1) 451990075Sobrien (match_operand:DI 2 "immediate_operand" "n")) 452090075Sobrien (const_int 0)))] 452190075Sobrien "" 452290075Sobrien "tbit.z %0, %I0 = %1, %2" 452390075Sobrien [(set_attr "itanium_class" "tbit")]) 452490075Sobrien 452590075Sobrien(define_insn "*bit_one" 452690075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 452790075Sobrien (ne:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r") 452890075Sobrien (const_int 1) 452990075Sobrien (match_operand:DI 2 "immediate_operand" "n")) 453090075Sobrien (const_int 0)))] 453190075Sobrien "" 453290075Sobrien "tbit.nz %0, %I0 = %1, %2" 453390075Sobrien [(set_attr "itanium_class" "tbit")]) 453490075Sobrien 453590075Sobrien;; :::::::::::::::::::: 453690075Sobrien;; :: 453790075Sobrien;; :: Branches 453890075Sobrien;; :: 453990075Sobrien;; :::::::::::::::::::: 454090075Sobrien 454190075Sobrien(define_expand "beq" 454290075Sobrien [(set (pc) 454390075Sobrien (if_then_else (match_dup 1) 454490075Sobrien (label_ref (match_operand 0 "" "")) 454590075Sobrien (pc)))] 454690075Sobrien "" 454790075Sobrien "operands[1] = ia64_expand_compare (EQ, VOIDmode);") 454890075Sobrien 454990075Sobrien(define_expand "bne" 455090075Sobrien [(set (pc) 455190075Sobrien (if_then_else (match_dup 1) 455290075Sobrien (label_ref (match_operand 0 "" "")) 455390075Sobrien (pc)))] 455490075Sobrien "" 455590075Sobrien "operands[1] = ia64_expand_compare (NE, VOIDmode);") 455690075Sobrien 455790075Sobrien(define_expand "blt" 455890075Sobrien [(set (pc) 455990075Sobrien (if_then_else (match_dup 1) 456090075Sobrien (label_ref (match_operand 0 "" "")) 456190075Sobrien (pc)))] 456290075Sobrien "" 456390075Sobrien "operands[1] = ia64_expand_compare (LT, VOIDmode);") 456490075Sobrien 456590075Sobrien(define_expand "ble" 456690075Sobrien [(set (pc) 456790075Sobrien (if_then_else (match_dup 1) 456890075Sobrien (label_ref (match_operand 0 "" "")) 456990075Sobrien (pc)))] 457090075Sobrien "" 457190075Sobrien "operands[1] = ia64_expand_compare (LE, VOIDmode);") 457290075Sobrien 457390075Sobrien(define_expand "bgt" 457490075Sobrien [(set (pc) 457590075Sobrien (if_then_else (match_dup 1) 457690075Sobrien (label_ref (match_operand 0 "" "")) 457790075Sobrien (pc)))] 457890075Sobrien "" 457990075Sobrien "operands[1] = ia64_expand_compare (GT, VOIDmode);") 458090075Sobrien 458190075Sobrien(define_expand "bge" 458290075Sobrien [(set (pc) 458390075Sobrien (if_then_else (match_dup 1) 458490075Sobrien (label_ref (match_operand 0 "" "")) 458590075Sobrien (pc)))] 458690075Sobrien "" 458790075Sobrien "operands[1] = ia64_expand_compare (GE, VOIDmode);") 458890075Sobrien 458990075Sobrien(define_expand "bltu" 459090075Sobrien [(set (pc) 459190075Sobrien (if_then_else (match_dup 1) 459290075Sobrien (label_ref (match_operand 0 "" "")) 459390075Sobrien (pc)))] 459490075Sobrien "" 459590075Sobrien "operands[1] = ia64_expand_compare (LTU, VOIDmode);") 459690075Sobrien 459790075Sobrien(define_expand "bleu" 459890075Sobrien [(set (pc) 459990075Sobrien (if_then_else (match_dup 1) 460090075Sobrien (label_ref (match_operand 0 "" "")) 460190075Sobrien (pc)))] 460290075Sobrien "" 460390075Sobrien "operands[1] = ia64_expand_compare (LEU, VOIDmode);") 460490075Sobrien 460590075Sobrien(define_expand "bgtu" 460690075Sobrien [(set (pc) 460790075Sobrien (if_then_else (match_dup 1) 460890075Sobrien (label_ref (match_operand 0 "" "")) 460990075Sobrien (pc)))] 461090075Sobrien "" 461190075Sobrien "operands[1] = ia64_expand_compare (GTU, VOIDmode);") 461290075Sobrien 461390075Sobrien(define_expand "bgeu" 461490075Sobrien [(set (pc) 461590075Sobrien (if_then_else (match_dup 1) 461690075Sobrien (label_ref (match_operand 0 "" "")) 461790075Sobrien (pc)))] 461890075Sobrien "" 461990075Sobrien "operands[1] = ia64_expand_compare (GEU, VOIDmode);") 462090075Sobrien 462190075Sobrien(define_expand "bunordered" 462290075Sobrien [(set (pc) 462390075Sobrien (if_then_else (match_dup 1) 462490075Sobrien (label_ref (match_operand 0 "" "")) 462590075Sobrien (pc)))] 462690075Sobrien "" 462790075Sobrien "operands[1] = ia64_expand_compare (UNORDERED, VOIDmode);") 462890075Sobrien 462990075Sobrien(define_expand "bordered" 463090075Sobrien [(set (pc) 463190075Sobrien (if_then_else (match_dup 1) 463290075Sobrien (label_ref (match_operand 0 "" "")) 463390075Sobrien (pc)))] 463490075Sobrien "" 463590075Sobrien "operands[1] = ia64_expand_compare (ORDERED, VOIDmode);") 463690075Sobrien 463790075Sobrien(define_insn "*br_true" 463890075Sobrien [(set (pc) 463990075Sobrien (if_then_else (match_operator 0 "predicate_operator" 464090075Sobrien [(match_operand:BI 1 "register_operand" "c") 464190075Sobrien (const_int 0)]) 464290075Sobrien (label_ref (match_operand 2 "" "")) 464390075Sobrien (pc)))] 464490075Sobrien "" 464590075Sobrien "(%J0) br.cond%+ %l2" 464690075Sobrien [(set_attr "itanium_class" "br") 464790075Sobrien (set_attr "predicable" "no")]) 464890075Sobrien 464990075Sobrien(define_insn "*br_false" 465090075Sobrien [(set (pc) 465190075Sobrien (if_then_else (match_operator 0 "predicate_operator" 465290075Sobrien [(match_operand:BI 1 "register_operand" "c") 465390075Sobrien (const_int 0)]) 465490075Sobrien (pc) 465590075Sobrien (label_ref (match_operand 2 "" ""))))] 465690075Sobrien "" 465790075Sobrien "(%j0) br.cond%+ %l2" 465890075Sobrien [(set_attr "itanium_class" "br") 465990075Sobrien (set_attr "predicable" "no")]) 466090075Sobrien 466190075Sobrien;; :::::::::::::::::::: 466290075Sobrien;; :: 466390075Sobrien;; :: Counted loop operations 466490075Sobrien;; :: 466590075Sobrien;; :::::::::::::::::::: 466690075Sobrien 466790075Sobrien(define_expand "doloop_end" 466890075Sobrien [(use (match_operand 0 "" "")) ; loop pseudo 466990075Sobrien (use (match_operand 1 "" "")) ; iterations; zero if unknown 467090075Sobrien (use (match_operand 2 "" "")) ; max iterations 467190075Sobrien (use (match_operand 3 "" "")) ; loop level 467290075Sobrien (use (match_operand 4 "" ""))] ; label 467390075Sobrien "" 467490075Sobrien{ 467590075Sobrien /* Only use cloop on innermost loops. */ 467690075Sobrien if (INTVAL (operands[3]) > 1) 467790075Sobrien FAIL; 467890075Sobrien emit_jump_insn (gen_doloop_end_internal (gen_rtx_REG (DImode, AR_LC_REGNUM), 467990075Sobrien operands[4])); 468090075Sobrien DONE; 4681117395Skan}) 468290075Sobrien 468390075Sobrien(define_insn "doloop_end_internal" 468490075Sobrien [(set (pc) (if_then_else (ne (match_operand:DI 0 "ar_lc_reg_operand" "") 468590075Sobrien (const_int 0)) 468690075Sobrien (label_ref (match_operand 1 "" "")) 468790075Sobrien (pc))) 468890075Sobrien (set (match_dup 0) (if_then_else:DI (ne (match_dup 0) (const_int 0)) 4689117395Skan (plus:DI (match_dup 0) (const_int -1)) 4690117395Skan (match_dup 0)))] 469190075Sobrien "" 469290075Sobrien "br.cloop.sptk.few %l1" 469390075Sobrien [(set_attr "itanium_class" "br") 469490075Sobrien (set_attr "predicable" "no")]) 469590075Sobrien 469690075Sobrien;; :::::::::::::::::::: 469790075Sobrien;; :: 469890075Sobrien;; :: Set flag operations 469990075Sobrien;; :: 470090075Sobrien;; :::::::::::::::::::: 470190075Sobrien 470290075Sobrien(define_expand "seq" 470390075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 470490075Sobrien "" 470590075Sobrien "operands[1] = ia64_expand_compare (EQ, DImode);") 470690075Sobrien 470790075Sobrien(define_expand "sne" 470890075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 470990075Sobrien "" 471090075Sobrien "operands[1] = ia64_expand_compare (NE, DImode);") 471190075Sobrien 471290075Sobrien(define_expand "slt" 471390075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 471490075Sobrien "" 471590075Sobrien "operands[1] = ia64_expand_compare (LT, DImode);") 471690075Sobrien 471790075Sobrien(define_expand "sle" 471890075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 471990075Sobrien "" 472090075Sobrien "operands[1] = ia64_expand_compare (LE, DImode);") 472190075Sobrien 472290075Sobrien(define_expand "sgt" 472390075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 472490075Sobrien "" 472590075Sobrien "operands[1] = ia64_expand_compare (GT, DImode);") 472690075Sobrien 472790075Sobrien(define_expand "sge" 472890075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 472990075Sobrien "" 473090075Sobrien "operands[1] = ia64_expand_compare (GE, DImode);") 473190075Sobrien 473290075Sobrien(define_expand "sltu" 473390075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 473490075Sobrien "" 473590075Sobrien "operands[1] = ia64_expand_compare (LTU, DImode);") 473690075Sobrien 473790075Sobrien(define_expand "sleu" 473890075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 473990075Sobrien "" 474090075Sobrien "operands[1] = ia64_expand_compare (LEU, DImode);") 474190075Sobrien 474290075Sobrien(define_expand "sgtu" 474390075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 474490075Sobrien "" 474590075Sobrien "operands[1] = ia64_expand_compare (GTU, DImode);") 474690075Sobrien 474790075Sobrien(define_expand "sgeu" 474890075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 474990075Sobrien "" 475090075Sobrien "operands[1] = ia64_expand_compare (GEU, DImode);") 475190075Sobrien 475290075Sobrien(define_expand "sunordered" 475390075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 475490075Sobrien "" 475590075Sobrien "operands[1] = ia64_expand_compare (UNORDERED, DImode);") 475690075Sobrien 475790075Sobrien(define_expand "sordered" 475890075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 475990075Sobrien "" 476090075Sobrien "operands[1] = ia64_expand_compare (ORDERED, DImode);") 476190075Sobrien 476290075Sobrien;; Don't allow memory as destination here, because cmov/cmov/st is more 476390075Sobrien;; efficient than mov/mov/cst/cst. 476490075Sobrien 476590075Sobrien(define_insn_and_split "*sne_internal" 476690075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 476790075Sobrien (ne:DI (match_operand:BI 1 "register_operand" "c") 476890075Sobrien (const_int 0)))] 476990075Sobrien "" 477090075Sobrien "#" 477190075Sobrien "reload_completed" 477290075Sobrien [(cond_exec (ne (match_dup 1) (const_int 0)) 477390075Sobrien (set (match_dup 0) (const_int 1))) 477490075Sobrien (cond_exec (eq (match_dup 1) (const_int 0)) 477590075Sobrien (set (match_dup 0) (const_int 0)))] 477690075Sobrien "" 477790075Sobrien [(set_attr "itanium_class" "unknown")]) 477890075Sobrien 477990075Sobrien(define_insn_and_split "*seq_internal" 478090075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 478190075Sobrien (eq:DI (match_operand:BI 1 "register_operand" "c") 478290075Sobrien (const_int 0)))] 478390075Sobrien "" 478490075Sobrien "#" 478590075Sobrien "reload_completed" 478690075Sobrien [(cond_exec (ne (match_dup 1) (const_int 0)) 478790075Sobrien (set (match_dup 0) (const_int 0))) 478890075Sobrien (cond_exec (eq (match_dup 1) (const_int 0)) 478990075Sobrien (set (match_dup 0) (const_int 1)))] 479090075Sobrien "" 479190075Sobrien [(set_attr "itanium_class" "unknown")]) 479290075Sobrien 479390075Sobrien;; :::::::::::::::::::: 479490075Sobrien;; :: 479590075Sobrien;; :: Conditional move instructions. 479690075Sobrien;; :: 479790075Sobrien;; :::::::::::::::::::: 479890075Sobrien 479990075Sobrien;; ??? Add movXXcc patterns? 480090075Sobrien 480190075Sobrien;; 480290075Sobrien;; DImode if_then_else patterns. 480390075Sobrien;; 480490075Sobrien 480590075Sobrien(define_insn "*cmovdi_internal" 480690075Sobrien [(set (match_operand:DI 0 "destination_operand" 480790075Sobrien "= r, r, r, r, r, r, r, r, r, r, m, Q, *f,*b,*d*e") 480890075Sobrien (if_then_else:DI 480990075Sobrien (match_operator 4 "predicate_operator" 481090075Sobrien [(match_operand:BI 1 "register_operand" 481190075Sobrien "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c") 481290075Sobrien (const_int 0)]) 481390075Sobrien (match_operand:DI 2 "move_operand" 4814132718Skan "rim, *f, *b,*d*e,rim,rim, rim,*f,*b,*d*e,rO,*f,rOQ,rO, rK") 481590075Sobrien (match_operand:DI 3 "move_operand" 4816132718Skan "rim,rim,rim, rim, *f, *b,*d*e,*f,*b,*d*e,rO,*f,rOQ,rO, rK")))] 481790075Sobrien "ia64_move_ok (operands[0], operands[2]) 481890075Sobrien && ia64_move_ok (operands[0], operands[3])" 4819117395Skan { abort (); } 482090075Sobrien [(set_attr "predicable" "no")]) 482190075Sobrien 482290075Sobrien(define_split 482390075Sobrien [(set (match_operand 0 "destination_operand" "") 482490075Sobrien (if_then_else 482590075Sobrien (match_operator 4 "predicate_operator" 482690075Sobrien [(match_operand:BI 1 "register_operand" "") 482790075Sobrien (const_int 0)]) 482890075Sobrien (match_operand 2 "move_operand" "") 482990075Sobrien (match_operand 3 "move_operand" "")))] 483090075Sobrien "reload_completed" 483190075Sobrien [(const_int 0)] 483290075Sobrien{ 4833132718Skan bool emitted_something = false; 4834132718Skan rtx dest = operands[0]; 4835132718Skan rtx srct = operands[2]; 4836132718Skan rtx srcf = operands[3]; 4837132718Skan rtx cond = operands[4]; 4838117395Skan 4839132718Skan if (! rtx_equal_p (dest, srct)) 484090075Sobrien { 4841132718Skan ia64_emit_cond_move (dest, srct, cond); 4842132718Skan emitted_something = true; 484390075Sobrien } 4844132718Skan if (! rtx_equal_p (dest, srcf)) 484590075Sobrien { 4846132718Skan cond = gen_rtx_fmt_ee (GET_CODE (cond) == NE ? EQ : NE, 4847132718Skan VOIDmode, operands[1], const0_rtx); 4848132718Skan ia64_emit_cond_move (dest, srcf, cond); 4849132718Skan emitted_something = true; 485090075Sobrien } 4851117395Skan if (! emitted_something) 4852132718Skan emit_note (NOTE_INSN_DELETED); 485390075Sobrien DONE; 4854117395Skan}) 485590075Sobrien 485690075Sobrien;; Absolute value pattern. 485790075Sobrien 485890075Sobrien(define_insn "*absdi2_internal" 485990075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r,r") 486090075Sobrien (if_then_else:DI 486190075Sobrien (match_operator 4 "predicate_operator" 486290075Sobrien [(match_operand:BI 1 "register_operand" "c,c") 486390075Sobrien (const_int 0)]) 486490075Sobrien (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" "rI,rI")) 486590075Sobrien (match_operand:DI 3 "gr_reg_or_22bit_operand" "0,rI")))] 486690075Sobrien "" 486790075Sobrien "#" 486890075Sobrien [(set_attr "itanium_class" "ialu,unknown") 486990075Sobrien (set_attr "predicable" "no")]) 487090075Sobrien 487190075Sobrien(define_split 487290075Sobrien [(set (match_operand:DI 0 "register_operand" "") 487390075Sobrien (if_then_else:DI 487490075Sobrien (match_operator 4 "predicate_operator" 487590075Sobrien [(match_operand:BI 1 "register_operand" "c,c") 487690075Sobrien (const_int 0)]) 487790075Sobrien (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" "")) 487890075Sobrien (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))] 487990075Sobrien "reload_completed && rtx_equal_p (operands[0], operands[3])" 488090075Sobrien [(cond_exec 488190075Sobrien (match_dup 4) 488290075Sobrien (set (match_dup 0) 488390075Sobrien (neg:DI (match_dup 2))))] 488490075Sobrien "") 488590075Sobrien 488690075Sobrien(define_split 488790075Sobrien [(set (match_operand:DI 0 "register_operand" "") 488890075Sobrien (if_then_else:DI 488990075Sobrien (match_operator 4 "predicate_operator" 489090075Sobrien [(match_operand:BI 1 "register_operand" "c,c") 489190075Sobrien (const_int 0)]) 489290075Sobrien (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" "")) 489390075Sobrien (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))] 489490075Sobrien "reload_completed" 489590075Sobrien [(cond_exec 489690075Sobrien (match_dup 4) 489790075Sobrien (set (match_dup 0) (neg:DI (match_dup 2)))) 489890075Sobrien (cond_exec 489990075Sobrien (match_dup 5) 490090075Sobrien (set (match_dup 0) (match_dup 3)))] 490190075Sobrien{ 490290075Sobrien operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE, 490390075Sobrien VOIDmode, operands[1], const0_rtx); 4904117395Skan}) 490590075Sobrien 490690075Sobrien;; 490790075Sobrien;; SImode if_then_else patterns. 490890075Sobrien;; 490990075Sobrien 491090075Sobrien(define_insn "*cmovsi_internal" 491190075Sobrien [(set (match_operand:SI 0 "destination_operand" "=r,m,*f,r,m,*f,r,m,*f") 491290075Sobrien (if_then_else:SI 491390075Sobrien (match_operator 4 "predicate_operator" 491490075Sobrien [(match_operand:BI 1 "register_operand" "c,c,c,c,c,c,c,c,c") 491590075Sobrien (const_int 0)]) 491690075Sobrien (match_operand:SI 2 "move_operand" 4917132718Skan "0,0,0,rim*f,rO,rO,rim*f,rO,rO") 491890075Sobrien (match_operand:SI 3 "move_operand" 4919132718Skan "rim*f,rO,rO,0,0,0,rim*f,rO,rO")))] 492090075Sobrien "ia64_move_ok (operands[0], operands[2]) 492190075Sobrien && ia64_move_ok (operands[0], operands[3])" 4922117395Skan { abort (); } 492390075Sobrien [(set_attr "predicable" "no")]) 492490075Sobrien 492590075Sobrien(define_insn "*abssi2_internal" 492690075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r,r") 492790075Sobrien (if_then_else:SI 492890075Sobrien (match_operator 4 "predicate_operator" 492990075Sobrien [(match_operand:BI 1 "register_operand" "c,c") 493090075Sobrien (const_int 0)]) 493190075Sobrien (neg:SI (match_operand:SI 3 "gr_reg_or_22bit_operand" "rI,rI")) 493290075Sobrien (match_operand:SI 2 "gr_reg_or_22bit_operand" "0,rI")))] 493390075Sobrien "" 493490075Sobrien "#" 493590075Sobrien [(set_attr "itanium_class" "ialu,unknown") 493690075Sobrien (set_attr "predicable" "no")]) 493790075Sobrien 493890075Sobrien(define_split 493990075Sobrien [(set (match_operand:SI 0 "register_operand" "") 494090075Sobrien (if_then_else:SI 494190075Sobrien (match_operator 4 "predicate_operator" 494290075Sobrien [(match_operand:BI 1 "register_operand" "c,c") 494390075Sobrien (const_int 0)]) 494490075Sobrien (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" "")) 494590075Sobrien (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))] 494690075Sobrien "reload_completed && rtx_equal_p (operands[0], operands[3])" 494790075Sobrien [(cond_exec 494890075Sobrien (match_dup 4) 494990075Sobrien (set (match_dup 0) 495090075Sobrien (neg:SI (match_dup 2))))] 495190075Sobrien "") 495290075Sobrien 495390075Sobrien(define_split 495490075Sobrien [(set (match_operand:SI 0 "register_operand" "") 495590075Sobrien (if_then_else:SI 495690075Sobrien (match_operator 4 "predicate_operator" 495790075Sobrien [(match_operand:BI 1 "register_operand" "c,c") 495890075Sobrien (const_int 0)]) 495990075Sobrien (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" "")) 496090075Sobrien (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))] 496190075Sobrien "reload_completed" 496290075Sobrien [(cond_exec 496390075Sobrien (match_dup 4) 496490075Sobrien (set (match_dup 0) (neg:SI (match_dup 2)))) 496590075Sobrien (cond_exec 496690075Sobrien (match_dup 5) 496790075Sobrien (set (match_dup 0) (match_dup 3)))] 496890075Sobrien{ 496990075Sobrien operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE, 497090075Sobrien VOIDmode, operands[1], const0_rtx); 4971117395Skan}) 497290075Sobrien 497390075Sobrien(define_insn_and_split "*cond_opsi2_internal" 497490075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 497590075Sobrien (match_operator:SI 5 "condop_operator" 497690075Sobrien [(if_then_else:SI 497790075Sobrien (match_operator 6 "predicate_operator" 497890075Sobrien [(match_operand:BI 1 "register_operand" "c") 497990075Sobrien (const_int 0)]) 498090075Sobrien (match_operand:SI 2 "gr_register_operand" "r") 498190075Sobrien (match_operand:SI 3 "gr_register_operand" "r")) 498290075Sobrien (match_operand:SI 4 "gr_register_operand" "r")]))] 498390075Sobrien "" 498490075Sobrien "#" 498590075Sobrien "reload_completed" 498690075Sobrien [(cond_exec 498790075Sobrien (match_dup 6) 498890075Sobrien (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 2) (match_dup 4)]))) 498990075Sobrien (cond_exec 499090075Sobrien (match_dup 7) 499190075Sobrien (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 3) (match_dup 4)])))] 499290075Sobrien{ 499390075Sobrien operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE, 499490075Sobrien VOIDmode, operands[1], const0_rtx); 4995117395Skan} 499690075Sobrien [(set_attr "itanium_class" "ialu") 499790075Sobrien (set_attr "predicable" "no")]) 499890075Sobrien 499990075Sobrien 500090075Sobrien(define_insn_and_split "*cond_opsi2_internal_b" 500190075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 500290075Sobrien (match_operator:SI 5 "condop_operator" 500390075Sobrien [(match_operand:SI 4 "gr_register_operand" "r") 500490075Sobrien (if_then_else:SI 500590075Sobrien (match_operator 6 "predicate_operator" 500690075Sobrien [(match_operand:BI 1 "register_operand" "c") 500790075Sobrien (const_int 0)]) 500890075Sobrien (match_operand:SI 2 "gr_register_operand" "r") 500990075Sobrien (match_operand:SI 3 "gr_register_operand" "r"))]))] 501090075Sobrien "" 501190075Sobrien "#" 501290075Sobrien "reload_completed" 501390075Sobrien [(cond_exec 501490075Sobrien (match_dup 6) 501590075Sobrien (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 2)]))) 501690075Sobrien (cond_exec 501790075Sobrien (match_dup 7) 501890075Sobrien (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 3)])))] 501990075Sobrien{ 502090075Sobrien operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE, 502190075Sobrien VOIDmode, operands[1], const0_rtx); 5022117395Skan} 502390075Sobrien [(set_attr "itanium_class" "ialu") 502490075Sobrien (set_attr "predicable" "no")]) 502590075Sobrien 502690075Sobrien 502790075Sobrien;; :::::::::::::::::::: 502890075Sobrien;; :: 502990075Sobrien;; :: Call and branch instructions 503090075Sobrien;; :: 503190075Sobrien;; :::::::::::::::::::: 503290075Sobrien 503390075Sobrien;; Subroutine call instruction returning no value. Operand 0 is the function 503490075Sobrien;; to call; operand 1 is the number of bytes of arguments pushed (in mode 503590075Sobrien;; `SImode', except it is normally a `const_int'); operand 2 is the number of 503690075Sobrien;; registers used as operands. 503790075Sobrien 503890075Sobrien;; On most machines, operand 2 is not actually stored into the RTL pattern. It 503990075Sobrien;; is supplied for the sake of some RISC machines which need to put this 504090075Sobrien;; information into the assembler code; they can put it in the RTL instead of 504190075Sobrien;; operand 1. 504290075Sobrien 504390075Sobrien(define_expand "call" 504490075Sobrien [(use (match_operand:DI 0 "" "")) 504590075Sobrien (use (match_operand 1 "" "")) 504690075Sobrien (use (match_operand 2 "" "")) 504790075Sobrien (use (match_operand 3 "" ""))] 504890075Sobrien "" 504990075Sobrien{ 5050117395Skan ia64_expand_call (NULL_RTX, operands[0], operands[2], false); 505190075Sobrien DONE; 5052117395Skan}) 505390075Sobrien 505490075Sobrien(define_expand "sibcall" 505590075Sobrien [(use (match_operand:DI 0 "" "")) 505690075Sobrien (use (match_operand 1 "" "")) 505790075Sobrien (use (match_operand 2 "" "")) 505890075Sobrien (use (match_operand 3 "" ""))] 505990075Sobrien "" 506090075Sobrien{ 5061117395Skan ia64_expand_call (NULL_RTX, operands[0], operands[2], true); 506290075Sobrien DONE; 5063117395Skan}) 506490075Sobrien 506590075Sobrien;; Subroutine call instruction returning a value. Operand 0 is the hard 506690075Sobrien;; register in which the value is returned. There are three more operands, 506790075Sobrien;; the same as the three operands of the `call' instruction (but with numbers 506890075Sobrien;; increased by one). 506990075Sobrien;; 507090075Sobrien;; Subroutines that return `BLKmode' objects use the `call' insn. 507190075Sobrien 507290075Sobrien(define_expand "call_value" 507390075Sobrien [(use (match_operand 0 "" "")) 507490075Sobrien (use (match_operand:DI 1 "" "")) 507590075Sobrien (use (match_operand 2 "" "")) 507690075Sobrien (use (match_operand 3 "" "")) 507790075Sobrien (use (match_operand 4 "" ""))] 507890075Sobrien "" 507990075Sobrien{ 5080117395Skan ia64_expand_call (operands[0], operands[1], operands[3], false); 508190075Sobrien DONE; 5082117395Skan}) 508390075Sobrien 508490075Sobrien(define_expand "sibcall_value" 508590075Sobrien [(use (match_operand 0 "" "")) 508690075Sobrien (use (match_operand:DI 1 "" "")) 508790075Sobrien (use (match_operand 2 "" "")) 508890075Sobrien (use (match_operand 3 "" "")) 508990075Sobrien (use (match_operand 4 "" ""))] 509090075Sobrien "" 509190075Sobrien{ 5092117395Skan ia64_expand_call (operands[0], operands[1], operands[3], true); 509390075Sobrien DONE; 5094117395Skan}) 509590075Sobrien 509690075Sobrien;; Call subroutine returning any type. 509790075Sobrien 509890075Sobrien(define_expand "untyped_call" 509990075Sobrien [(parallel [(call (match_operand 0 "" "") 510090075Sobrien (const_int 0)) 510190075Sobrien (match_operand 1 "" "") 510290075Sobrien (match_operand 2 "" "")])] 510390075Sobrien "" 510490075Sobrien{ 510590075Sobrien int i; 510690075Sobrien 510790075Sobrien emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx)); 510890075Sobrien 510990075Sobrien for (i = 0; i < XVECLEN (operands[2], 0); i++) 511090075Sobrien { 511190075Sobrien rtx set = XVECEXP (operands[2], 0, i); 511290075Sobrien emit_move_insn (SET_DEST (set), SET_SRC (set)); 511390075Sobrien } 511490075Sobrien 511590075Sobrien /* The optimizer does not know that the call sets the function value 511690075Sobrien registers we stored in the result block. We avoid problems by 511790075Sobrien claiming that all hard registers are used and clobbered at this 511890075Sobrien point. */ 511990075Sobrien emit_insn (gen_blockage ()); 512090075Sobrien 512190075Sobrien DONE; 5122117395Skan}) 512390075Sobrien 5124117395Skan(define_insn "call_nogp" 5125117395Skan [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i")) 5126117395Skan (const_int 0)) 5127117395Skan (clobber (match_operand:DI 1 "register_operand" "=b,b"))] 512890075Sobrien "" 5129117395Skan "br.call%+.many %1 = %0" 513090075Sobrien [(set_attr "itanium_class" "br,scall")]) 513190075Sobrien 5132117395Skan(define_insn "call_value_nogp" 5133132718Skan [(set (match_operand 0 "" "=X,X") 5134117395Skan (call (mem:DI (match_operand:DI 1 "call_operand" "?b,i")) 5135117395Skan (const_int 0))) 5136117395Skan (clobber (match_operand:DI 2 "register_operand" "=b,b"))] 513790075Sobrien "" 5138117395Skan "br.call%+.many %2 = %1" 513990075Sobrien [(set_attr "itanium_class" "br,scall")]) 514090075Sobrien 5141117395Skan(define_insn "sibcall_nogp" 5142117395Skan [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i")) 5143117395Skan (const_int 0))] 514490075Sobrien "" 514590075Sobrien "br%+.many %0" 514690075Sobrien [(set_attr "itanium_class" "br,scall")]) 514790075Sobrien 5148117395Skan(define_insn "call_gp" 5149132718Skan [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,i")) 5150117395Skan (const_int 1)) 5151117395Skan (clobber (match_operand:DI 1 "register_operand" "=b,b")) 5152117395Skan (clobber (match_scratch:DI 2 "=&r,X")) 5153117395Skan (clobber (match_scratch:DI 3 "=b,X"))] 515490075Sobrien "" 5155117395Skan "#" 515690075Sobrien [(set_attr "itanium_class" "br,scall")]) 515790075Sobrien 5158117395Skan;; Irritatingly, we don't have access to INSN within the split body. 5159117395Skan;; See commentary in ia64_split_call as to why these aren't peep2. 5160117395Skan(define_split 5161117395Skan [(call (mem (match_operand 0 "call_operand" "")) 5162117395Skan (const_int 1)) 5163117395Skan (clobber (match_operand:DI 1 "register_operand" "")) 5164117395Skan (clobber (match_scratch:DI 2 "")) 5165117395Skan (clobber (match_scratch:DI 3 ""))] 5166117395Skan "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)" 5167117395Skan [(const_int 0)] 5168117395Skan{ 5169117395Skan ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2], 5170117395Skan operands[3], true, false); 5171117395Skan DONE; 5172117395Skan}) 5173117395Skan 5174117395Skan(define_split 5175117395Skan [(call (mem (match_operand 0 "call_operand" "")) 5176117395Skan (const_int 1)) 5177117395Skan (clobber (match_operand:DI 1 "register_operand" "")) 5178117395Skan (clobber (match_scratch:DI 2 "")) 5179117395Skan (clobber (match_scratch:DI 3 ""))] 5180117395Skan "reload_completed" 5181117395Skan [(const_int 0)] 5182117395Skan{ 5183117395Skan ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2], 5184117395Skan operands[3], false, false); 5185117395Skan DONE; 5186117395Skan}) 5187117395Skan 5188117395Skan(define_insn "call_value_gp" 5189132718Skan [(set (match_operand 0 "" "=X,X") 5190117395Skan (call (mem:DI (match_operand:DI 1 "call_operand" "?r,i")) 5191117395Skan (const_int 1))) 5192117395Skan (clobber (match_operand:DI 2 "register_operand" "=b,b")) 5193117395Skan (clobber (match_scratch:DI 3 "=&r,X")) 5194117395Skan (clobber (match_scratch:DI 4 "=b,X"))] 519590075Sobrien "" 5196117395Skan "#" 519790075Sobrien [(set_attr "itanium_class" "br,scall")]) 519890075Sobrien 5199117395Skan(define_split 5200117395Skan [(set (match_operand 0 "" "") 5201117395Skan (call (mem:DI (match_operand:DI 1 "call_operand" "")) 5202117395Skan (const_int 1))) 5203117395Skan (clobber (match_operand:DI 2 "register_operand" "")) 5204117395Skan (clobber (match_scratch:DI 3 "")) 5205117395Skan (clobber (match_scratch:DI 4 ""))] 5206117395Skan "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)" 5207117395Skan [(const_int 0)] 5208117395Skan{ 5209117395Skan ia64_split_call (operands[0], operands[1], operands[2], operands[3], 5210117395Skan operands[4], true, false); 5211117395Skan DONE; 5212117395Skan}) 5213117395Skan 5214117395Skan(define_split 5215117395Skan [(set (match_operand 0 "" "") 5216117395Skan (call (mem:DI (match_operand:DI 1 "call_operand" "")) 5217117395Skan (const_int 1))) 5218117395Skan (clobber (match_operand:DI 2 "register_operand" "")) 5219117395Skan (clobber (match_scratch:DI 3 "")) 5220117395Skan (clobber (match_scratch:DI 4 ""))] 5221117395Skan "reload_completed" 5222117395Skan [(const_int 0)] 5223117395Skan{ 5224117395Skan ia64_split_call (operands[0], operands[1], operands[2], operands[3], 5225117395Skan operands[4], false, false); 5226117395Skan DONE; 5227117395Skan}) 5228117395Skan 5229117395Skan(define_insn_and_split "sibcall_gp" 5230117395Skan [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,i")) 5231117395Skan (const_int 1)) 5232117395Skan (clobber (match_scratch:DI 1 "=&r,X")) 5233117395Skan (clobber (match_scratch:DI 2 "=b,X"))] 523490075Sobrien "" 5235117395Skan "#" 5236117395Skan "reload_completed" 5237117395Skan [(const_int 0)] 5238117395Skan{ 5239117395Skan ia64_split_call (NULL_RTX, operands[0], NULL_RTX, operands[1], 5240117395Skan operands[2], true, true); 5241117395Skan DONE; 5242117395Skan} 524390075Sobrien [(set_attr "itanium_class" "br")]) 524490075Sobrien 524590075Sobrien(define_insn "return_internal" 524690075Sobrien [(return) 524790075Sobrien (use (match_operand:DI 0 "register_operand" "b"))] 524890075Sobrien "" 524990075Sobrien "br.ret.sptk.many %0" 525090075Sobrien [(set_attr "itanium_class" "br")]) 525190075Sobrien 525290075Sobrien(define_insn "return" 525390075Sobrien [(return)] 525490075Sobrien "ia64_direct_return ()" 525590075Sobrien "br.ret.sptk.many rp" 525690075Sobrien [(set_attr "itanium_class" "br")]) 525790075Sobrien 525890075Sobrien(define_insn "*return_true" 525990075Sobrien [(set (pc) 526090075Sobrien (if_then_else (match_operator 0 "predicate_operator" 526190075Sobrien [(match_operand:BI 1 "register_operand" "c") 526290075Sobrien (const_int 0)]) 526390075Sobrien (return) 526490075Sobrien (pc)))] 526590075Sobrien "ia64_direct_return ()" 526690075Sobrien "(%J0) br.ret%+.many rp" 526790075Sobrien [(set_attr "itanium_class" "br") 526890075Sobrien (set_attr "predicable" "no")]) 526990075Sobrien 527090075Sobrien(define_insn "*return_false" 527190075Sobrien [(set (pc) 527290075Sobrien (if_then_else (match_operator 0 "predicate_operator" 527390075Sobrien [(match_operand:BI 1 "register_operand" "c") 527490075Sobrien (const_int 0)]) 527590075Sobrien (pc) 527690075Sobrien (return)))] 527790075Sobrien "ia64_direct_return ()" 527890075Sobrien "(%j0) br.ret%+.many rp" 527990075Sobrien [(set_attr "itanium_class" "br") 528090075Sobrien (set_attr "predicable" "no")]) 528190075Sobrien 528290075Sobrien(define_insn "jump" 528390075Sobrien [(set (pc) (label_ref (match_operand 0 "" "")))] 528490075Sobrien "" 528590075Sobrien "br %l0" 528690075Sobrien [(set_attr "itanium_class" "br")]) 528790075Sobrien 528890075Sobrien(define_insn "indirect_jump" 528990075Sobrien [(set (pc) (match_operand:DI 0 "register_operand" "b"))] 529090075Sobrien "" 529190075Sobrien "br %0" 529290075Sobrien [(set_attr "itanium_class" "br")]) 529390075Sobrien 529490075Sobrien(define_expand "tablejump" 529590075Sobrien [(parallel [(set (pc) (match_operand:DI 0 "memory_operand" "")) 529690075Sobrien (use (label_ref (match_operand 1 "" "")))])] 529790075Sobrien "" 529890075Sobrien{ 529990075Sobrien rtx op0 = operands[0]; 530090075Sobrien rtx addr; 530190075Sobrien 530290075Sobrien /* ??? Bother -- do_tablejump is "helpful" and pulls the table 530390075Sobrien element into a register without bothering to see whether that 530490075Sobrien is necessary given the operand predicate. Check for MEM just 530590075Sobrien in case someone fixes this. */ 530690075Sobrien if (GET_CODE (op0) == MEM) 530790075Sobrien addr = XEXP (op0, 0); 530890075Sobrien else 530990075Sobrien { 531090075Sobrien /* Otherwise, cheat and guess that the previous insn in the 531190075Sobrien stream was the memory load. Grab the address from that. 531290075Sobrien Note we have to momentarily pop out of the sequence started 531390075Sobrien by the insn-emit wrapper in order to grab the last insn. */ 531490075Sobrien rtx last, set; 531590075Sobrien 531690075Sobrien end_sequence (); 531790075Sobrien last = get_last_insn (); 531890075Sobrien start_sequence (); 531990075Sobrien set = single_set (last); 532090075Sobrien 532190075Sobrien if (! rtx_equal_p (SET_DEST (set), op0) 532290075Sobrien || GET_CODE (SET_SRC (set)) != MEM) 532390075Sobrien abort (); 532490075Sobrien addr = XEXP (SET_SRC (set), 0); 532590075Sobrien if (rtx_equal_p (addr, op0)) 532690075Sobrien abort (); 532790075Sobrien } 532890075Sobrien 532990075Sobrien /* Jump table elements are stored pc-relative. That is, a displacement 533090075Sobrien from the entry to the label. Thus to convert to an absolute address 533190075Sobrien we add the address of the memory from which the value is loaded. */ 533290075Sobrien operands[0] = expand_simple_binop (DImode, PLUS, op0, addr, 533390075Sobrien NULL_RTX, 1, OPTAB_DIRECT); 533490075Sobrien}) 533590075Sobrien 533690075Sobrien(define_insn "*tablejump_internal" 533790075Sobrien [(set (pc) (match_operand:DI 0 "register_operand" "b")) 533890075Sobrien (use (label_ref (match_operand 1 "" "")))] 533990075Sobrien "" 534090075Sobrien "br %0" 534190075Sobrien [(set_attr "itanium_class" "br")]) 534290075Sobrien 534390075Sobrien 534490075Sobrien;; :::::::::::::::::::: 534590075Sobrien;; :: 534690075Sobrien;; :: Prologue and Epilogue instructions 534790075Sobrien;; :: 534890075Sobrien;; :::::::::::::::::::: 534990075Sobrien 535090075Sobrien(define_expand "prologue" 535190075Sobrien [(const_int 1)] 535290075Sobrien "" 535390075Sobrien{ 535490075Sobrien ia64_expand_prologue (); 535590075Sobrien DONE; 5356117395Skan}) 535790075Sobrien 535890075Sobrien(define_expand "epilogue" 535990075Sobrien [(return)] 536090075Sobrien "" 536190075Sobrien{ 536290075Sobrien ia64_expand_epilogue (0); 536390075Sobrien DONE; 5364117395Skan}) 536590075Sobrien 536690075Sobrien(define_expand "sibcall_epilogue" 536790075Sobrien [(return)] 536890075Sobrien "" 536990075Sobrien{ 537090075Sobrien ia64_expand_epilogue (1); 537190075Sobrien DONE; 5372117395Skan}) 537390075Sobrien 537490075Sobrien;; This prevents the scheduler from moving the SP decrement past FP-relative 537590075Sobrien;; stack accesses. This is the same as adddi3 plus the extra set. 537690075Sobrien 537790075Sobrien(define_insn "prologue_allocate_stack" 537890075Sobrien [(set (match_operand:DI 0 "register_operand" "=r,r,r") 537990075Sobrien (plus:DI (match_operand:DI 1 "register_operand" "%r,r,a") 538090075Sobrien (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J"))) 538196263Sobrien (set (match_operand:DI 3 "register_operand" "+r,r,r") 538290075Sobrien (match_dup 3))] 538390075Sobrien "" 538490075Sobrien "@ 5385117395Skan add %0 = %1, %2 5386117395Skan adds %0 = %2, %1 5387117395Skan addl %0 = %2, %1" 538890075Sobrien [(set_attr "itanium_class" "ialu")]) 538990075Sobrien 539090075Sobrien;; This prevents the scheduler from moving the SP restore past FP-relative 539190075Sobrien;; stack accesses. This is similar to movdi plus the extra set. 539290075Sobrien 539390075Sobrien(define_insn "epilogue_deallocate_stack" 539490075Sobrien [(set (match_operand:DI 0 "register_operand" "=r") 539590075Sobrien (match_operand:DI 1 "register_operand" "+r")) 539690075Sobrien (set (match_dup 1) (match_dup 1))] 539790075Sobrien "" 539890075Sobrien "mov %0 = %1" 539990075Sobrien [(set_attr "itanium_class" "ialu")]) 540090075Sobrien 5401117395Skan;; As USE insns aren't meaningful after reload, this is used instead 5402117395Skan;; to prevent deleting instructions setting registers for EH handling 5403117395Skan(define_insn "prologue_use" 5404117395Skan [(unspec:DI [(match_operand:DI 0 "register_operand" "")] 5405117395Skan UNSPEC_PROLOGUE_USE)] 5406117395Skan "" 5407117395Skan "" 5408117395Skan [(set_attr "itanium_class" "ignore") 5409132718Skan (set_attr "predicable" "no") 5410132718Skan (set_attr "empty" "yes")]) 5411117395Skan 541290075Sobrien;; Allocate a new register frame. 541390075Sobrien 541490075Sobrien(define_insn "alloc" 541590075Sobrien [(set (match_operand:DI 0 "register_operand" "=r") 5416117395Skan (unspec_volatile:DI [(const_int 0)] UNSPECV_ALLOC)) 541790075Sobrien (use (match_operand:DI 1 "const_int_operand" "i")) 541890075Sobrien (use (match_operand:DI 2 "const_int_operand" "i")) 541990075Sobrien (use (match_operand:DI 3 "const_int_operand" "i")) 542090075Sobrien (use (match_operand:DI 4 "const_int_operand" "i"))] 542190075Sobrien "" 542290075Sobrien "alloc %0 = ar.pfs, %1, %2, %3, %4" 542390075Sobrien [(set_attr "itanium_class" "syst_m0") 542490075Sobrien (set_attr "predicable" "no")]) 542590075Sobrien 542690075Sobrien;; Modifies ar.unat 542790075Sobrien(define_expand "gr_spill" 542890075Sobrien [(parallel [(set (match_operand:DI 0 "memory_operand" "=m") 542990075Sobrien (unspec:DI [(match_operand:DI 1 "register_operand" "r") 5430117395Skan (match_operand:DI 2 "const_int_operand" "")] 5431117395Skan UNSPEC_GR_SPILL)) 543290075Sobrien (clobber (match_dup 3))])] 543390075Sobrien "" 543490075Sobrien "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);") 543590075Sobrien 543690075Sobrien(define_insn "gr_spill_internal" 543790075Sobrien [(set (match_operand:DI 0 "memory_operand" "=m") 543890075Sobrien (unspec:DI [(match_operand:DI 1 "register_operand" "r") 5439117395Skan (match_operand:DI 2 "const_int_operand" "")] 5440117395Skan UNSPEC_GR_SPILL)) 544190075Sobrien (clobber (match_operand:DI 3 "register_operand" ""))] 544290075Sobrien "" 544390075Sobrien{ 5444117395Skan /* Note that we use a C output pattern here to avoid the predicate 5445117395Skan being automatically added before the .mem.offset directive. */ 5446117395Skan return ".mem.offset %2, 0\;%,st8.spill %0 = %1%P0"; 5447117395Skan} 544890075Sobrien [(set_attr "itanium_class" "st")]) 544990075Sobrien 545090075Sobrien;; Reads ar.unat 545190075Sobrien(define_expand "gr_restore" 545290075Sobrien [(parallel [(set (match_operand:DI 0 "register_operand" "=r") 545390075Sobrien (unspec:DI [(match_operand:DI 1 "memory_operand" "m") 5454117395Skan (match_operand:DI 2 "const_int_operand" "")] 5455117395Skan UNSPEC_GR_RESTORE)) 545690075Sobrien (use (match_dup 3))])] 545790075Sobrien "" 545890075Sobrien "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);") 545990075Sobrien 546090075Sobrien(define_insn "gr_restore_internal" 546190075Sobrien [(set (match_operand:DI 0 "register_operand" "=r") 546290075Sobrien (unspec:DI [(match_operand:DI 1 "memory_operand" "m") 5463117395Skan (match_operand:DI 2 "const_int_operand" "")] 5464117395Skan UNSPEC_GR_RESTORE)) 546590075Sobrien (use (match_operand:DI 3 "register_operand" ""))] 546690075Sobrien "" 5467117395Skan { return ".mem.offset %2, 0\;%,ld8.fill %0 = %1%P1"; } 546890075Sobrien [(set_attr "itanium_class" "ld")]) 546990075Sobrien 547090075Sobrien(define_insn "fr_spill" 5471132718Skan [(set (match_operand:XF 0 "memory_operand" "=m") 5472132718Skan (unspec:XF [(match_operand:XF 1 "register_operand" "f")] 5473117395Skan UNSPEC_FR_SPILL))] 547490075Sobrien "" 547590075Sobrien "stf.spill %0 = %1%P0" 547690075Sobrien [(set_attr "itanium_class" "stf")]) 547790075Sobrien 547890075Sobrien(define_insn "fr_restore" 5479132718Skan [(set (match_operand:XF 0 "register_operand" "=f") 5480132718Skan (unspec:XF [(match_operand:XF 1 "memory_operand" "m")] 5481117395Skan UNSPEC_FR_RESTORE))] 548290075Sobrien "" 548390075Sobrien "ldf.fill %0 = %1%P1" 548490075Sobrien [(set_attr "itanium_class" "fld")]) 548590075Sobrien 548690075Sobrien;; ??? The explicit stop is not ideal. It would be better if 548790075Sobrien;; rtx_needs_barrier took care of this, but this is something that can be 548890075Sobrien;; fixed later. This avoids an RSE DV. 548990075Sobrien 549090075Sobrien(define_insn "bsp_value" 549190075Sobrien [(set (match_operand:DI 0 "register_operand" "=r") 5492117395Skan (unspec:DI [(const_int 0)] UNSPEC_BSP_VALUE))] 549390075Sobrien "" 5494117395Skan "* 5495117395Skan{ 5496117395Skan return \";;\;%,mov %0 = ar.bsp\"; 5497117395Skan}" 549890075Sobrien [(set_attr "itanium_class" "frar_i")]) 549990075Sobrien 550090075Sobrien(define_insn "set_bsp" 5501117395Skan [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")] 5502117395Skan UNSPECV_SET_BSP)] 550390075Sobrien "" 5504117395Skan "flushrs 5505117395Skan mov r19=ar.rsc 5506117395Skan ;; 5507117395Skan and r19=0x1c,r19 5508117395Skan ;; 5509117395Skan mov ar.rsc=r19 5510117395Skan ;; 5511117395Skan mov ar.bspstore=%0 5512117395Skan ;; 5513117395Skan or r19=0x3,r19 5514117395Skan ;; 5515117395Skan loadrs 5516117395Skan invala 5517117395Skan ;; 5518117395Skan mov ar.rsc=r19" 551990075Sobrien [(set_attr "itanium_class" "unknown") 552090075Sobrien (set_attr "predicable" "no")]) 552190075Sobrien 552290075Sobrien;; ??? The explicit stops are not ideal. It would be better if 552390075Sobrien;; rtx_needs_barrier took care of this, but this is something that can be 552490075Sobrien;; fixed later. This avoids an RSE DV. 552590075Sobrien 552690075Sobrien(define_insn "flushrs" 5527117395Skan [(unspec [(const_int 0)] UNSPEC_FLUSHRS)] 552890075Sobrien "" 552990075Sobrien ";;\;flushrs\;;;" 5530117395Skan [(set_attr "itanium_class" "rse_m") 5531117395Skan (set_attr "predicable" "no")]) 553290075Sobrien 553390075Sobrien;; :::::::::::::::::::: 553490075Sobrien;; :: 553590075Sobrien;; :: Miscellaneous instructions 553690075Sobrien;; :: 553790075Sobrien;; :::::::::::::::::::: 553890075Sobrien 5539132718Skan;; ??? Emitting a NOP instruction isn't very useful. This should probably 554090075Sobrien;; be emitting ";;" to force a break in the instruction packing. 554190075Sobrien 554290075Sobrien;; No operation, needed in case the user uses -g but not -O. 554390075Sobrien(define_insn "nop" 554490075Sobrien [(const_int 0)] 554590075Sobrien "" 554690075Sobrien "nop 0" 5547132718Skan [(set_attr "itanium_class" "nop")]) 554890075Sobrien 554990075Sobrien(define_insn "nop_m" 555090075Sobrien [(const_int 1)] 555190075Sobrien "" 555290075Sobrien "nop.m 0" 555390075Sobrien [(set_attr "itanium_class" "nop_m")]) 555490075Sobrien 555590075Sobrien(define_insn "nop_i" 555690075Sobrien [(const_int 2)] 555790075Sobrien "" 555890075Sobrien "nop.i 0" 555990075Sobrien [(set_attr "itanium_class" "nop_i")]) 556090075Sobrien 556190075Sobrien(define_insn "nop_f" 556290075Sobrien [(const_int 3)] 556390075Sobrien "" 556490075Sobrien "nop.f 0" 556590075Sobrien [(set_attr "itanium_class" "nop_f")]) 556690075Sobrien 556790075Sobrien(define_insn "nop_b" 556890075Sobrien [(const_int 4)] 556990075Sobrien "" 557090075Sobrien "nop.b 0" 557190075Sobrien [(set_attr "itanium_class" "nop_b")]) 557290075Sobrien 557390075Sobrien(define_insn "nop_x" 557490075Sobrien [(const_int 5)] 557590075Sobrien "" 557690075Sobrien "" 5577132718Skan [(set_attr "itanium_class" "nop_x") 5578132718Skan (set_attr "empty" "yes")]) 557990075Sobrien 5580132718Skan;; The following insn will be never generated. It is used only by 5581132718Skan;; insn scheduler to change state before advancing cycle. 5582132718Skan(define_insn "pre_cycle" 5583132718Skan [(const_int 6)] 5584132718Skan "" 5585132718Skan "" 5586132718Skan [(set_attr "itanium_class" "pre_cycle")]) 5587132718Skan 558890075Sobrien(define_insn "bundle_selector" 5589117395Skan [(unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BUNDLE_SELECTOR)] 559090075Sobrien "" 5591117395Skan { return get_bundle_name (INTVAL (operands[0])); } 559290075Sobrien [(set_attr "itanium_class" "ignore") 559390075Sobrien (set_attr "predicable" "no")]) 559490075Sobrien 559590075Sobrien;; Pseudo instruction that prevents the scheduler from moving code above this 559690075Sobrien;; point. 559790075Sobrien(define_insn "blockage" 5598117395Skan [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 559990075Sobrien "" 560090075Sobrien "" 560190075Sobrien [(set_attr "itanium_class" "ignore") 560290075Sobrien (set_attr "predicable" "no")]) 560390075Sobrien 560490075Sobrien(define_insn "insn_group_barrier" 5605117395Skan [(unspec_volatile [(match_operand 0 "const_int_operand" "")] 5606117395Skan UNSPECV_INSN_GROUP_BARRIER)] 560790075Sobrien "" 560890075Sobrien ";;" 560990075Sobrien [(set_attr "itanium_class" "stop_bit") 5610132718Skan (set_attr "predicable" "no") 5611132718Skan (set_attr "empty" "yes")]) 561290075Sobrien 561396263Sobrien(define_expand "trap" 561496263Sobrien [(trap_if (const_int 1) (const_int 0))] 561596263Sobrien "" 561696263Sobrien "") 561796263Sobrien 561896263Sobrien;; ??? We don't have a match-any slot type. Setting the type to unknown 561996263Sobrien;; produces worse code that setting the slot type to A. 562096263Sobrien 562196263Sobrien(define_insn "*trap" 562296263Sobrien [(trap_if (const_int 1) (match_operand 0 "const_int_operand" ""))] 562396263Sobrien "" 562496263Sobrien "break %0" 562596263Sobrien [(set_attr "itanium_class" "chk_s")]) 562696263Sobrien 562796263Sobrien(define_expand "conditional_trap" 562896263Sobrien [(trap_if (match_operand 0 "" "") (match_operand 1 "" ""))] 562996263Sobrien "" 563096263Sobrien{ 563196263Sobrien operands[0] = ia64_expand_compare (GET_CODE (operands[0]), VOIDmode); 563296263Sobrien}) 563396263Sobrien 563496263Sobrien(define_insn "*conditional_trap" 563596263Sobrien [(trap_if (match_operator 0 "predicate_operator" 563696263Sobrien [(match_operand:BI 1 "register_operand" "c") 563796263Sobrien (const_int 0)]) 563896263Sobrien (match_operand 2 "const_int_operand" ""))] 563996263Sobrien "" 564096263Sobrien "(%J0) break %2" 564196263Sobrien [(set_attr "itanium_class" "chk_s") 564296263Sobrien (set_attr "predicable" "no")]) 564396263Sobrien 564490075Sobrien(define_insn "break_f" 5645117395Skan [(unspec_volatile [(const_int 0)] UNSPECV_BREAK)] 564690075Sobrien "" 564790075Sobrien "break.f 0" 564890075Sobrien [(set_attr "itanium_class" "nop_f")]) 564990075Sobrien 565090075Sobrien(define_insn "prefetch" 565190075Sobrien [(prefetch (match_operand:DI 0 "address_operand" "p") 565290075Sobrien (match_operand:DI 1 "const_int_operand" "n") 565390075Sobrien (match_operand:DI 2 "const_int_operand" "n"))] 565490075Sobrien "" 565590075Sobrien{ 565690075Sobrien static const char * const alt[2][4] = { 565790075Sobrien { 5658119256Skan "%,lfetch.nta [%0]", 5659119256Skan "%,lfetch.nt1 [%0]", 5660119256Skan "%,lfetch.nt2 [%0]", 5661119256Skan "%,lfetch [%0]" 566290075Sobrien }, 566390075Sobrien { 5664119256Skan "%,lfetch.excl.nta [%0]", 5665119256Skan "%,lfetch.excl.nt1 [%0]", 5666119256Skan "%,lfetch.excl.nt2 [%0]", 5667119256Skan "%,lfetch.excl [%0]" 566890075Sobrien } 566990075Sobrien }; 567090075Sobrien int i = (INTVAL (operands[1])); 567190075Sobrien int j = (INTVAL (operands[2])); 567290075Sobrien 567390075Sobrien if (i != 0 && i != 1) 567490075Sobrien abort (); 567590075Sobrien if (j < 0 || j > 3) 567690075Sobrien abort (); 567790075Sobrien return alt[i][j]; 567890075Sobrien} 567990075Sobrien [(set_attr "itanium_class" "lfetch")]) 568090075Sobrien 568190075Sobrien;; Non-local goto support. 568290075Sobrien 568390075Sobrien(define_expand "save_stack_nonlocal" 568490075Sobrien [(use (match_operand:OI 0 "memory_operand" "")) 568590075Sobrien (use (match_operand:DI 1 "register_operand" ""))] 568690075Sobrien "" 568790075Sobrien{ 568890075Sobrien emit_library_call (gen_rtx_SYMBOL_REF (Pmode, 568990075Sobrien \"__ia64_save_stack_nonlocal\"), 569090075Sobrien 0, VOIDmode, 2, XEXP (operands[0], 0), Pmode, 569190075Sobrien operands[1], Pmode); 569290075Sobrien DONE; 5693117395Skan}) 569490075Sobrien 569590075Sobrien(define_expand "nonlocal_goto" 569690075Sobrien [(use (match_operand 0 "general_operand" "")) 569790075Sobrien (use (match_operand 1 "general_operand" "")) 569890075Sobrien (use (match_operand 2 "general_operand" "")) 569990075Sobrien (use (match_operand 3 "general_operand" ""))] 570090075Sobrien "" 570190075Sobrien{ 570290075Sobrien emit_library_call (gen_rtx_SYMBOL_REF (Pmode, \"__ia64_nonlocal_goto\"), 570390075Sobrien LCT_NORETURN, VOIDmode, 3, 570490075Sobrien operands[1], Pmode, 570590075Sobrien copy_to_reg (XEXP (operands[2], 0)), Pmode, 570690075Sobrien operands[3], Pmode); 570790075Sobrien emit_barrier (); 570890075Sobrien DONE; 5709117395Skan}) 571090075Sobrien 5711117395Skan(define_insn_and_split "builtin_setjmp_receiver" 5712117395Skan [(unspec_volatile [(match_operand:DI 0 "" "")] UNSPECV_SETJMP_RECEIVER)] 571390075Sobrien "" 5714117395Skan "#" 5715117395Skan "reload_completed" 5716117395Skan [(const_int 0)] 571790075Sobrien{ 5718117395Skan ia64_reload_gp (); 571990075Sobrien DONE; 5720117395Skan}) 572190075Sobrien 572290075Sobrien(define_expand "eh_epilogue" 572390075Sobrien [(use (match_operand:DI 0 "register_operand" "r")) 572490075Sobrien (use (match_operand:DI 1 "register_operand" "r")) 572590075Sobrien (use (match_operand:DI 2 "register_operand" "r"))] 572690075Sobrien "" 572790075Sobrien{ 572890075Sobrien rtx bsp = gen_rtx_REG (Pmode, 10); 572990075Sobrien rtx sp = gen_rtx_REG (Pmode, 9); 573090075Sobrien 573190075Sobrien if (GET_CODE (operands[0]) != REG || REGNO (operands[0]) != 10) 573290075Sobrien { 573390075Sobrien emit_move_insn (bsp, operands[0]); 573490075Sobrien operands[0] = bsp; 573590075Sobrien } 573690075Sobrien if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 9) 573790075Sobrien { 573890075Sobrien emit_move_insn (sp, operands[2]); 573990075Sobrien operands[2] = sp; 574090075Sobrien } 574190075Sobrien emit_insn (gen_rtx_USE (VOIDmode, sp)); 574290075Sobrien emit_insn (gen_rtx_USE (VOIDmode, bsp)); 574390075Sobrien 574490075Sobrien cfun->machine->ia64_eh_epilogue_sp = sp; 574590075Sobrien cfun->machine->ia64_eh_epilogue_bsp = bsp; 5746117395Skan}) 574790075Sobrien 574890075Sobrien;; Builtin apply support. 574990075Sobrien 575090075Sobrien(define_expand "restore_stack_nonlocal" 575190075Sobrien [(use (match_operand:DI 0 "register_operand" "")) 575290075Sobrien (use (match_operand:OI 1 "memory_operand" ""))] 575390075Sobrien "" 575490075Sobrien{ 575590075Sobrien emit_library_call (gen_rtx_SYMBOL_REF (Pmode, 5756117395Skan "__ia64_restore_stack_nonlocal"), 575790075Sobrien 0, VOIDmode, 1, 575890075Sobrien copy_to_reg (XEXP (operands[1], 0)), Pmode); 575990075Sobrien DONE; 5760117395Skan}) 576190075Sobrien 576290075Sobrien 576390075Sobrien;;; Intrinsics support. 576490075Sobrien 576590075Sobrien(define_expand "mf" 576690075Sobrien [(set (mem:BLK (match_dup 0)) 5767117395Skan (unspec:BLK [(mem:BLK (match_dup 0))] UNSPEC_MF))] 576890075Sobrien "" 576990075Sobrien{ 577090075Sobrien operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode)); 577190075Sobrien MEM_VOLATILE_P (operands[0]) = 1; 5772117395Skan}) 577390075Sobrien 577490075Sobrien(define_insn "*mf_internal" 577590075Sobrien [(set (match_operand:BLK 0 "" "") 5776117395Skan (unspec:BLK [(match_operand:BLK 1 "" "")] UNSPEC_MF))] 577790075Sobrien "" 577890075Sobrien "mf" 577990075Sobrien [(set_attr "itanium_class" "syst_m")]) 578090075Sobrien 578190075Sobrien(define_insn "fetchadd_acq_si" 578290075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 5783132718Skan (match_operand:SI 1 "not_postinc_memory_operand" "+S")) 5784132718Skan (set (match_dup 1) 578590075Sobrien (unspec:SI [(match_dup 1) 5786117395Skan (match_operand:SI 2 "fetchadd_operand" "n")] 5787117395Skan UNSPEC_FETCHADD_ACQ))] 578890075Sobrien "" 578990075Sobrien "fetchadd4.acq %0 = %1, %2" 579090075Sobrien [(set_attr "itanium_class" "sem")]) 579190075Sobrien 579290075Sobrien(define_insn "fetchadd_acq_di" 579390075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 5794132718Skan (match_operand:DI 1 "not_postinc_memory_operand" "+S")) 5795132718Skan (set (match_dup 1) 579690075Sobrien (unspec:DI [(match_dup 1) 5797117395Skan (match_operand:DI 2 "fetchadd_operand" "n")] 5798117395Skan UNSPEC_FETCHADD_ACQ))] 579990075Sobrien "" 580090075Sobrien "fetchadd8.acq %0 = %1, %2" 580190075Sobrien [(set_attr "itanium_class" "sem")]) 580290075Sobrien 580390075Sobrien(define_insn "cmpxchg_acq_si" 580490075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 5805132718Skan (match_operand:SI 1 "not_postinc_memory_operand" "+S")) 5806132718Skan (set (match_dup 1) 580790075Sobrien (unspec:SI [(match_dup 1) 580890075Sobrien (match_operand:SI 2 "gr_register_operand" "r") 5809132718Skan (match_operand:DI 3 "ar_ccv_reg_operand" "")] 5810117395Skan UNSPEC_CMPXCHG_ACQ))] 581190075Sobrien "" 581290075Sobrien "cmpxchg4.acq %0 = %1, %2, %3" 581390075Sobrien [(set_attr "itanium_class" "sem")]) 581490075Sobrien 581590075Sobrien(define_insn "cmpxchg_acq_di" 581690075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 5817132718Skan (match_operand:DI 1 "not_postinc_memory_operand" "+S")) 5818132718Skan (set (match_dup 1) 581990075Sobrien (unspec:DI [(match_dup 1) 582090075Sobrien (match_operand:DI 2 "gr_register_operand" "r") 5821117395Skan (match_operand:DI 3 "ar_ccv_reg_operand" "")] 5822117395Skan UNSPEC_CMPXCHG_ACQ))] 582390075Sobrien "" 582490075Sobrien "cmpxchg8.acq %0 = %1, %2, %3" 582590075Sobrien [(set_attr "itanium_class" "sem")]) 582690075Sobrien 582790075Sobrien(define_insn "xchgsi" 582890075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 582990075Sobrien (match_operand:SI 1 "not_postinc_memory_operand" "+S")) 583090075Sobrien (set (match_dup 1) 583190075Sobrien (match_operand:SI 2 "gr_register_operand" "r"))] 583290075Sobrien "" 583390075Sobrien "xchg4 %0 = %1, %2" 583490075Sobrien [(set_attr "itanium_class" "sem")]) 583590075Sobrien 583690075Sobrien(define_insn "xchgdi" 583790075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 583890075Sobrien (match_operand:DI 1 "not_postinc_memory_operand" "+S")) 583990075Sobrien (set (match_dup 1) 584090075Sobrien (match_operand:DI 2 "gr_register_operand" "r"))] 584190075Sobrien "" 584290075Sobrien "xchg8 %0 = %1, %2" 584390075Sobrien [(set_attr "itanium_class" "sem")]) 584490075Sobrien 584590075Sobrien;; Predication. 584690075Sobrien 584790075Sobrien(define_cond_exec 584890075Sobrien [(match_operator 0 "predicate_operator" 584990075Sobrien [(match_operand:BI 1 "register_operand" "c") 585090075Sobrien (const_int 0)])] 585190075Sobrien "" 585290075Sobrien "(%J0)") 585390075Sobrien 585490075Sobrien(define_insn "pred_rel_mutex" 585590075Sobrien [(set (match_operand:BI 0 "register_operand" "+c") 5856117395Skan (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))] 585790075Sobrien "" 585890075Sobrien ".pred.rel.mutex %0, %I0" 585990075Sobrien [(set_attr "itanium_class" "ignore") 586090075Sobrien (set_attr "predicable" "no")]) 586190075Sobrien 586290075Sobrien(define_insn "safe_across_calls_all" 5863117395Skan [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_ALL)] 586490075Sobrien "" 586590075Sobrien ".pred.safe_across_calls p1-p63" 586690075Sobrien [(set_attr "itanium_class" "ignore") 586790075Sobrien (set_attr "predicable" "no")]) 586890075Sobrien 586990075Sobrien(define_insn "safe_across_calls_normal" 5870117395Skan [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_NORMAL)] 587190075Sobrien "" 587290075Sobrien{ 5873132718Skan emit_safe_across_calls (); 5874117395Skan return ""; 5875117395Skan} 587690075Sobrien [(set_attr "itanium_class" "ignore") 587790075Sobrien (set_attr "predicable" "no")]) 587890075Sobrien 587990075Sobrien;; UNSPEC instruction definition to "swizzle" 32 bit pointer into 64 bit 588090075Sobrien;; pointer. This is used by the HP-UX 32 bit mode. 588190075Sobrien 588290075Sobrien(define_insn "ptr_extend" 588390075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 5884117395Skan (unspec:DI [(match_operand:SI 1 "gr_register_operand" "r")] 5885117395Skan UNSPEC_ADDP4))] 588690075Sobrien "" 588790075Sobrien "addp4 %0 = 0,%1" 588890075Sobrien [(set_attr "itanium_class" "ialu")]) 588990075Sobrien 589090075Sobrien;; 5891117395Skan;; Optimizations for ptr_extend 5892117395Skan 5893132718Skan(define_insn "ptr_extend_plus_imm" 5894117395Skan [(set (match_operand:DI 0 "gr_register_operand" "=r") 5895117395Skan (unspec:DI 5896117395Skan [(plus:SI (match_operand:SI 1 "basereg_operand" "r") 5897117395Skan (match_operand:SI 2 "gr_reg_or_14bit_operand" "rI"))] 5898117395Skan UNSPEC_ADDP4))] 5899117395Skan "addp4_optimize_ok (operands[1], operands[2])" 5900117395Skan "addp4 %0 = %2, %1" 5901117395Skan [(set_attr "itanium_class" "ialu")]) 5902117395Skan 5903117395Skan(define_insn "*ptr_extend_plus_2" 5904117395Skan [(set (match_operand:DI 0 "gr_register_operand" "=r") 5905117395Skan (unspec:DI 5906117395Skan [(plus:SI (match_operand:SI 1 "gr_register_operand" "r") 5907117395Skan (match_operand:SI 2 "basereg_operand" "r"))] 5908117395Skan UNSPEC_ADDP4))] 5909117395Skan "addp4_optimize_ok (operands[1], operands[2])" 5910117395Skan "addp4 %0 = %1, %2" 5911117395Skan [(set_attr "itanium_class" "ialu")]) 5912