190075Sobrien;; IA-64 Machine description template 2169689Skan;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 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 21169689Skan;; the Free Software Foundation, 51 Franklin Street, Fifth Floor, 22169689Skan;; Boston, MA 02110-1301, 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) 59169689Skan (UNSPEC_DTPMOD 5) 60117395Skan 61117395Skan (UNSPEC_LD_BASE 9) 62117395Skan (UNSPEC_GR_SPILL 10) 63117395Skan (UNSPEC_GR_RESTORE 11) 64117395Skan (UNSPEC_FR_SPILL 12) 65117395Skan (UNSPEC_FR_RESTORE 13) 66117395Skan (UNSPEC_FR_RECIP_APPROX 14) 67117395Skan (UNSPEC_PRED_REL_MUTEX 15) 68132718Skan (UNSPEC_GETF_EXP 16) 69117395Skan (UNSPEC_PIC_CALL 17) 70117395Skan (UNSPEC_MF 18) 71117395Skan (UNSPEC_CMPXCHG_ACQ 19) 72117395Skan (UNSPEC_FETCHADD_ACQ 20) 73117395Skan (UNSPEC_BSP_VALUE 21) 74117395Skan (UNSPEC_FLUSHRS 22) 75117395Skan (UNSPEC_BUNDLE_SELECTOR 23) 76117395Skan (UNSPEC_ADDP4 24) 77117395Skan (UNSPEC_PROLOGUE_USE 25) 78122180Skan (UNSPEC_RET_ADDR 26) 79132718Skan (UNSPEC_SETF_EXP 27) 80132718Skan (UNSPEC_FR_SQRT_RECIP_APPROX 28) 81169689Skan (UNSPEC_SHRP 29) 82169689Skan (UNSPEC_COPYSIGN 30) 83169689Skan (UNSPEC_VECT_EXTR 31) 84169689Skan (UNSPEC_LDA 40) 85169689Skan (UNSPEC_LDS 41) 86169689Skan (UNSPEC_LDSA 42) 87169689Skan (UNSPEC_LDCCLR 43) 88169689Skan (UNSPEC_CHKACLR 45) 89169689Skan (UNSPEC_CHKS 47) 90117395Skan ]) 91117395Skan 92117395Skan(define_constants 93117395Skan [(UNSPECV_ALLOC 0) 94117395Skan (UNSPECV_BLOCKAGE 1) 95117395Skan (UNSPECV_INSN_GROUP_BARRIER 2) 96117395Skan (UNSPECV_BREAK 3) 97117395Skan (UNSPECV_SET_BSP 4) 98117395Skan (UNSPECV_PSAC_ALL 5) ; pred.safe_across_calls 99117395Skan (UNSPECV_PSAC_NORMAL 6) 100117395Skan (UNSPECV_SETJMP_RECEIVER 7) 101117395Skan ]) 102169689Skan 103169689Skan(include "predicates.md") 10490075Sobrien 10590075Sobrien;; :::::::::::::::::::: 10690075Sobrien;; :: 10790075Sobrien;; :: Attributes 10890075Sobrien;; :: 10990075Sobrien;; :::::::::::::::::::: 11090075Sobrien 111132718Skan;; Processor type. This attribute must exactly match the processor_type 112132718Skan;; enumeration in ia64.h. 113132718Skan(define_attr "cpu" "itanium,itanium2" (const (symbol_ref "ia64_tune"))) 114132718Skan 11590075Sobrien;; Instruction type. This primarily determines how instructions can be 11690075Sobrien;; packed in bundles, and secondarily affects scheduling to function units. 11790075Sobrien 11890075Sobrien;; A alu, can go in I or M syllable of a bundle 11990075Sobrien;; I integer 12090075Sobrien;; M memory 12190075Sobrien;; F floating-point 12290075Sobrien;; B branch 12390075Sobrien;; L long immediate, takes two syllables 12490075Sobrien;; S stop bit 12590075Sobrien 12690075Sobrien;; ??? Should not have any pattern with type unknown. Perhaps add code to 12790075Sobrien;; check this in md_reorg? Currently use unknown for patterns which emit 12890075Sobrien;; multiple instructions, patterns which emit 0 instructions, and patterns 12990075Sobrien;; which emit instruction that can go in any slot (e.g. nop). 13090075Sobrien 131117395Skan(define_attr "itanium_class" "unknown,ignore,stop_bit,br,fcmp,fcvtfx,fld, 132169689Skan fldp,fmac,fmisc,frar_i,frar_m,frbr,frfr,frpr,ialu,icmp,ilog,ishf, 133169689Skan ld,chk_s_i,chk_s_f,chk_a,long_i,mmalua,mmmul,mmshf,mmshfi,rse_m,scall,sem,stf, 134169689Skan st,syst_m0, syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop, 135169689Skan nop_b,nop_f,nop_i,nop_m,nop_x,lfetch,pre_cycle" 136117395Skan (const_string "unknown")) 13790075Sobrien 138169689Skan;; chk_s_i has an I and an M form; use type A for convenience. 13990075Sobrien(define_attr "type" "unknown,A,I,M,F,B,L,X,S" 140169689Skan (cond [(eq_attr "itanium_class" "ld,st,fld,fldp,stf,sem,nop_m") (const_string "M") 14190075Sobrien (eq_attr "itanium_class" "rse_m,syst_m,syst_m0") (const_string "M") 14290075Sobrien (eq_attr "itanium_class" "frar_m,toar_m,frfr,tofr") (const_string "M") 14390075Sobrien (eq_attr "itanium_class" "lfetch") (const_string "M") 144169689Skan (eq_attr "itanium_class" "chk_s_f,chk_a") (const_string "M") 145169689Skan (eq_attr "itanium_class" "chk_s_i,ialu,icmp,ilog,mmalua") 146169689Skan (const_string "A") 14790075Sobrien (eq_attr "itanium_class" "fmisc,fmac,fcmp,xmpy") (const_string "F") 14890075Sobrien (eq_attr "itanium_class" "fcvtfx,nop_f") (const_string "F") 14990075Sobrien (eq_attr "itanium_class" "frar_i,toar_i,frbr,tobr") (const_string "I") 15090075Sobrien (eq_attr "itanium_class" "frpr,topr,ishf,xtd,tbit") (const_string "I") 15190075Sobrien (eq_attr "itanium_class" "mmmul,mmshf,mmshfi,nop_i") (const_string "I") 15290075Sobrien (eq_attr "itanium_class" "br,scall,nop_b") (const_string "B") 15390075Sobrien (eq_attr "itanium_class" "stop_bit") (const_string "S") 15490075Sobrien (eq_attr "itanium_class" "nop_x") (const_string "X") 15590075Sobrien (eq_attr "itanium_class" "long_i") (const_string "L")] 15690075Sobrien (const_string "unknown"))) 15790075Sobrien 15890075Sobrien(define_attr "itanium_requires_unit0" "no,yes" 15990075Sobrien (cond [(eq_attr "itanium_class" "syst_m0,sem,frfr,rse_m") (const_string "yes") 16090075Sobrien (eq_attr "itanium_class" "toar_m,frar_m") (const_string "yes") 16190075Sobrien (eq_attr "itanium_class" "frbr,tobr,mmmul") (const_string "yes") 16290075Sobrien (eq_attr "itanium_class" "tbit,ishf,topr,frpr") (const_string "yes") 16390075Sobrien (eq_attr "itanium_class" "toar_i,frar_i") (const_string "yes") 16490075Sobrien (eq_attr "itanium_class" "fmisc,fcmp") (const_string "yes")] 16590075Sobrien (const_string "no"))) 16690075Sobrien 16790075Sobrien;; Predication. True iff this instruction can be predicated. 16890075Sobrien 16990075Sobrien(define_attr "predicable" "no,yes" (const_string "yes")) 17090075Sobrien 171132718Skan;; Empty. True iff this insn does not generate any code. 172132718Skan 173132718Skan(define_attr "empty" "no,yes" (const_string "no")) 174132718Skan 175169689Skan;; True iff this insn must be the first insn of an instruction group. 176169689Skan;; This is true for the alloc instruction, and will also be true of others 177169689Skan;; when we have full intrinsics support. 178169689Skan 179169689Skan(define_attr "first_insn" "no,yes" (const_string "no")) 180169689Skan 181169689Skan(define_attr "data_speculative" "no,yes" (const_string "no")) 182169689Skan 183169689Skan(define_attr "control_speculative" "no,yes" (const_string "no")) 184169689Skan 185169689Skan(define_attr "check_load" "no,yes" (const_string "no")) 18690075Sobrien 187132718Skan;; DFA descriptions of ia64 processors used for insn scheduling and 188132718Skan;; bundling. 18990075Sobrien 190132718Skan(automata_option "ndfa") 19190075Sobrien 192132718Skan;; Uncomment the following line to output automata for debugging. 193132718Skan;; (automata_option "v") 19490075Sobrien 195132718Skan(automata_option "w") 19690075Sobrien 197132718Skan(include "itanium1.md") 198132718Skan(include "itanium2.md") 19990075Sobrien 20090075Sobrien 20190075Sobrien;; :::::::::::::::::::: 20290075Sobrien;; :: 20390075Sobrien;; :: Moves 20490075Sobrien;; :: 20590075Sobrien;; :::::::::::::::::::: 20690075Sobrien 20790075Sobrien;; Set of a single predicate register. This is only used to implement 20890075Sobrien;; pr-to-pr move and complement. 20990075Sobrien 21090075Sobrien(define_insn "*movcci" 21190075Sobrien [(set (match_operand:CCI 0 "register_operand" "=c,c,c") 21290075Sobrien (match_operand:CCI 1 "nonmemory_operand" "O,n,c"))] 21390075Sobrien "" 21490075Sobrien "@ 21590075Sobrien cmp.ne %0, p0 = r0, r0 21690075Sobrien cmp.eq %0, p0 = r0, r0 21790075Sobrien (%1) cmp.eq.unc %0, p0 = r0, r0" 21890075Sobrien [(set_attr "itanium_class" "icmp") 21990075Sobrien (set_attr "predicable" "no")]) 22090075Sobrien 22190075Sobrien(define_insn "movbi" 222169689Skan [(set (match_operand:BI 0 "destination_operand" "=c,c,?c,?*r, c,*r,*r,*m,*r") 223169689Skan (match_operand:BI 1 "move_operand" " O,n, c, c,*r, n,*m,*r,*r"))] 22490075Sobrien "" 22590075Sobrien "@ 22690075Sobrien cmp.ne %0, %I0 = r0, r0 22790075Sobrien cmp.eq %0, %I0 = r0, r0 22890075Sobrien # 22990075Sobrien # 23090075Sobrien tbit.nz %0, %I0 = %1, 0 23190075Sobrien adds %0 = %1, r0 23290075Sobrien ld1%O1 %0 = %1%P1 23390075Sobrien st1%Q0 %0 = %1%P0 23490075Sobrien mov %0 = %1" 23590075Sobrien [(set_attr "itanium_class" "icmp,icmp,unknown,unknown,tbit,ialu,ld,st,ialu")]) 23690075Sobrien 23790075Sobrien(define_split 23890075Sobrien [(set (match_operand:BI 0 "register_operand" "") 23990075Sobrien (match_operand:BI 1 "register_operand" ""))] 24090075Sobrien "reload_completed 24190075Sobrien && GET_CODE (operands[0]) == REG && GR_REGNO_P (REGNO (operands[0])) 24290075Sobrien && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))" 24390075Sobrien [(cond_exec (ne (match_dup 1) (const_int 0)) 24490075Sobrien (set (match_dup 0) (const_int 1))) 24590075Sobrien (cond_exec (eq (match_dup 1) (const_int 0)) 24690075Sobrien (set (match_dup 0) (const_int 0)))] 24790075Sobrien "") 24890075Sobrien 24990075Sobrien(define_split 25090075Sobrien [(set (match_operand:BI 0 "register_operand" "") 25190075Sobrien (match_operand:BI 1 "register_operand" ""))] 25290075Sobrien "reload_completed 25390075Sobrien && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0])) 25490075Sobrien && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))" 25590075Sobrien [(set (match_dup 2) (match_dup 4)) 25690075Sobrien (set (match_dup 3) (match_dup 5)) 257117395Skan (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))] 25890075Sobrien "operands[2] = gen_rtx_REG (CCImode, REGNO (operands[0])); 25990075Sobrien operands[3] = gen_rtx_REG (CCImode, REGNO (operands[0]) + 1); 26090075Sobrien operands[4] = gen_rtx_REG (CCImode, REGNO (operands[1])); 26190075Sobrien operands[5] = gen_rtx_REG (CCImode, REGNO (operands[1]) + 1);") 26290075Sobrien 26390075Sobrien(define_expand "movqi" 26490075Sobrien [(set (match_operand:QI 0 "general_operand" "") 26590075Sobrien (match_operand:QI 1 "general_operand" ""))] 26690075Sobrien "" 26790075Sobrien{ 268117395Skan rtx op1 = ia64_expand_move (operands[0], operands[1]); 269117395Skan if (!op1) 270117395Skan DONE; 271117395Skan operands[1] = op1; 272117395Skan}) 27390075Sobrien 27490075Sobrien(define_insn "*movqi_internal" 27590075Sobrien [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f") 27690075Sobrien (match_operand:QI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))] 27790075Sobrien "ia64_move_ok (operands[0], operands[1])" 27890075Sobrien "@ 27990075Sobrien mov %0 = %r1 28090075Sobrien addl %0 = %1, r0 28190075Sobrien ld1%O1 %0 = %1%P1 28290075Sobrien st1%Q0 %0 = %r1%P0 28390075Sobrien getf.sig %0 = %1 28490075Sobrien setf.sig %0 = %r1 28590075Sobrien mov %0 = %1" 28690075Sobrien [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")]) 28790075Sobrien 28890075Sobrien(define_expand "movhi" 28990075Sobrien [(set (match_operand:HI 0 "general_operand" "") 29090075Sobrien (match_operand:HI 1 "general_operand" ""))] 29190075Sobrien "" 29290075Sobrien{ 293117395Skan rtx op1 = ia64_expand_move (operands[0], operands[1]); 294117395Skan if (!op1) 295117395Skan DONE; 296117395Skan operands[1] = op1; 297117395Skan}) 29890075Sobrien 29990075Sobrien(define_insn "*movhi_internal" 30090075Sobrien [(set (match_operand:HI 0 "destination_operand" "=r,r,r, m, r,*f,*f") 30190075Sobrien (match_operand:HI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))] 30290075Sobrien "ia64_move_ok (operands[0], operands[1])" 30390075Sobrien "@ 30490075Sobrien mov %0 = %r1 30590075Sobrien addl %0 = %1, r0 30690075Sobrien ld2%O1 %0 = %1%P1 30790075Sobrien st2%Q0 %0 = %r1%P0 30890075Sobrien getf.sig %0 = %1 30990075Sobrien setf.sig %0 = %r1 31090075Sobrien mov %0 = %1" 31190075Sobrien [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")]) 31290075Sobrien 31390075Sobrien(define_expand "movsi" 31490075Sobrien [(set (match_operand:SI 0 "general_operand" "") 31590075Sobrien (match_operand:SI 1 "general_operand" ""))] 31690075Sobrien "" 31790075Sobrien{ 318117395Skan rtx op1 = ia64_expand_move (operands[0], operands[1]); 319117395Skan if (!op1) 320117395Skan DONE; 321117395Skan operands[1] = op1; 322117395Skan}) 32390075Sobrien 32490075Sobrien(define_insn "*movsi_internal" 32590075Sobrien [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d") 32690075Sobrien (match_operand:SI 1 "move_operand" "rO,J,i,m,rO,*f,rO,*f,*d,rK"))] 32790075Sobrien "ia64_move_ok (operands[0], operands[1])" 32890075Sobrien "@ 32990075Sobrien mov %0 = %r1 33090075Sobrien addl %0 = %1, r0 33190075Sobrien movl %0 = %1 33290075Sobrien ld4%O1 %0 = %1%P1 33390075Sobrien st4%Q0 %0 = %r1%P0 33490075Sobrien getf.sig %0 = %1 33590075Sobrien setf.sig %0 = %r1 33690075Sobrien mov %0 = %1 33790075Sobrien mov %0 = %1 33890075Sobrien mov %0 = %r1" 339117395Skan ;; frar_m, toar_m ??? why not frar_i and toar_i 34090075Sobrien [(set_attr "itanium_class" "ialu,ialu,long_i,ld,st,frfr,tofr,fmisc,frar_m,toar_m")]) 34190075Sobrien 34290075Sobrien(define_expand "movdi" 34390075Sobrien [(set (match_operand:DI 0 "general_operand" "") 34490075Sobrien (match_operand:DI 1 "general_operand" ""))] 34590075Sobrien "" 34690075Sobrien{ 347117395Skan rtx op1 = ia64_expand_move (operands[0], operands[1]); 348117395Skan if (!op1) 349117395Skan DONE; 350117395Skan operands[1] = op1; 351117395Skan}) 35290075Sobrien 35390075Sobrien(define_insn "*movdi_internal" 35490075Sobrien [(set (match_operand:DI 0 "destination_operand" 35590075Sobrien "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b, r,*e, r,*d, r,*c") 35690075Sobrien (match_operand:DI 1 "move_operand" 357132718Skan "rO,JT,i,m,rO,*f,rO,*f, Q,*f,*b,rO,*e,rK,*d,rK,*c,rO"))] 35890075Sobrien "ia64_move_ok (operands[0], operands[1])" 35990075Sobrien{ 36090075Sobrien static const char * const alt[] = { 361117395Skan "%,mov %0 = %r1", 362117395Skan "%,addl %0 = %1, r0", 363117395Skan "%,movl %0 = %1", 364117395Skan "%,ld8%O1 %0 = %1%P1", 365117395Skan "%,st8%Q0 %0 = %r1%P0", 366117395Skan "%,getf.sig %0 = %1", 367117395Skan "%,setf.sig %0 = %r1", 368117395Skan "%,mov %0 = %1", 369117395Skan "%,ldf8 %0 = %1%P1", 370117395Skan "%,stf8 %0 = %1%P0", 371117395Skan "%,mov %0 = %1", 372117395Skan "%,mov %0 = %r1", 373117395Skan "%,mov %0 = %1", 374117395Skan "%,mov %0 = %1", 375117395Skan "%,mov %0 = %1", 376117395Skan "%,mov %0 = %1", 377117395Skan "mov %0 = pr", 378117395Skan "mov pr = %1, -1" 37990075Sobrien }; 38090075Sobrien 381169689Skan gcc_assert (which_alternative != 2 || TARGET_NO_PIC 382169689Skan || !symbolic_operand (operands[1], VOIDmode)); 38390075Sobrien 38490075Sobrien return alt[which_alternative]; 385117395Skan} 38690075Sobrien [(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")]) 38790075Sobrien 388169689Skan(define_mode_macro MODE [BI QI HI SI DI SF DF XF TI]) 389169689Skan(define_mode_macro MODE_FOR_EXTEND [QI HI SI]) 390169689Skan 391169689Skan(define_mode_attr output_a [ 392169689Skan (BI "ld1.a %0 = %1%P1") 393169689Skan (QI "ld1.a %0 = %1%P1") 394169689Skan (HI "ld2.a %0 = %1%P1") 395169689Skan (SI "ld4.a %0 = %1%P1") 396169689Skan (DI 397169689Skan "@ 398169689Skan ld8.a %0 = %1%P1 399169689Skan ldf8.a %0 = %1%P1") 400169689Skan (SF 401169689Skan "@ 402169689Skan ldfs.a %0 = %1%P1 403169689Skan ld4.a %0 = %1%P1") 404169689Skan (DF 405169689Skan "@ 406169689Skan ldfd.a %0 = %1%P1 407169689Skan ld8.a %0 = %1%P1") 408169689Skan (XF "ldfe.a %0 = %1%P1") 409169689Skan (TI "ldfp8.a %X0 = %1%P1")]) 410169689Skan 411169689Skan(define_mode_attr output_s [ 412169689Skan (BI "ld1.s %0 = %1%P1") 413169689Skan (QI "ld1.s %0 = %1%P1") 414169689Skan (HI "ld2.s %0 = %1%P1") 415169689Skan (SI "ld4.s %0 = %1%P1") 416169689Skan (DI 417169689Skan "@ 418169689Skan ld8.s %0 = %1%P1 419169689Skan ldf8.s %0 = %1%P1") 420169689Skan (SF 421169689Skan "@ 422169689Skan ldfs.s %0 = %1%P1 423169689Skan ld4.s %0 = %1%P1") 424169689Skan (DF 425169689Skan "@ 426169689Skan ldfd.s %0 = %1%P1 427169689Skan ld8.s %0 = %1%P1") 428169689Skan (XF "ldfe.s %0 = %1%P1") 429169689Skan (TI "ldfp8.s %X0 = %1%P1")]) 430169689Skan 431169689Skan(define_mode_attr output_sa [ 432169689Skan (BI "ld1.sa %0 = %1%P1") 433169689Skan (QI "ld1.sa %0 = %1%P1") 434169689Skan (HI "ld2.sa %0 = %1%P1") 435169689Skan (SI "ld4.sa %0 = %1%P1") 436169689Skan (DI 437169689Skan "@ 438169689Skan ld8.sa %0 = %1%P1 439169689Skan ldf8.sa %0 = %1%P1") 440169689Skan (SF 441169689Skan "@ 442169689Skan ldfs.sa %0 = %1%P1 443169689Skan ld4.sa %0 = %1%P1") 444169689Skan (DF 445169689Skan "@ 446169689Skan ldfd.sa %0 = %1%P1 447169689Skan ld8.sa %0 = %1%P1") 448169689Skan (XF "ldfe.sa %0 = %1%P1") 449169689Skan (TI "ldfp8.sa %X0 = %1%P1")]) 450169689Skan 451169689Skan(define_mode_attr output_c_clr [ 452169689Skan (BI "ld1.c.clr%O1 %0 = %1%P1") 453169689Skan (QI "ld1.c.clr%O1 %0 = %1%P1") 454169689Skan (HI "ld2.c.clr%O1 %0 = %1%P1") 455169689Skan (SI "ld4.c.clr%O1 %0 = %1%P1") 456169689Skan (DI 457169689Skan "@ 458169689Skan ld8.c.clr%O1 %0 = %1%P1 459169689Skan ldf8.c.clr %0 = %1%P1") 460169689Skan (SF 461169689Skan "@ 462169689Skan ldfs.c.clr %0 = %1%P1 463169689Skan ld4.c.clr%O1 %0 = %1%P1") 464169689Skan (DF 465169689Skan "@ 466169689Skan ldfd.c.clr %0 = %1%P1 467169689Skan ld8.c.clr%O1 %0 = %1%P1") 468169689Skan (XF "ldfe.c.clr %0 = %1%P1") 469169689Skan (TI "ldfp8.c.clr %X0 = %1%P1")]) 470169689Skan 471169689Skan(define_mode_attr ld_reg_constr [(BI "=*r") (QI "=r") (HI "=r") (SI "=r") (DI "=r,*f") (SF "=f,*r") (DF "=f,*r") (XF "=f") (TI "=*x")]) 472169689Skan(define_mode_attr ldc_reg_constr [(BI "+*r") (QI "+r") (HI "+r") (SI "+r") (DI "+r,*f") (SF "+f,*r") (DF "+f,*r") (XF "+f") (TI "+*x")]) 473169689Skan(define_mode_attr chk_reg_constr [(BI "*r") (QI "r") (HI "r") (SI "r") (DI "r,*f") (SF "f,*r") (DF "f,*r") (XF "f") (TI "*x")]) 474169689Skan 475169689Skan(define_mode_attr mem_constr [(BI "*m") (QI "m") (HI "m") (SI "m") (DI "m,Q") (SF "Q,m") (DF "Q,m") (XF "m") (TI "Q")]) 476169689Skan 477169689Skan;; Define register predicate prefix. 478169689Skan;; We can generate speculative loads only for general and fp registers - this 479169689Skan;; is constrainted in ia64.c: ia64_speculate_insn (). 480169689Skan(define_mode_attr reg_pred_prefix [(BI "gr") (QI "gr") (HI "gr") (SI "gr") (DI "grfr") (SF "grfr") (DF "grfr") (XF "fr") (TI "fr")]) 481169689Skan 482169689Skan(define_mode_attr ld_class [(BI "ld") (QI "ld") (HI "ld") (SI "ld") (DI "ld,fld") (SF "fld,ld") (DF "fld,ld") (XF "fld") (TI "fldp")]) 483169689Skan(define_mode_attr chka_class [(BI "chk_a") (QI "chk_a") (HI "chk_a") (SI "chk_a") (DI "chk_a,chk_a") (SF "chk_a,chk_a") (DF "chk_a,chk_a") (XF "chk_a") (TI "chk_a")]) 484169689Skan(define_mode_attr chks_class [(BI "chk_s_i") (QI "chk_s_i") (HI "chk_s_i") (SI "chk_s_i") (DI "chk_s_i,chk_s_f") (SF "chk_s_f,chk_s_i") (DF "chk_s_f,chk_s_i") (XF "chk_s_f") (TI "chk_s_i")]) 485169689Skan 486169689Skan(define_mode_attr attr_yes [(BI "yes") (QI "yes") (HI "yes") (SI "yes") (DI "yes,yes") (SF "yes,yes") (DF "yes,yes") (XF "yes") (TI "yes")]) 487169689Skan 488169689Skan(define_insn "mov<mode>_advanced" 489169689Skan [(set (match_operand:MODE 0 "<reg_pred_prefix>_register_operand" "<ld_reg_constr>") 490169689Skan (unspec:MODE [(match_operand:MODE 1 "memory_operand" "<mem_constr>")] UNSPEC_LDA))] 491169689Skan "ia64_move_ok (operands[0], operands[1])" 492169689Skan "<output_a>" 493169689Skan [(set_attr "itanium_class" "<ld_class>") 494169689Skan (set_attr "data_speculative" "<attr_yes>")]) 495169689Skan 496169689Skan(define_insn "zero_extend<mode>di2_advanced" 497169689Skan [(set (match_operand:DI 0 "gr_register_operand" "=r") 498169689Skan (zero_extend:DI (unspec:MODE_FOR_EXTEND [(match_operand:MODE_FOR_EXTEND 1 "memory_operand" "<mem_constr>")] UNSPEC_LDA)))] 499169689Skan "" 500169689Skan "<output_a>" 501169689Skan [(set_attr "itanium_class" "<ld_class>") 502169689Skan (set_attr "data_speculative" "<attr_yes>")]) 503169689Skan 504169689Skan(define_insn "mov<mode>_speculative" 505169689Skan [(set (match_operand:MODE 0 "<reg_pred_prefix>_register_operand" "<ld_reg_constr>") 506169689Skan (unspec:MODE [(match_operand:MODE 1 "memory_operand" "<mem_constr>")] UNSPEC_LDS))] 507169689Skan "ia64_move_ok (operands[0], operands[1])" 508169689Skan "<output_s>" 509169689Skan [(set_attr "itanium_class" "<ld_class>") 510169689Skan (set_attr "control_speculative" "<attr_yes>")]) 511169689Skan 512169689Skan(define_insn "zero_extend<mode>di2_speculative" 513169689Skan [(set (match_operand:DI 0 "gr_register_operand" "=r") 514169689Skan (zero_extend:DI (unspec:MODE_FOR_EXTEND [(match_operand:MODE_FOR_EXTEND 1 "memory_operand" "<mem_constr>")] UNSPEC_LDS)))] 515169689Skan "" 516169689Skan "<output_s>" 517169689Skan [(set_attr "itanium_class" "<ld_class>") 518169689Skan (set_attr "control_speculative" "<attr_yes>")]) 519169689Skan 520169689Skan(define_insn "mov<mode>_speculative_advanced" 521169689Skan [(set (match_operand:MODE 0 "<reg_pred_prefix>_register_operand" "<ld_reg_constr>") 522169689Skan (unspec:MODE [(match_operand:MODE 1 "memory_operand" "<mem_constr>")] UNSPEC_LDSA))] 523169689Skan "ia64_move_ok (operands[0], operands[1])" 524169689Skan "<output_sa>" 525169689Skan [(set_attr "itanium_class" "<ld_class>") 526169689Skan (set_attr "data_speculative" "<attr_yes>") 527169689Skan (set_attr "control_speculative" "<attr_yes>")]) 528169689Skan 529169689Skan(define_insn "zero_extend<mode>di2_speculative_advanced" 530169689Skan [(set (match_operand:DI 0 "gr_register_operand" "=r") 531169689Skan (zero_extend:DI (unspec:MODE_FOR_EXTEND [(match_operand:MODE_FOR_EXTEND 1 "memory_operand" "<mem_constr>")] UNSPEC_LDSA)))] 532169689Skan "" 533169689Skan "<output_sa>" 534169689Skan [(set_attr "itanium_class" "<ld_class>") 535169689Skan (set_attr "data_speculative" "<attr_yes>") 536169689Skan (set_attr "control_speculative" "<attr_yes>")]) 537169689Skan 538169689Skan(define_insn "mov<mode>_clr" 539169689Skan [(set (match_operand:MODE 0 "<reg_pred_prefix>_register_operand" "<ldc_reg_constr>") 540169689Skan (if_then_else:MODE (ne (unspec [(match_dup 0)] UNSPEC_LDCCLR) (const_int 0)) 541169689Skan (match_operand:MODE 1 "memory_operand" "<mem_constr>") 542169689Skan (match_dup 0)))] 543169689Skan "ia64_move_ok (operands[0], operands[1])" 544169689Skan "<output_c_clr>" 545169689Skan [(set_attr "itanium_class" "<ld_class>") 546169689Skan (set_attr "check_load" "<attr_yes>")]) 547169689Skan 548169689Skan(define_insn "zero_extend<mode>di2_clr" 549169689Skan [(set (match_operand:DI 0 "gr_register_operand" "+r") 550169689Skan (if_then_else:DI (ne (unspec [(match_dup 0)] UNSPEC_LDCCLR) (const_int 0)) 551169689Skan (zero_extend:DI (match_operand:MODE_FOR_EXTEND 1 "memory_operand" "<mem_constr>")) 552169689Skan (match_dup 0)))] 553169689Skan "" 554169689Skan "<output_c_clr>" 555169689Skan [(set_attr "itanium_class" "<ld_class>") 556169689Skan (set_attr "check_load" "<attr_yes>")]) 557169689Skan 558169689Skan(define_insn "advanced_load_check_clr_<mode>" 559169689Skan [(set (pc) 560169689Skan (if_then_else (ne (unspec [(match_operand:MODE 0 "<reg_pred_prefix>_register_operand" "<chk_reg_constr>")] UNSPEC_CHKACLR) (const_int 0)) 561169689Skan (pc) 562169689Skan (label_ref (match_operand 1 "" ""))))] 563169689Skan "" 564169689Skan "chk.a.clr %0, %l1" 565169689Skan [(set_attr "itanium_class" "<chka_class>")]) 566169689Skan 567169689Skan(define_insn "speculation_check_<mode>" 568169689Skan [(set (pc) 569169689Skan (if_then_else (ne (unspec [(match_operand:MODE 0 "<reg_pred_prefix>_register_operand" "<chk_reg_constr>")] UNSPEC_CHKS) (const_int 0)) 570169689Skan (pc) 571169689Skan (label_ref (match_operand 1 "" ""))))] 572169689Skan "" 573169689Skan "chk.s %0, %l1" 574169689Skan [(set_attr "itanium_class" "<chks_class>")]) 575169689Skan 57690075Sobrien(define_split 577132718Skan [(set (match_operand 0 "register_operand" "") 578132718Skan (match_operand 1 "symbolic_operand" ""))] 579169689Skan "reload_completed" 58090075Sobrien [(const_int 0)] 58190075Sobrien{ 582169689Skan if (ia64_expand_load_address (operands[0], operands[1])) 583169689Skan DONE; 584169689Skan else 585169689Skan FAIL; 586117395Skan}) 58790075Sobrien 58890075Sobrien(define_expand "load_fptr" 589169689Skan [(set (match_operand:DI 0 "register_operand" "") 590169689Skan (plus:DI (match_dup 2) (match_operand 1 "function_operand" ""))) 591169689Skan (set (match_dup 0) (match_dup 3))] 592169689Skan "reload_completed" 59390075Sobrien{ 594169689Skan operands[2] = pic_offset_table_rtx; 595169689Skan operands[3] = gen_const_mem (DImode, operands[0]); 596117395Skan}) 59790075Sobrien 59890075Sobrien(define_insn "*load_fptr_internal1" 59990075Sobrien [(set (match_operand:DI 0 "register_operand" "=r") 600117395Skan (plus:DI (reg:DI 1) (match_operand 1 "function_operand" "s")))] 601169689Skan "reload_completed" 60290075Sobrien "addl %0 = @ltoff(@fptr(%1)), gp" 60390075Sobrien [(set_attr "itanium_class" "ialu")]) 60490075Sobrien 60590075Sobrien(define_insn "load_gprel" 60690075Sobrien [(set (match_operand:DI 0 "register_operand" "=r") 607117395Skan (plus:DI (reg:DI 1) (match_operand 1 "sdata_symbolic_operand" "s")))] 608169689Skan "reload_completed" 60990075Sobrien "addl %0 = @gprel(%1), gp" 61090075Sobrien [(set_attr "itanium_class" "ialu")]) 61190075Sobrien 612169689Skan(define_insn "*gprel64_offset" 61390075Sobrien [(set (match_operand:DI 0 "register_operand" "=r") 61490075Sobrien (minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))] 615169689Skan "reload_completed" 61690075Sobrien "movl %0 = @gprel(%1)" 61790075Sobrien [(set_attr "itanium_class" "long_i")]) 61890075Sobrien 61990075Sobrien(define_expand "load_gprel64" 620169689Skan [(set (match_operand:DI 0 "register_operand" "") 621169689Skan (minus:DI (match_operand:DI 1 "symbolic_operand" "") (match_dup 2))) 622169689Skan (set (match_dup 0) 623169689Skan (plus:DI (match_dup 2) (match_dup 0)))] 624169689Skan "reload_completed" 62590075Sobrien{ 626169689Skan operands[2] = pic_offset_table_rtx; 627117395Skan}) 62890075Sobrien 629132718Skan;; This is used as a placeholder for the return address during early 630132718Skan;; compilation. We won't know where we've placed this until during 631132718Skan;; reload, at which point it can wind up in b0, a general register, 632132718Skan;; or memory. The only safe destination under these conditions is a 633132718Skan;; general register. 634132718Skan 635132718Skan(define_insn_and_split "*movdi_ret_addr" 636132718Skan [(set (match_operand:DI 0 "register_operand" "=r") 637132718Skan (unspec:DI [(const_int 0)] UNSPEC_RET_ADDR))] 63890075Sobrien "" 639132718Skan "#" 640132718Skan "reload_completed" 641132718Skan [(const_int 0)] 64290075Sobrien{ 643132718Skan ia64_split_return_addr_rtx (operands[0]); 644132718Skan DONE; 645132718Skan} 646132718Skan [(set_attr "itanium_class" "ialu")]) 64790075Sobrien 648117395Skan(define_insn "*load_symptr_high" 64990075Sobrien [(set (match_operand:DI 0 "register_operand" "=r") 650117395Skan (plus:DI (high:DI (match_operand 1 "got_symbolic_operand" "s")) 651117395Skan (match_operand:DI 2 "register_operand" "a")))] 652169689Skan "reload_completed" 653117395Skan{ 654117395Skan if (HAVE_AS_LTOFFX_LDXMOV_RELOCS) 655117395Skan return "%,addl %0 = @ltoffx(%1), %2"; 656117395Skan else 657117395Skan return "%,addl %0 = @ltoff(%1), %2"; 658117395Skan} 65990075Sobrien [(set_attr "itanium_class" "ialu")]) 66090075Sobrien 661117395Skan(define_insn "*load_symptr_low" 662117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 663117395Skan (lo_sum:DI (match_operand:DI 1 "register_operand" "r") 664117395Skan (match_operand 2 "got_symbolic_operand" "s")))] 665169689Skan "reload_completed" 666117395Skan{ 667117395Skan if (HAVE_AS_LTOFFX_LDXMOV_RELOCS) 668117395Skan return "%,ld8.mov %0 = [%1], %2"; 669117395Skan else 670117395Skan return "%,ld8 %0 = [%1]"; 671117395Skan} 672117395Skan [(set_attr "itanium_class" "ld")]) 673117395Skan 674169689Skan(define_insn_and_split "load_dtpmod" 675117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 676169689Skan (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] 677169689Skan UNSPEC_DTPMOD))] 678117395Skan "" 679169689Skan "#" 680169689Skan "reload_completed" 681169689Skan [(set (match_dup 0) 682169689Skan (plus:DI (unspec:DI [(match_dup 1)] UNSPEC_LTOFF_DTPMOD) 683169689Skan (match_dup 2))) 684169689Skan (set (match_dup 0) (match_dup 3))] 685169689Skan{ 686169689Skan operands[2] = pic_offset_table_rtx; 687169689Skan operands[3] = gen_const_mem (DImode, operands[0]); 688169689Skan}) 689117395Skan 690169689Skan(define_insn "*load_ltoff_dtpmod" 691117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 692169689Skan (plus:DI (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] 693169689Skan UNSPEC_LTOFF_DTPMOD) 694169689Skan (match_operand:DI 2 "register_operand" "a")))] 695169689Skan "reload_completed" 696169689Skan "addl %0 = @ltoff(@dtpmod(%1)), %2" 697117395Skan [(set_attr "itanium_class" "ialu")]) 698117395Skan 699117395Skan(define_expand "load_dtprel" 700117395Skan [(set (match_operand:DI 0 "register_operand" "") 701169689Skan (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] 702117395Skan UNSPEC_DTPREL))] 703117395Skan "" 704117395Skan "") 705117395Skan 706117395Skan(define_insn "*load_dtprel64" 707117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 708169689Skan (unspec:DI [(match_operand 1 "ld_tls_symbolic_operand" "")] 709117395Skan UNSPEC_DTPREL))] 710117395Skan "TARGET_TLS64" 711117395Skan "movl %0 = @dtprel(%1)" 712117395Skan [(set_attr "itanium_class" "long_i")]) 713117395Skan 714117395Skan(define_insn "*load_dtprel22" 715117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 716169689Skan (unspec:DI [(match_operand 1 "ld_tls_symbolic_operand" "")] 717117395Skan UNSPEC_DTPREL))] 718117395Skan "" 719117395Skan "addl %0 = @dtprel(%1), r0" 720117395Skan [(set_attr "itanium_class" "ialu")]) 721117395Skan 722169689Skan(define_insn_and_split "*load_dtprel_gd" 723169689Skan [(set (match_operand:DI 0 "register_operand" "=r") 724169689Skan (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] 725169689Skan UNSPEC_DTPREL))] 726169689Skan "" 727169689Skan "#" 728169689Skan "reload_completed" 729169689Skan [(set (match_dup 0) 730169689Skan (plus:DI (unspec:DI [(match_dup 1)] UNSPEC_LTOFF_DTPREL) 731169689Skan (match_dup 2))) 732169689Skan (set (match_dup 0) (match_dup 3))] 733169689Skan{ 734169689Skan operands[2] = pic_offset_table_rtx; 735169689Skan operands[3] = gen_const_mem (DImode, operands[0]); 736169689Skan}) 737169689Skan 738169689Skan(define_insn "*load_ltoff_dtprel" 739169689Skan [(set (match_operand:DI 0 "register_operand" "=r") 740169689Skan (plus:DI (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] 741169689Skan UNSPEC_LTOFF_DTPREL) 742169689Skan (match_operand:DI 2 "register_operand" "a")))] 743169689Skan "" 744169689Skan "addl %0 = @ltoff(@dtprel(%1)), %2" 745169689Skan [(set_attr "itanium_class" "ialu")]) 746169689Skan 747117395Skan(define_expand "add_dtprel" 748117395Skan [(set (match_operand:DI 0 "register_operand" "") 749169689Skan (plus:DI (unspec:DI [(match_operand 1 "ld_tls_symbolic_operand" "")] 750169689Skan UNSPEC_DTPREL) 751169689Skan (match_operand:DI 2 "register_operand" "")))] 752117395Skan "!TARGET_TLS64" 753117395Skan "") 754117395Skan 755117395Skan(define_insn "*add_dtprel14" 756117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 757169689Skan (plus:DI (unspec:DI [(match_operand 1 "ld_tls_symbolic_operand" "")] 758169689Skan UNSPEC_DTPREL) 759169689Skan (match_operand:DI 2 "register_operand" "r")))] 760117395Skan "TARGET_TLS14" 761169689Skan "adds %0 = @dtprel(%1), %2" 762117395Skan [(set_attr "itanium_class" "ialu")]) 763117395Skan 764117395Skan(define_insn "*add_dtprel22" 765117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 766169689Skan (plus:DI (unspec:DI [(match_operand 1 "ld_tls_symbolic_operand" "")] 767169689Skan UNSPEC_DTPREL) 768169689Skan (match_operand:DI 2 "register_operand" "a")))] 769117395Skan "TARGET_TLS22" 770169689Skan "addl %0 = @dtprel(%1), %2" 771117395Skan [(set_attr "itanium_class" "ialu")]) 772117395Skan 773117395Skan(define_expand "load_tprel" 774117395Skan [(set (match_operand:DI 0 "register_operand" "") 775169689Skan (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")] 776117395Skan UNSPEC_TPREL))] 777117395Skan "" 778117395Skan "") 779117395Skan 780117395Skan(define_insn "*load_tprel64" 781117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 782169689Skan (unspec:DI [(match_operand 1 "le_tls_symbolic_operand" "")] 783117395Skan UNSPEC_TPREL))] 784117395Skan "TARGET_TLS64" 785117395Skan "movl %0 = @tprel(%1)" 786117395Skan [(set_attr "itanium_class" "long_i")]) 787117395Skan 788117395Skan(define_insn "*load_tprel22" 789117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 790169689Skan (unspec:DI [(match_operand 1 "le_tls_symbolic_operand" "")] 791117395Skan UNSPEC_TPREL))] 792117395Skan "" 793117395Skan "addl %0 = @tprel(%1), r0" 794117395Skan [(set_attr "itanium_class" "ialu")]) 795117395Skan 796169689Skan(define_insn_and_split "*load_tprel_ie" 797169689Skan [(set (match_operand:DI 0 "register_operand" "=r") 798169689Skan (unspec:DI [(match_operand 1 "ie_tls_symbolic_operand" "")] 799169689Skan UNSPEC_TPREL))] 800169689Skan "" 801169689Skan "#" 802169689Skan "reload_completed" 803169689Skan [(set (match_dup 0) 804169689Skan (plus:DI (unspec:DI [(match_dup 1)] UNSPEC_LTOFF_TPREL) 805169689Skan (match_dup 2))) 806169689Skan (set (match_dup 0) (match_dup 3))] 807169689Skan{ 808169689Skan operands[2] = pic_offset_table_rtx; 809169689Skan operands[3] = gen_const_mem (DImode, operands[0]); 810169689Skan}) 811169689Skan 812169689Skan(define_insn "*load_ltoff_tprel" 813169689Skan [(set (match_operand:DI 0 "register_operand" "=r") 814169689Skan (plus:DI (unspec:DI [(match_operand 1 "ie_tls_symbolic_operand" "")] 815169689Skan UNSPEC_LTOFF_TPREL) 816169689Skan (match_operand:DI 2 "register_operand" "a")))] 817169689Skan "" 818169689Skan "addl %0 = @ltoff(@tprel(%1)), %2" 819169689Skan [(set_attr "itanium_class" "ialu")]) 820169689Skan 821117395Skan(define_expand "add_tprel" 822117395Skan [(set (match_operand:DI 0 "register_operand" "") 823169689Skan (plus:DI (unspec:DI [(match_operand 1 "le_tls_symbolic_operand" "")] 824169689Skan UNSPEC_TPREL) 825169689Skan (match_operand:DI 2 "register_operand" "")))] 826117395Skan "!TARGET_TLS64" 827117395Skan "") 828117395Skan 829117395Skan(define_insn "*add_tprel14" 830117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 831169689Skan (plus:DI (unspec:DI [(match_operand 1 "le_tls_symbolic_operand" "")] 832169689Skan UNSPEC_TPREL) 833169689Skan (match_operand:DI 2 "register_operand" "r")))] 834117395Skan "TARGET_TLS14" 835169689Skan "adds %0 = @tprel(%1), %2" 836117395Skan [(set_attr "itanium_class" "ialu")]) 837117395Skan 838117395Skan(define_insn "*add_tprel22" 839117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 840169689Skan (plus:DI (unspec:DI [(match_operand 1 "le_tls_symbolic_operand" "")] 841169689Skan UNSPEC_TPREL) 842169689Skan (match_operand:DI 2 "register_operand" "a")))] 843117395Skan "TARGET_TLS22" 844169689Skan "addl %0 = @tprel(%1), %2" 845117395Skan [(set_attr "itanium_class" "ialu")]) 846117395Skan 84790075Sobrien;; With no offsettable memory references, we've got to have a scratch 848132718Skan;; around to play with the second word. However, in order to avoid a 849132718Skan;; reload nightmare we lie, claim we don't need one, and fix it up 850132718Skan;; in ia64_split_tmode_move. 85190075Sobrien(define_expand "movti" 852132718Skan [(set (match_operand:TI 0 "general_operand" "") 853132718Skan (match_operand:TI 1 "general_operand" ""))] 85490075Sobrien "" 85590075Sobrien{ 856117395Skan rtx op1 = ia64_expand_move (operands[0], operands[1]); 857117395Skan if (!op1) 858117395Skan DONE; 859117395Skan operands[1] = op1; 860117395Skan}) 86190075Sobrien 86290075Sobrien(define_insn_and_split "*movti_internal" 863169689Skan [(set (match_operand:TI 0 "destination_operand" "=r, *fm,*x,*f, Q") 864169689Skan (match_operand:TI 1 "general_operand" "r*fim,r, Q, *fOQ,*f"))] 86590075Sobrien "ia64_move_ok (operands[0], operands[1])" 866169689Skan "@ 867169689Skan # 868169689Skan # 869169689Skan ldfp8 %X0 = %1%P1 870169689Skan # 871169689Skan #" 872169689Skan "reload_completed && !ia64_load_pair_ok(operands[0], operands[1])" 87390075Sobrien [(const_int 0)] 87490075Sobrien{ 875132718Skan ia64_split_tmode_move (operands); 87690075Sobrien DONE; 877117395Skan} 878169689Skan [(set_attr "itanium_class" "unknown,unknown,fldp,unknown,unknown")]) 87990075Sobrien 88090075Sobrien;; Floating Point Moves 88190075Sobrien;; 88290075Sobrien;; Note - Patterns for SF mode moves are compulsory, but 883117395Skan;; patterns for DF are optional, as GCC can synthesize them. 88490075Sobrien 88590075Sobrien(define_expand "movsf" 88690075Sobrien [(set (match_operand:SF 0 "general_operand" "") 88790075Sobrien (match_operand:SF 1 "general_operand" ""))] 88890075Sobrien "" 88990075Sobrien{ 890117395Skan rtx op1 = ia64_expand_move (operands[0], operands[1]); 891117395Skan if (!op1) 892117395Skan DONE; 893117395Skan operands[1] = op1; 894117395Skan}) 89590075Sobrien 89690075Sobrien(define_insn "*movsf_internal" 89790075Sobrien [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m") 89890075Sobrien (match_operand:SF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))] 89990075Sobrien "ia64_move_ok (operands[0], operands[1])" 90090075Sobrien "@ 901117395Skan mov %0 = %F1 902117395Skan ldfs %0 = %1%P1 903117395Skan stfs %0 = %F1%P0 904117395Skan getf.s %0 = %F1 905117395Skan setf.s %0 = %1 906117395Skan mov %0 = %1 907117395Skan ld4%O1 %0 = %1%P1 908117395Skan st4%Q0 %0 = %1%P0" 90990075Sobrien [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")]) 91090075Sobrien 91190075Sobrien(define_expand "movdf" 91290075Sobrien [(set (match_operand:DF 0 "general_operand" "") 91390075Sobrien (match_operand:DF 1 "general_operand" ""))] 91490075Sobrien "" 91590075Sobrien{ 916117395Skan rtx op1 = ia64_expand_move (operands[0], operands[1]); 917117395Skan if (!op1) 918117395Skan DONE; 919117395Skan operands[1] = op1; 920117395Skan}) 92190075Sobrien 92290075Sobrien(define_insn "*movdf_internal" 92390075Sobrien [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m") 92490075Sobrien (match_operand:DF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))] 92590075Sobrien "ia64_move_ok (operands[0], operands[1])" 92690075Sobrien "@ 927117395Skan mov %0 = %F1 928117395Skan ldfd %0 = %1%P1 929117395Skan stfd %0 = %F1%P0 930117395Skan getf.d %0 = %F1 931117395Skan setf.d %0 = %1 932117395Skan mov %0 = %1 933117395Skan ld8%O1 %0 = %1%P1 934117395Skan st8%Q0 %0 = %1%P0" 93590075Sobrien [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")]) 93690075Sobrien 93790075Sobrien;; With no offsettable memory references, we've got to have a scratch 93890075Sobrien;; around to play with the second word if the variable winds up in GRs. 939132718Skan(define_expand "movxf" 940132718Skan [(set (match_operand:XF 0 "general_operand" "") 941132718Skan (match_operand:XF 1 "general_operand" ""))] 942132718Skan "" 94390075Sobrien{ 944169689Skan if (ia64_expand_movxf_movrf (XFmode, operands)) 945169689Skan DONE; 946117395Skan}) 94790075Sobrien 94890075Sobrien;; ??? There's no easy way to mind volatile acquire/release semantics. 94990075Sobrien 950132718Skan(define_insn "*movxf_internal" 951169689Skan [(set (match_operand:XF 0 "destination_operand" "=f,f, m") 952169689Skan (match_operand:XF 1 "general_operand" "fG,m,fG"))] 953132718Skan "ia64_move_ok (operands[0], operands[1])" 95490075Sobrien "@ 955117395Skan mov %0 = %F1 956117395Skan ldfe %0 = %1%P1 957117395Skan stfe %0 = %F1%P0" 95890075Sobrien [(set_attr "itanium_class" "fmisc,fld,stf")]) 959132718Skan 960169689Skan;; Same as for movxf, but for RFmode. 961169689Skan(define_expand "movrf" 962169689Skan [(set (match_operand:RF 0 "general_operand" "") 963169689Skan (match_operand:RF 1 "general_operand" ""))] 964169689Skan "" 965169689Skan{ 966169689Skan if (ia64_expand_movxf_movrf (RFmode, operands)) 967169689Skan DONE; 968169689Skan}) 969169689Skan 970169689Skan(define_insn "*movrf_internal" 971169689Skan [(set (match_operand:RF 0 "destination_operand" "=f,f, m") 972169689Skan (match_operand:RF 1 "general_operand" "fG,m,fG"))] 973169689Skan "ia64_move_ok (operands[0], operands[1])" 974169689Skan "@ 975169689Skan mov %0 = %F1 976169689Skan ldf.fill %0 = %1%P1 977169689Skan stf.spill %0 = %F1%P0" 978169689Skan [(set_attr "itanium_class" "fmisc,fld,stf")]) 979169689Skan 980132718Skan;; Better code generation via insns that deal with TFmode register pairs 981132718Skan;; directly. Same concerns apply as for TImode. 982132718Skan(define_expand "movtf" 983132718Skan [(set (match_operand:TF 0 "general_operand" "") 984132718Skan (match_operand:TF 1 "general_operand" ""))] 985132718Skan "" 986132718Skan{ 987132718Skan rtx op1 = ia64_expand_move (operands[0], operands[1]); 988132718Skan if (!op1) 989132718Skan DONE; 990132718Skan operands[1] = op1; 991132718Skan}) 992132718Skan 993132718Skan(define_insn_and_split "*movtf_internal" 994169689Skan [(set (match_operand:TF 0 "destination_operand" "=r,r,m") 995132718Skan (match_operand:TF 1 "general_operand" "ri,m,r"))] 996132718Skan "ia64_move_ok (operands[0], operands[1])" 997132718Skan "#" 998132718Skan "reload_completed" 999132718Skan [(const_int 0)] 1000132718Skan{ 1001132718Skan ia64_split_tmode_move (operands); 1002132718Skan DONE; 1003132718Skan} 1004132718Skan [(set_attr "itanium_class" "unknown") 1005132718Skan (set_attr "predicable" "no")]) 1006132718Skan 100790075Sobrien 100890075Sobrien;; :::::::::::::::::::: 100990075Sobrien;; :: 101090075Sobrien;; :: Conversions 101190075Sobrien;; :: 101290075Sobrien;; :::::::::::::::::::: 101390075Sobrien 101490075Sobrien;; Signed conversions from a smaller integer to a larger integer 101590075Sobrien 101690075Sobrien(define_insn "extendqidi2" 101790075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 101890075Sobrien (sign_extend:DI (match_operand:QI 1 "gr_register_operand" "r")))] 101990075Sobrien "" 102090075Sobrien "sxt1 %0 = %1" 102190075Sobrien [(set_attr "itanium_class" "xtd")]) 102290075Sobrien 102390075Sobrien(define_insn "extendhidi2" 102490075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 102590075Sobrien (sign_extend:DI (match_operand:HI 1 "gr_register_operand" "r")))] 102690075Sobrien "" 102790075Sobrien "sxt2 %0 = %1" 102890075Sobrien [(set_attr "itanium_class" "xtd")]) 102990075Sobrien 103090075Sobrien(define_insn "extendsidi2" 103190075Sobrien [(set (match_operand:DI 0 "grfr_register_operand" "=r,?f") 103290075Sobrien (sign_extend:DI (match_operand:SI 1 "grfr_register_operand" "r,f")))] 103390075Sobrien "" 103490075Sobrien "@ 103590075Sobrien sxt4 %0 = %1 103690075Sobrien fsxt.r %0 = %1, %1" 103790075Sobrien [(set_attr "itanium_class" "xtd,fmisc")]) 103890075Sobrien 103990075Sobrien;; Unsigned conversions from a smaller integer to a larger integer 104090075Sobrien 104190075Sobrien(define_insn "zero_extendqidi2" 104290075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r,r") 104390075Sobrien (zero_extend:DI (match_operand:QI 1 "gr_nonimmediate_operand" "r,m")))] 104490075Sobrien "" 104590075Sobrien "@ 104690075Sobrien zxt1 %0 = %1 104790075Sobrien ld1%O1 %0 = %1%P1" 104890075Sobrien [(set_attr "itanium_class" "xtd,ld")]) 104990075Sobrien 105090075Sobrien(define_insn "zero_extendhidi2" 105190075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r,r") 105290075Sobrien (zero_extend:DI (match_operand:HI 1 "gr_nonimmediate_operand" "r,m")))] 105390075Sobrien "" 105490075Sobrien "@ 105590075Sobrien zxt2 %0 = %1 105690075Sobrien ld2%O1 %0 = %1%P1" 105790075Sobrien [(set_attr "itanium_class" "xtd,ld")]) 105890075Sobrien 105990075Sobrien(define_insn "zero_extendsidi2" 106090075Sobrien [(set (match_operand:DI 0 "grfr_register_operand" "=r,r,?f") 106190075Sobrien (zero_extend:DI 106290075Sobrien (match_operand:SI 1 "grfr_nonimmediate_operand" "r,m,f")))] 106390075Sobrien "" 106490075Sobrien "@ 1065169689Skan addp4 %0 = %1, r0 106690075Sobrien ld4%O1 %0 = %1%P1 106790075Sobrien fmix.r %0 = f0, %1" 1068169689Skan [(set_attr "itanium_class" "ialu,ld,fmisc")]) 106990075Sobrien 107090075Sobrien;; Convert between floating point types of different sizes. 107190075Sobrien 107290075Sobrien;; At first glance, it would appear that emitting fnorm for an extending 107390075Sobrien;; conversion is unnecessary. However, the stf and getf instructions work 107490075Sobrien;; correctly only if the input is properly rounded for its type. In 107590075Sobrien;; particular, we get the wrong result for getf.d/stfd if the input is a 107690075Sobrien;; denorm single. Since we don't know what the next instruction will be, we 107790075Sobrien;; have to emit an fnorm. 107890075Sobrien 107990075Sobrien;; ??? Optimization opportunity here. Get rid of the insn altogether 108090075Sobrien;; when we can. Should probably use a scheme like has been proposed 108190075Sobrien;; for ia32 in dealing with operands that match unary operators. This 108290075Sobrien;; would let combine merge the thing into adjacent insns. See also how the 108390075Sobrien;; mips port handles SIGN_EXTEND as operands to integer arithmetic insns via 108490075Sobrien;; se_register_operand. 108590075Sobrien 108690075Sobrien(define_insn "extendsfdf2" 108790075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 108890075Sobrien (float_extend:DF (match_operand:SF 1 "fr_register_operand" "f")))] 108990075Sobrien "" 109090075Sobrien "fnorm.d %0 = %1" 109190075Sobrien [(set_attr "itanium_class" "fmac")]) 109290075Sobrien 1093132718Skan(define_insn "extendsfxf2" 1094132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 1095132718Skan (float_extend:XF (match_operand:SF 1 "fr_register_operand" "f")))] 1096132718Skan "" 109790075Sobrien "fnorm %0 = %1" 109890075Sobrien [(set_attr "itanium_class" "fmac")]) 109990075Sobrien 1100132718Skan(define_insn "extenddfxf2" 1101132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 1102132718Skan (float_extend:XF (match_operand:DF 1 "fr_register_operand" "f")))] 1103132718Skan "" 110490075Sobrien "fnorm %0 = %1" 110590075Sobrien [(set_attr "itanium_class" "fmac")]) 110690075Sobrien 110790075Sobrien(define_insn "truncdfsf2" 110890075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 110990075Sobrien (float_truncate:SF (match_operand:DF 1 "fr_register_operand" "f")))] 111090075Sobrien "" 111190075Sobrien "fnorm.s %0 = %1" 111290075Sobrien [(set_attr "itanium_class" "fmac")]) 111390075Sobrien 1114132718Skan(define_insn "truncxfsf2" 111590075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 1116132718Skan (float_truncate:SF (match_operand:XF 1 "fr_register_operand" "f")))] 1117132718Skan "" 111890075Sobrien "fnorm.s %0 = %1" 111990075Sobrien [(set_attr "itanium_class" "fmac")]) 112090075Sobrien 1121132718Skan(define_insn "truncxfdf2" 112290075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 1123132718Skan (float_truncate:DF (match_operand:XF 1 "fr_register_operand" "f")))] 1124132718Skan "" 112590075Sobrien "fnorm.d %0 = %1" 112690075Sobrien [(set_attr "itanium_class" "fmac")]) 112790075Sobrien 112890075Sobrien;; Convert between signed integer types and floating point. 112990075Sobrien 1130132718Skan(define_insn "floatdixf2" 1131132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 1132132718Skan (float:XF (match_operand:DI 1 "fr_register_operand" "f")))] 1133132718Skan "" 113490075Sobrien "fcvt.xf %0 = %1" 113590075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 113690075Sobrien 113790075Sobrien(define_insn "fix_truncsfdi2" 113890075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 113990075Sobrien (fix:DI (match_operand:SF 1 "fr_register_operand" "f")))] 114090075Sobrien "" 114190075Sobrien "fcvt.fx.trunc %0 = %1" 114290075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 114390075Sobrien 114490075Sobrien(define_insn "fix_truncdfdi2" 114590075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 114690075Sobrien (fix:DI (match_operand:DF 1 "fr_register_operand" "f")))] 114790075Sobrien "" 114890075Sobrien "fcvt.fx.trunc %0 = %1" 114990075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 115090075Sobrien 1151132718Skan(define_insn "fix_truncxfdi2" 115290075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 1153132718Skan (fix:DI (match_operand:XF 1 "fr_register_operand" "f")))] 1154132718Skan "" 115590075Sobrien "fcvt.fx.trunc %0 = %1" 115690075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 115790075Sobrien 1158132718Skan(define_insn "fix_truncxfdi2_alts" 115990075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 1160132718Skan (fix:DI (match_operand:XF 1 "fr_register_operand" "f"))) 116190075Sobrien (use (match_operand:SI 2 "const_int_operand" ""))] 1162132718Skan "" 116390075Sobrien "fcvt.fx.trunc.s%2 %0 = %1" 116490075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 116590075Sobrien 116690075Sobrien;; Convert between unsigned integer types and floating point. 116790075Sobrien 116890075Sobrien(define_insn "floatunsdisf2" 116990075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 117090075Sobrien (unsigned_float:SF (match_operand:DI 1 "fr_register_operand" "f")))] 117190075Sobrien "" 117290075Sobrien "fcvt.xuf.s %0 = %1" 117390075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 117490075Sobrien 117590075Sobrien(define_insn "floatunsdidf2" 117690075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 117790075Sobrien (unsigned_float:DF (match_operand:DI 1 "fr_register_operand" "f")))] 117890075Sobrien "" 117990075Sobrien "fcvt.xuf.d %0 = %1" 118090075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 118190075Sobrien 1182132718Skan(define_insn "floatunsdixf2" 1183132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 1184132718Skan (unsigned_float:XF (match_operand:DI 1 "fr_register_operand" "f")))] 1185132718Skan "" 118690075Sobrien "fcvt.xuf %0 = %1" 118790075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 118890075Sobrien 118990075Sobrien(define_insn "fixuns_truncsfdi2" 119090075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 119190075Sobrien (unsigned_fix:DI (match_operand:SF 1 "fr_register_operand" "f")))] 119290075Sobrien "" 119390075Sobrien "fcvt.fxu.trunc %0 = %1" 119490075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 119590075Sobrien 119690075Sobrien(define_insn "fixuns_truncdfdi2" 119790075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 119890075Sobrien (unsigned_fix:DI (match_operand:DF 1 "fr_register_operand" "f")))] 119990075Sobrien "" 120090075Sobrien "fcvt.fxu.trunc %0 = %1" 120190075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 120290075Sobrien 1203132718Skan(define_insn "fixuns_truncxfdi2" 120490075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 1205132718Skan (unsigned_fix:DI (match_operand:XF 1 "fr_register_operand" "f")))] 1206132718Skan "" 120790075Sobrien "fcvt.fxu.trunc %0 = %1" 120890075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 120990075Sobrien 1210132718Skan(define_insn "fixuns_truncxfdi2_alts" 121190075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 1212132718Skan (unsigned_fix:DI (match_operand:XF 1 "fr_register_operand" "f"))) 121390075Sobrien (use (match_operand:SI 2 "const_int_operand" ""))] 1214132718Skan "" 121590075Sobrien "fcvt.fxu.trunc.s%2 %0 = %1" 121690075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 121790075Sobrien 121890075Sobrien;; :::::::::::::::::::: 121990075Sobrien;; :: 122090075Sobrien;; :: Bit field extraction 122190075Sobrien;; :: 122290075Sobrien;; :::::::::::::::::::: 122390075Sobrien 122490075Sobrien(define_insn "extv" 122590075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 122690075Sobrien (sign_extract:DI (match_operand:DI 1 "gr_register_operand" "r") 1227169689Skan (match_operand:DI 2 "extr_len_operand" "n") 1228169689Skan (match_operand:DI 3 "shift_count_operand" "M")))] 122990075Sobrien "" 123090075Sobrien "extr %0 = %1, %3, %2" 123190075Sobrien [(set_attr "itanium_class" "ishf")]) 123290075Sobrien 123390075Sobrien(define_insn "extzv" 123490075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 123590075Sobrien (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r") 1236169689Skan (match_operand:DI 2 "extr_len_operand" "n") 1237169689Skan (match_operand:DI 3 "shift_count_operand" "M")))] 123890075Sobrien "" 123990075Sobrien "extr.u %0 = %1, %3, %2" 124090075Sobrien [(set_attr "itanium_class" "ishf")]) 124190075Sobrien 124290075Sobrien;; Insert a bit field. 124390075Sobrien;; Can have 3 operands, source1 (inserter), source2 (insertee), dest. 124490075Sobrien;; Source1 can be 0 or -1. 124590075Sobrien;; Source2 can be 0. 124690075Sobrien 124790075Sobrien;; ??? Actual dep instruction is more powerful than what these insv 124890075Sobrien;; patterns support. Unfortunately, combine is unable to create patterns 124990075Sobrien;; where source2 != dest. 125090075Sobrien 125190075Sobrien(define_expand "insv" 125290075Sobrien [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "") 125390075Sobrien (match_operand:DI 1 "const_int_operand" "") 125490075Sobrien (match_operand:DI 2 "const_int_operand" "")) 125590075Sobrien (match_operand:DI 3 "nonmemory_operand" ""))] 125690075Sobrien "" 125790075Sobrien{ 125890075Sobrien int width = INTVAL (operands[1]); 125990075Sobrien int shift = INTVAL (operands[2]); 126090075Sobrien 126190075Sobrien /* If operand[3] is a constant, and isn't 0 or -1, then load it into a 126290075Sobrien pseudo. */ 126390075Sobrien if (! register_operand (operands[3], DImode) 126490075Sobrien && operands[3] != const0_rtx && operands[3] != constm1_rtx) 126590075Sobrien operands[3] = force_reg (DImode, operands[3]); 126690075Sobrien 126790075Sobrien /* If this is a single dep instruction, we have nothing to do. */ 126890075Sobrien if (! ((register_operand (operands[3], DImode) && width <= 16) 126990075Sobrien || operands[3] == const0_rtx || operands[3] == constm1_rtx)) 127090075Sobrien { 127190075Sobrien /* Check for cases that can be implemented with a mix instruction. */ 127290075Sobrien if (width == 32 && shift == 0) 127390075Sobrien { 127490075Sobrien /* Directly generating the mix4left instruction confuses 127590075Sobrien optimize_bit_field in function.c. Since this is performing 127690075Sobrien a useful optimization, we defer generation of the complicated 127790075Sobrien mix4left RTL to the first splitting phase. */ 127890075Sobrien rtx tmp = gen_reg_rtx (DImode); 127990075Sobrien emit_insn (gen_shift_mix4left (operands[0], operands[3], tmp)); 128090075Sobrien DONE; 128190075Sobrien } 128290075Sobrien else if (width == 32 && shift == 32) 128390075Sobrien { 128490075Sobrien emit_insn (gen_mix4right (operands[0], operands[3])); 128590075Sobrien DONE; 128690075Sobrien } 128790075Sobrien 128890075Sobrien /* We could handle remaining cases by emitting multiple dep 128990075Sobrien instructions. 129090075Sobrien 129190075Sobrien If we need more than two dep instructions then we lose. A 6 129290075Sobrien insn sequence mov mask1,mov mask2,shl;;and,and;;or is better than 129390075Sobrien mov;;dep,shr;;dep,shr;;dep. The former can be executed in 3 cycles, 129490075Sobrien the latter is 6 cycles on an Itanium (TM) processor, because there is 129590075Sobrien only one function unit that can execute dep and shr immed. 129690075Sobrien 129790075Sobrien If we only need two dep instruction, then we still lose. 129890075Sobrien mov;;dep,shr;;dep is still 4 cycles. Even if we optimize away 129990075Sobrien the unnecessary mov, this is still undesirable because it will be 130090075Sobrien hard to optimize, and it creates unnecessary pressure on the I0 130190075Sobrien function unit. */ 130290075Sobrien 130390075Sobrien FAIL; 130490075Sobrien 130590075Sobrien#if 0 130690075Sobrien /* This code may be useful for other IA-64 processors, so we leave it in 130790075Sobrien for now. */ 130890075Sobrien while (width > 16) 130990075Sobrien { 131090075Sobrien rtx tmp; 131190075Sobrien 131290075Sobrien emit_insn (gen_insv (operands[0], GEN_INT (16), GEN_INT (shift), 131390075Sobrien operands[3])); 131490075Sobrien shift += 16; 131590075Sobrien width -= 16; 131690075Sobrien tmp = gen_reg_rtx (DImode); 131790075Sobrien emit_insn (gen_lshrdi3 (tmp, operands[3], GEN_INT (16))); 131890075Sobrien operands[3] = tmp; 131990075Sobrien } 132090075Sobrien operands[1] = GEN_INT (width); 132190075Sobrien operands[2] = GEN_INT (shift); 132290075Sobrien#endif 132390075Sobrien } 1324117395Skan}) 132590075Sobrien 132690075Sobrien(define_insn "*insv_internal" 132790075Sobrien [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r") 132890075Sobrien (match_operand:DI 1 "const_int_operand" "n") 132990075Sobrien (match_operand:DI 2 "const_int_operand" "n")) 133090075Sobrien (match_operand:DI 3 "nonmemory_operand" "rP"))] 133190075Sobrien "(gr_register_operand (operands[3], DImode) && INTVAL (operands[1]) <= 16) 133290075Sobrien || operands[3] == const0_rtx || operands[3] == constm1_rtx" 133390075Sobrien "dep %0 = %3, %0, %2, %1" 133490075Sobrien [(set_attr "itanium_class" "ishf")]) 133590075Sobrien 1336117395Skan;; Combine doesn't like to create bit-field insertions into zero. 1337169689Skan(define_insn "*shladdp4_internal" 1338169689Skan [(set (match_operand:DI 0 "gr_register_operand" "=r") 1339169689Skan (and:DI (ashift:DI (match_operand:DI 1 "gr_register_operand" "r") 1340169689Skan (match_operand:DI 2 "shladd_log2_operand" "n")) 1341169689Skan (match_operand:DI 3 "const_int_operand" "n")))] 1342169689Skan "ia64_depz_field_mask (operands[3], operands[2]) + INTVAL (operands[2]) == 32" 1343169689Skan "shladdp4 %0 = %1, %2, r0" 1344169689Skan [(set_attr "itanium_class" "ialu")]) 1345169689Skan 134690075Sobrien(define_insn "*depz_internal" 134790075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 134890075Sobrien (and:DI (ashift:DI (match_operand:DI 1 "gr_register_operand" "r") 134990075Sobrien (match_operand:DI 2 "const_int_operand" "n")) 135090075Sobrien (match_operand:DI 3 "const_int_operand" "n")))] 135190075Sobrien "CONST_OK_FOR_M (INTVAL (operands[2])) 135290075Sobrien && ia64_depz_field_mask (operands[3], operands[2]) > 0" 135390075Sobrien{ 135490075Sobrien operands[3] = GEN_INT (ia64_depz_field_mask (operands[3], operands[2])); 1355117395Skan return "%,dep.z %0 = %1, %2, %3"; 1356117395Skan} 135790075Sobrien [(set_attr "itanium_class" "ishf")]) 135890075Sobrien 135990075Sobrien(define_insn "shift_mix4left" 136090075Sobrien [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r") 136190075Sobrien (const_int 32) (const_int 0)) 136290075Sobrien (match_operand:DI 1 "gr_register_operand" "r")) 136390075Sobrien (clobber (match_operand:DI 2 "gr_register_operand" "=r"))] 136490075Sobrien "" 136590075Sobrien "#" 136690075Sobrien [(set_attr "itanium_class" "unknown")]) 136790075Sobrien 136890075Sobrien(define_split 136990075Sobrien [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "") 137090075Sobrien (const_int 32) (const_int 0)) 137190075Sobrien (match_operand:DI 1 "register_operand" "")) 137290075Sobrien (clobber (match_operand:DI 2 "register_operand" ""))] 1373169689Skan "" 137490075Sobrien [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32))) 137590075Sobrien (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0)) 137690075Sobrien (lshiftrt:DI (match_dup 3) (const_int 32)))] 137790075Sobrien "operands[3] = operands[2];") 137890075Sobrien 137990075Sobrien(define_insn "*mix4left" 138090075Sobrien [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r") 138190075Sobrien (const_int 32) (const_int 0)) 138290075Sobrien (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r") 138390075Sobrien (const_int 32)))] 138490075Sobrien "" 138590075Sobrien "mix4.l %0 = %0, %r1" 138690075Sobrien [(set_attr "itanium_class" "mmshf")]) 138790075Sobrien 138890075Sobrien(define_insn "mix4right" 138990075Sobrien [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r") 139090075Sobrien (const_int 32) (const_int 32)) 139190075Sobrien (match_operand:DI 1 "gr_reg_or_0_operand" "rO"))] 139290075Sobrien "" 139390075Sobrien "mix4.r %0 = %r1, %0" 139490075Sobrien [(set_attr "itanium_class" "mmshf")]) 139590075Sobrien 139690075Sobrien;; This is used by the rotrsi3 pattern. 139790075Sobrien 139890075Sobrien(define_insn "*mix4right_3op" 139990075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 140090075Sobrien (ior:DI (zero_extend:DI (match_operand:SI 1 "gr_register_operand" "r")) 140190075Sobrien (ashift:DI (zero_extend:DI 140290075Sobrien (match_operand:SI 2 "gr_register_operand" "r")) 140390075Sobrien (const_int 32))))] 140490075Sobrien "" 140590075Sobrien "mix4.r %0 = %2, %1" 140690075Sobrien [(set_attr "itanium_class" "mmshf")]) 140790075Sobrien 140890075Sobrien 140990075Sobrien;; :::::::::::::::::::: 141090075Sobrien;; :: 141190075Sobrien;; :: 1 bit Integer arithmetic 141290075Sobrien;; :: 141390075Sobrien;; :::::::::::::::::::: 141490075Sobrien 141590075Sobrien(define_insn_and_split "andbi3" 141690075Sobrien [(set (match_operand:BI 0 "register_operand" "=c,c,r") 141790075Sobrien (and:BI (match_operand:BI 1 "register_operand" "%0,0,r") 141890075Sobrien (match_operand:BI 2 "register_operand" "c,r,r")))] 141990075Sobrien "" 142090075Sobrien "@ 142190075Sobrien # 142290075Sobrien tbit.nz.and.orcm %0, %I0 = %2, 0 142390075Sobrien and %0 = %2, %1" 142490075Sobrien "reload_completed 142590075Sobrien && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0])) 142690075Sobrien && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))" 142790075Sobrien [(cond_exec (eq (match_dup 2) (const_int 0)) 142890075Sobrien (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0)) 142990075Sobrien (match_dup 0))))] 143090075Sobrien "" 143190075Sobrien [(set_attr "itanium_class" "unknown,tbit,ilog")]) 143290075Sobrien 143390075Sobrien(define_insn_and_split "*andcmbi3" 143490075Sobrien [(set (match_operand:BI 0 "register_operand" "=c,c,r") 143590075Sobrien (and:BI (not:BI (match_operand:BI 1 "register_operand" "c,r,r")) 143690075Sobrien (match_operand:BI 2 "register_operand" "0,0,r")))] 143790075Sobrien "" 143890075Sobrien "@ 143990075Sobrien # 144090075Sobrien tbit.z.and.orcm %0, %I0 = %1, 0 144190075Sobrien andcm %0 = %2, %1" 144290075Sobrien "reload_completed 144390075Sobrien && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0])) 144490075Sobrien && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))" 144590075Sobrien [(cond_exec (ne (match_dup 1) (const_int 0)) 144690075Sobrien (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0)) 144790075Sobrien (match_dup 0))))] 144890075Sobrien "" 144990075Sobrien [(set_attr "itanium_class" "unknown,tbit,ilog")]) 145090075Sobrien 145190075Sobrien(define_insn_and_split "iorbi3" 145290075Sobrien [(set (match_operand:BI 0 "register_operand" "=c,c,r") 145390075Sobrien (ior:BI (match_operand:BI 1 "register_operand" "%0,0,r") 145490075Sobrien (match_operand:BI 2 "register_operand" "c,r,r")))] 145590075Sobrien "" 145690075Sobrien "@ 145790075Sobrien # 145890075Sobrien tbit.nz.or.andcm %0, %I0 = %2, 0 145990075Sobrien or %0 = %2, %1" 146090075Sobrien "reload_completed 146190075Sobrien && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0])) 146290075Sobrien && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))" 146390075Sobrien [(cond_exec (ne (match_dup 2) (const_int 0)) 146490075Sobrien (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0)) 146590075Sobrien (match_dup 0))))] 146690075Sobrien "" 146790075Sobrien [(set_attr "itanium_class" "unknown,tbit,ilog")]) 146890075Sobrien 146990075Sobrien(define_insn_and_split "*iorcmbi3" 147090075Sobrien [(set (match_operand:BI 0 "register_operand" "=c,c") 147190075Sobrien (ior:BI (not:BI (match_operand:BI 1 "register_operand" "c,r")) 147290075Sobrien (match_operand:BI 2 "register_operand" "0,0")))] 147390075Sobrien "" 147490075Sobrien "@ 147590075Sobrien # 147690075Sobrien tbit.z.or.andcm %0, %I0 = %1, 0" 147790075Sobrien "reload_completed 147890075Sobrien && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0])) 147990075Sobrien && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))" 148090075Sobrien [(cond_exec (eq (match_dup 1) (const_int 0)) 148190075Sobrien (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0)) 148290075Sobrien (match_dup 0))))] 148390075Sobrien "" 148490075Sobrien [(set_attr "itanium_class" "unknown,tbit")]) 148590075Sobrien 148690075Sobrien(define_insn "one_cmplbi2" 148790075Sobrien [(set (match_operand:BI 0 "register_operand" "=c,r,c,&c") 148890075Sobrien (not:BI (match_operand:BI 1 "register_operand" "r,r,0,c"))) 148990075Sobrien (clobber (match_scratch:BI 2 "=X,X,c,X"))] 149090075Sobrien "" 149190075Sobrien "@ 149290075Sobrien tbit.z %0, %I0 = %1, 0 149390075Sobrien xor %0 = 1, %1 149490075Sobrien # 149590075Sobrien #" 149690075Sobrien [(set_attr "itanium_class" "tbit,ilog,unknown,unknown")]) 149790075Sobrien 149890075Sobrien(define_split 149990075Sobrien [(set (match_operand:BI 0 "register_operand" "") 150090075Sobrien (not:BI (match_operand:BI 1 "register_operand" ""))) 150190075Sobrien (clobber (match_scratch:BI 2 ""))] 150290075Sobrien "reload_completed 150390075Sobrien && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0])) 150490075Sobrien && rtx_equal_p (operands[0], operands[1])" 150590075Sobrien [(set (match_dup 4) (match_dup 3)) 150690075Sobrien (set (match_dup 0) (const_int 1)) 150790075Sobrien (cond_exec (ne (match_dup 2) (const_int 0)) 150890075Sobrien (set (match_dup 0) (const_int 0))) 1509117395Skan (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))] 151090075Sobrien "operands[3] = gen_rtx_REG (CCImode, REGNO (operands[1])); 151190075Sobrien operands[4] = gen_rtx_REG (CCImode, REGNO (operands[2]));") 151290075Sobrien 151390075Sobrien(define_split 151490075Sobrien [(set (match_operand:BI 0 "register_operand" "") 151590075Sobrien (not:BI (match_operand:BI 1 "register_operand" ""))) 151690075Sobrien (clobber (match_scratch:BI 2 ""))] 151790075Sobrien "reload_completed 151890075Sobrien && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0])) 151990075Sobrien && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1])) 152090075Sobrien && ! rtx_equal_p (operands[0], operands[1])" 152190075Sobrien [(cond_exec (ne (match_dup 1) (const_int 0)) 152290075Sobrien (set (match_dup 0) (const_int 0))) 152390075Sobrien (cond_exec (eq (match_dup 1) (const_int 0)) 152490075Sobrien (set (match_dup 0) (const_int 1))) 1525117395Skan (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))] 152690075Sobrien "") 152790075Sobrien 152890075Sobrien(define_insn "*cmpsi_and_0" 152990075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 153090075Sobrien (and:BI (match_operator:BI 4 "predicate_operator" 153190075Sobrien [(match_operand:SI 2 "gr_reg_or_0_operand" "rO") 153290075Sobrien (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]) 153390075Sobrien (match_operand:BI 1 "register_operand" "0")))] 153490075Sobrien "" 153590075Sobrien "cmp4.%C4.and.orcm %0, %I0 = %3, %r2" 153690075Sobrien [(set_attr "itanium_class" "icmp")]) 153790075Sobrien 153890075Sobrien(define_insn "*cmpsi_and_1" 153990075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 154090075Sobrien (and:BI (match_operator:BI 3 "signed_inequality_operator" 154190075Sobrien [(match_operand:SI 2 "gr_register_operand" "r") 154290075Sobrien (const_int 0)]) 154390075Sobrien (match_operand:BI 1 "register_operand" "0")))] 154490075Sobrien "" 154590075Sobrien "cmp4.%C3.and.orcm %0, %I0 = r0, %2" 154690075Sobrien [(set_attr "itanium_class" "icmp")]) 154790075Sobrien 154890075Sobrien(define_insn "*cmpsi_andnot_0" 154990075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 155090075Sobrien (and:BI (not:BI (match_operator:BI 4 "predicate_operator" 155190075Sobrien [(match_operand:SI 2 "gr_reg_or_0_operand" "rO") 155290075Sobrien (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])) 155390075Sobrien (match_operand:BI 1 "register_operand" "0")))] 155490075Sobrien "" 155590075Sobrien "cmp4.%C4.or.andcm %I0, %0 = %3, %r2" 155690075Sobrien [(set_attr "itanium_class" "icmp")]) 155790075Sobrien 155890075Sobrien(define_insn "*cmpsi_andnot_1" 155990075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 156090075Sobrien (and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator" 156190075Sobrien [(match_operand:SI 2 "gr_register_operand" "r") 156290075Sobrien (const_int 0)])) 156390075Sobrien (match_operand:BI 1 "register_operand" "0")))] 156490075Sobrien "" 156590075Sobrien "cmp4.%C3.or.andcm %I0, %0 = r0, %2" 156690075Sobrien [(set_attr "itanium_class" "icmp")]) 156790075Sobrien 156890075Sobrien(define_insn "*cmpdi_and_0" 156990075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 157090075Sobrien (and:BI (match_operator:BI 4 "predicate_operator" 157190075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 157290075Sobrien (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]) 157390075Sobrien (match_operand:BI 1 "register_operand" "0")))] 157490075Sobrien "" 157590075Sobrien "cmp.%C4.and.orcm %0, %I0 = %3, %2" 157690075Sobrien [(set_attr "itanium_class" "icmp")]) 157790075Sobrien 157890075Sobrien(define_insn "*cmpdi_and_1" 157990075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 158090075Sobrien (and:BI (match_operator:BI 3 "signed_inequality_operator" 158190075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 158290075Sobrien (const_int 0)]) 158390075Sobrien (match_operand:BI 1 "register_operand" "0")))] 158490075Sobrien "" 158590075Sobrien "cmp.%C3.and.orcm %0, %I0 = r0, %2" 158690075Sobrien [(set_attr "itanium_class" "icmp")]) 158790075Sobrien 158890075Sobrien(define_insn "*cmpdi_andnot_0" 158990075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 159090075Sobrien (and:BI (not:BI (match_operator:BI 4 "predicate_operator" 159190075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 159290075Sobrien (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])) 159390075Sobrien (match_operand:BI 1 "register_operand" "0")))] 159490075Sobrien "" 159590075Sobrien "cmp.%C4.or.andcm %I0, %0 = %3, %2" 159690075Sobrien [(set_attr "itanium_class" "icmp")]) 159790075Sobrien 159890075Sobrien(define_insn "*cmpdi_andnot_1" 159990075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 160090075Sobrien (and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator" 160190075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 160290075Sobrien (const_int 0)])) 160390075Sobrien (match_operand:BI 1 "register_operand" "0")))] 160490075Sobrien "" 160590075Sobrien "cmp.%C3.or.andcm %I0, %0 = r0, %2" 160690075Sobrien [(set_attr "itanium_class" "icmp")]) 160790075Sobrien 160890075Sobrien(define_insn "*tbit_and_0" 160990075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 161090075Sobrien (and:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r") 161190075Sobrien (const_int 1)) 161290075Sobrien (const_int 0)) 161390075Sobrien (match_operand:BI 2 "register_operand" "0")))] 161490075Sobrien "" 161590075Sobrien "tbit.nz.and.orcm %0, %I0 = %1, 0" 161690075Sobrien [(set_attr "itanium_class" "tbit")]) 161790075Sobrien 161890075Sobrien(define_insn "*tbit_and_1" 161990075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 162090075Sobrien (and:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r") 162190075Sobrien (const_int 1)) 162290075Sobrien (const_int 0)) 162390075Sobrien (match_operand:BI 2 "register_operand" "0")))] 162490075Sobrien "" 162590075Sobrien "tbit.z.and.orcm %0, %I0 = %1, 0" 162690075Sobrien [(set_attr "itanium_class" "tbit")]) 162790075Sobrien 162890075Sobrien(define_insn "*tbit_and_2" 162990075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 163090075Sobrien (and:BI (ne:BI (zero_extract:DI 163190075Sobrien (match_operand:DI 1 "gr_register_operand" "r") 163290075Sobrien (const_int 1) 1633169689Skan (match_operand:DI 2 "shift_count_operand" "M")) 163490075Sobrien (const_int 0)) 163590075Sobrien (match_operand:BI 3 "register_operand" "0")))] 163690075Sobrien "" 163790075Sobrien "tbit.nz.and.orcm %0, %I0 = %1, %2" 163890075Sobrien [(set_attr "itanium_class" "tbit")]) 163990075Sobrien 164090075Sobrien(define_insn "*tbit_and_3" 164190075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 164290075Sobrien (and:BI (eq:BI (zero_extract:DI 164390075Sobrien (match_operand:DI 1 "gr_register_operand" "r") 164490075Sobrien (const_int 1) 1645169689Skan (match_operand:DI 2 "shift_count_operand" "M")) 164690075Sobrien (const_int 0)) 164790075Sobrien (match_operand:BI 3 "register_operand" "0")))] 164890075Sobrien "" 164990075Sobrien "tbit.z.and.orcm %0, %I0 = %1, %2" 165090075Sobrien [(set_attr "itanium_class" "tbit")]) 165190075Sobrien 165290075Sobrien(define_insn "*cmpsi_or_0" 165390075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 165490075Sobrien (ior:BI (match_operator:BI 4 "predicate_operator" 165590075Sobrien [(match_operand:SI 2 "gr_reg_or_0_operand" "rO") 165690075Sobrien (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]) 165790075Sobrien (match_operand:BI 1 "register_operand" "0")))] 165890075Sobrien "" 165990075Sobrien "cmp4.%C4.or.andcm %0, %I0 = %3, %r2" 166090075Sobrien [(set_attr "itanium_class" "icmp")]) 166190075Sobrien 166290075Sobrien(define_insn "*cmpsi_or_1" 166390075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 166490075Sobrien (ior:BI (match_operator:BI 3 "signed_inequality_operator" 166590075Sobrien [(match_operand:SI 2 "gr_register_operand" "r") 166690075Sobrien (const_int 0)]) 166790075Sobrien (match_operand:BI 1 "register_operand" "0")))] 166890075Sobrien "" 166990075Sobrien "cmp4.%C3.or.andcm %0, %I0 = r0, %2" 167090075Sobrien [(set_attr "itanium_class" "icmp")]) 167190075Sobrien 167290075Sobrien(define_insn "*cmpsi_orcm_0" 167390075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 167490075Sobrien (ior:BI (not:BI (match_operator:BI 4 "predicate_operator" 167590075Sobrien [(match_operand:SI 2 "gr_reg_or_0_operand" "rO") 167690075Sobrien (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])) 167790075Sobrien (match_operand:BI 1 "register_operand" "0")))] 167890075Sobrien "" 167990075Sobrien "cmp4.%C4.and.orcm %I0, %0 = %3, %r2" 168090075Sobrien [(set_attr "itanium_class" "icmp")]) 168190075Sobrien 168290075Sobrien(define_insn "*cmpsi_orcm_1" 168390075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 168490075Sobrien (ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator" 168590075Sobrien [(match_operand:SI 2 "gr_register_operand" "r") 168690075Sobrien (const_int 0)])) 168790075Sobrien (match_operand:BI 1 "register_operand" "0")))] 168890075Sobrien "" 168990075Sobrien "cmp4.%C3.and.orcm %I0, %0 = r0, %2" 169090075Sobrien [(set_attr "itanium_class" "icmp")]) 169190075Sobrien 169290075Sobrien(define_insn "*cmpdi_or_0" 169390075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 169490075Sobrien (ior:BI (match_operator:BI 4 "predicate_operator" 169590075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 169690075Sobrien (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]) 169790075Sobrien (match_operand:BI 1 "register_operand" "0")))] 169890075Sobrien "" 169990075Sobrien "cmp.%C4.or.andcm %0, %I0 = %3, %2" 170090075Sobrien [(set_attr "itanium_class" "icmp")]) 170190075Sobrien 170290075Sobrien(define_insn "*cmpdi_or_1" 170390075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 170490075Sobrien (ior:BI (match_operator:BI 3 "signed_inequality_operator" 170590075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 170690075Sobrien (const_int 0)]) 170790075Sobrien (match_operand:BI 1 "register_operand" "0")))] 170890075Sobrien "" 170990075Sobrien "cmp.%C3.or.andcm %0, %I0 = r0, %2" 171090075Sobrien [(set_attr "itanium_class" "icmp")]) 171190075Sobrien 171290075Sobrien(define_insn "*cmpdi_orcm_0" 171390075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 171490075Sobrien (ior:BI (not:BI (match_operator:BI 4 "predicate_operator" 171590075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 171690075Sobrien (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])) 171790075Sobrien (match_operand:BI 1 "register_operand" "0")))] 171890075Sobrien "" 171990075Sobrien "cmp.%C4.and.orcm %I0, %0 = %3, %2" 172090075Sobrien [(set_attr "itanium_class" "icmp")]) 172190075Sobrien 172290075Sobrien(define_insn "*cmpdi_orcm_1" 172390075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 172490075Sobrien (ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator" 172590075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 172690075Sobrien (const_int 0)])) 172790075Sobrien (match_operand:BI 1 "register_operand" "0")))] 172890075Sobrien "" 172990075Sobrien "cmp.%C3.and.orcm %I0, %0 = r0, %2" 173090075Sobrien [(set_attr "itanium_class" "icmp")]) 173190075Sobrien 173290075Sobrien(define_insn "*tbit_or_0" 173390075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 173490075Sobrien (ior:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r") 173590075Sobrien (const_int 1)) 173690075Sobrien (const_int 0)) 173790075Sobrien (match_operand:BI 2 "register_operand" "0")))] 173890075Sobrien "" 173990075Sobrien "tbit.nz.or.andcm %0, %I0 = %1, 0" 174090075Sobrien [(set_attr "itanium_class" "tbit")]) 174190075Sobrien 174290075Sobrien(define_insn "*tbit_or_1" 174390075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 174490075Sobrien (ior:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r") 174590075Sobrien (const_int 1)) 174690075Sobrien (const_int 0)) 174790075Sobrien (match_operand:BI 2 "register_operand" "0")))] 174890075Sobrien "" 174990075Sobrien "tbit.z.or.andcm %0, %I0 = %1, 0" 175090075Sobrien [(set_attr "itanium_class" "tbit")]) 175190075Sobrien 175290075Sobrien(define_insn "*tbit_or_2" 175390075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 175490075Sobrien (ior:BI (ne:BI (zero_extract:DI 175590075Sobrien (match_operand:DI 1 "gr_register_operand" "r") 175690075Sobrien (const_int 1) 1757169689Skan (match_operand:DI 2 "shift_count_operand" "M")) 175890075Sobrien (const_int 0)) 175990075Sobrien (match_operand:BI 3 "register_operand" "0")))] 176090075Sobrien "" 176190075Sobrien "tbit.nz.or.andcm %0, %I0 = %1, %2" 176290075Sobrien [(set_attr "itanium_class" "tbit")]) 176390075Sobrien 176490075Sobrien(define_insn "*tbit_or_3" 176590075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 176690075Sobrien (ior:BI (eq:BI (zero_extract:DI 176790075Sobrien (match_operand:DI 1 "gr_register_operand" "r") 176890075Sobrien (const_int 1) 1769169689Skan (match_operand:DI 2 "shift_count_operand" "M")) 177090075Sobrien (const_int 0)) 177190075Sobrien (match_operand:BI 3 "register_operand" "0")))] 177290075Sobrien "" 177390075Sobrien "tbit.z.or.andcm %0, %I0 = %1, %2" 177490075Sobrien [(set_attr "itanium_class" "tbit")]) 177590075Sobrien 177690075Sobrien;; Transform test of and/or of setcc into parallel comparisons. 177790075Sobrien 177890075Sobrien(define_split 177990075Sobrien [(set (match_operand:BI 0 "register_operand" "") 178090075Sobrien (ne:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "") 178190075Sobrien (const_int 0)) 178290075Sobrien (match_operand:DI 3 "register_operand" "")) 178390075Sobrien (const_int 0)))] 178490075Sobrien "" 178590075Sobrien [(set (match_dup 0) 178690075Sobrien (and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0)) 178790075Sobrien (match_dup 2)))] 178890075Sobrien "") 178990075Sobrien 179090075Sobrien(define_split 179190075Sobrien [(set (match_operand:BI 0 "register_operand" "") 179290075Sobrien (eq:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "") 179390075Sobrien (const_int 0)) 179490075Sobrien (match_operand:DI 3 "register_operand" "")) 179590075Sobrien (const_int 0)))] 179690075Sobrien "" 179790075Sobrien [(set (match_dup 0) 179890075Sobrien (and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0)) 179990075Sobrien (match_dup 2))) 180090075Sobrien (parallel [(set (match_dup 0) (not:BI (match_dup 0))) 180190075Sobrien (clobber (scratch))])] 180290075Sobrien "") 180390075Sobrien 180490075Sobrien(define_split 180590075Sobrien [(set (match_operand:BI 0 "register_operand" "") 180690075Sobrien (ne:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "") 180790075Sobrien (const_int 0)) 180890075Sobrien (match_operand:DI 3 "register_operand" "")) 180990075Sobrien (const_int 0)))] 181090075Sobrien "" 181190075Sobrien [(set (match_dup 0) 181290075Sobrien (ior:BI (ne:BI (match_dup 3) (const_int 0)) 181390075Sobrien (match_dup 2)))] 181490075Sobrien "") 181590075Sobrien 181690075Sobrien(define_split 181790075Sobrien [(set (match_operand:BI 0 "register_operand" "") 181890075Sobrien (eq:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "") 181990075Sobrien (const_int 0)) 182090075Sobrien (match_operand:DI 3 "register_operand" "")) 182190075Sobrien (const_int 0)))] 182290075Sobrien "" 182390075Sobrien [(set (match_dup 0) 182490075Sobrien (ior:BI (ne:BI (match_dup 3) (const_int 0)) 182590075Sobrien (match_dup 2))) 182690075Sobrien (parallel [(set (match_dup 0) (not:BI (match_dup 0))) 182790075Sobrien (clobber (scratch))])] 182890075Sobrien "") 182990075Sobrien 183090075Sobrien;; ??? Incredibly hackish. Either need four proper patterns with all 183190075Sobrien;; the alternatives, or rely on sched1 to split the insn and hope that 183290075Sobrien;; nothing bad happens to the comparisons in the meantime. 183390075Sobrien;; 183490075Sobrien;; Alternately, adjust combine to allow 2->2 and 3->3 splits, assuming 183590075Sobrien;; that we're doing height reduction. 183690075Sobrien; 183790075Sobrien;(define_insn_and_split "" 183890075Sobrien; [(set (match_operand:BI 0 "register_operand" "=c") 183990075Sobrien; (and:BI (and:BI (match_operator:BI 1 "comparison_operator" 184090075Sobrien; [(match_operand 2 "" "") 184190075Sobrien; (match_operand 3 "" "")]) 184290075Sobrien; (match_operator:BI 4 "comparison_operator" 184390075Sobrien; [(match_operand 5 "" "") 184490075Sobrien; (match_operand 6 "" "")])) 184590075Sobrien; (match_dup 0)))] 184690075Sobrien; "flag_schedule_insns" 184790075Sobrien; "#" 184890075Sobrien; "" 184990075Sobrien; [(set (match_dup 0) (and:BI (match_dup 1) (match_dup 0))) 185090075Sobrien; (set (match_dup 0) (and:BI (match_dup 4) (match_dup 0)))] 185190075Sobrien; "") 185290075Sobrien; 185390075Sobrien;(define_insn_and_split "" 185490075Sobrien; [(set (match_operand:BI 0 "register_operand" "=c") 185590075Sobrien; (ior:BI (ior:BI (match_operator:BI 1 "comparison_operator" 185690075Sobrien; [(match_operand 2 "" "") 185790075Sobrien; (match_operand 3 "" "")]) 185890075Sobrien; (match_operator:BI 4 "comparison_operator" 185990075Sobrien; [(match_operand 5 "" "") 186090075Sobrien; (match_operand 6 "" "")])) 186190075Sobrien; (match_dup 0)))] 186290075Sobrien; "flag_schedule_insns" 186390075Sobrien; "#" 186490075Sobrien; "" 186590075Sobrien; [(set (match_dup 0) (ior:BI (match_dup 1) (match_dup 0))) 186690075Sobrien; (set (match_dup 0) (ior:BI (match_dup 4) (match_dup 0)))] 186790075Sobrien; "") 186890075Sobrien; 186990075Sobrien;(define_split 187090075Sobrien; [(set (match_operand:BI 0 "register_operand" "") 187190075Sobrien; (and:BI (and:BI (match_operator:BI 1 "comparison_operator" 187290075Sobrien; [(match_operand 2 "" "") 187390075Sobrien; (match_operand 3 "" "")]) 187490075Sobrien; (match_operand:BI 7 "register_operand" "")) 187590075Sobrien; (and:BI (match_operator:BI 4 "comparison_operator" 187690075Sobrien; [(match_operand 5 "" "") 187790075Sobrien; (match_operand 6 "" "")]) 187890075Sobrien; (match_operand:BI 8 "register_operand" ""))))] 187990075Sobrien; "" 188090075Sobrien; [(set (match_dup 0) (and:BI (match_dup 7) (match_dup 8))) 188190075Sobrien; (set (match_dup 0) (and:BI (and:BI (match_dup 1) (match_dup 4)) 188290075Sobrien; (match_dup 0)))] 188390075Sobrien; "") 188490075Sobrien; 188590075Sobrien;(define_split 188690075Sobrien; [(set (match_operand:BI 0 "register_operand" "") 188790075Sobrien; (ior:BI (ior:BI (match_operator:BI 1 "comparison_operator" 188890075Sobrien; [(match_operand 2 "" "") 188990075Sobrien; (match_operand 3 "" "")]) 189090075Sobrien; (match_operand:BI 7 "register_operand" "")) 189190075Sobrien; (ior:BI (match_operator:BI 4 "comparison_operator" 189290075Sobrien; [(match_operand 5 "" "") 189390075Sobrien; (match_operand 6 "" "")]) 189490075Sobrien; (match_operand:BI 8 "register_operand" ""))))] 189590075Sobrien; "" 189690075Sobrien; [(set (match_dup 0) (ior:BI (match_dup 7) (match_dup 8))) 189790075Sobrien; (set (match_dup 0) (ior:BI (ior:BI (match_dup 1) (match_dup 4)) 189890075Sobrien; (match_dup 0)))] 189990075Sobrien; "") 190090075Sobrien 190190075Sobrien;; Try harder to avoid predicate copies by duplicating compares. 190290075Sobrien;; Note that we'll have already split the predicate copy, which 190390075Sobrien;; is kind of a pain, but oh well. 190490075Sobrien 190590075Sobrien(define_peephole2 190690075Sobrien [(set (match_operand:BI 0 "register_operand" "") 190790075Sobrien (match_operand:BI 1 "comparison_operator" "")) 190890075Sobrien (set (match_operand:CCI 2 "register_operand" "") 190990075Sobrien (match_operand:CCI 3 "register_operand" "")) 191090075Sobrien (set (match_operand:CCI 4 "register_operand" "") 191190075Sobrien (match_operand:CCI 5 "register_operand" "")) 191290075Sobrien (set (match_operand:BI 6 "register_operand" "") 1913117395Skan (unspec:BI [(match_dup 6)] UNSPEC_PRED_REL_MUTEX))] 191490075Sobrien "REGNO (operands[3]) == REGNO (operands[0]) 191590075Sobrien && REGNO (operands[4]) == REGNO (operands[0]) + 1 191690075Sobrien && REGNO (operands[4]) == REGNO (operands[2]) + 1 191790075Sobrien && REGNO (operands[6]) == REGNO (operands[2])" 191890075Sobrien [(set (match_dup 0) (match_dup 1)) 191990075Sobrien (set (match_dup 6) (match_dup 7))] 192090075Sobrien "operands[7] = copy_rtx (operands[1]);") 192190075Sobrien 192290075Sobrien;; :::::::::::::::::::: 192390075Sobrien;; :: 192490075Sobrien;; :: 16 bit Integer arithmetic 192590075Sobrien;; :: 192690075Sobrien;; :::::::::::::::::::: 192790075Sobrien 192890075Sobrien(define_insn "mulhi3" 192990075Sobrien [(set (match_operand:HI 0 "gr_register_operand" "=r") 193090075Sobrien (mult:HI (match_operand:HI 1 "gr_register_operand" "r") 193190075Sobrien (match_operand:HI 2 "gr_register_operand" "r")))] 193290075Sobrien "" 193390075Sobrien "pmpy2.r %0 = %1, %2" 193490075Sobrien [(set_attr "itanium_class" "mmmul")]) 193590075Sobrien 193690075Sobrien 193790075Sobrien;; :::::::::::::::::::: 193890075Sobrien;; :: 193990075Sobrien;; :: 32 bit Integer arithmetic 194090075Sobrien;; :: 194190075Sobrien;; :::::::::::::::::::: 194290075Sobrien 194390075Sobrien(define_insn "addsi3" 194490075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r") 194590075Sobrien (plus:SI (match_operand:SI 1 "gr_register_operand" "%r,r,a") 194690075Sobrien (match_operand:SI 2 "gr_reg_or_22bit_operand" "r,I,J")))] 194790075Sobrien "" 194890075Sobrien "@ 1949117395Skan add %0 = %1, %2 1950117395Skan adds %0 = %2, %1 1951117395Skan addl %0 = %2, %1" 195290075Sobrien [(set_attr "itanium_class" "ialu")]) 195390075Sobrien 195490075Sobrien(define_insn "*addsi3_plus1" 195590075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 195690075Sobrien (plus:SI (plus:SI (match_operand:SI 1 "gr_register_operand" "r") 195790075Sobrien (match_operand:SI 2 "gr_register_operand" "r")) 195890075Sobrien (const_int 1)))] 195990075Sobrien "" 196090075Sobrien "add %0 = %1, %2, 1" 196190075Sobrien [(set_attr "itanium_class" "ialu")]) 196290075Sobrien 196390075Sobrien(define_insn "*addsi3_plus1_alt" 196490075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 196590075Sobrien (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r") 196690075Sobrien (const_int 2)) 196790075Sobrien (const_int 1)))] 196890075Sobrien "" 196990075Sobrien "add %0 = %1, %1, 1" 197090075Sobrien [(set_attr "itanium_class" "ialu")]) 197190075Sobrien 197290075Sobrien(define_insn "*addsi3_shladd" 197390075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 197490075Sobrien (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r") 197590075Sobrien (match_operand:SI 2 "shladd_operand" "n")) 197690075Sobrien (match_operand:SI 3 "gr_register_operand" "r")))] 197790075Sobrien "" 197890075Sobrien "shladd %0 = %1, %S2, %3" 197990075Sobrien [(set_attr "itanium_class" "ialu")]) 198090075Sobrien 198190075Sobrien(define_insn "subsi3" 198290075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 198390075Sobrien (minus:SI (match_operand:SI 1 "gr_reg_or_8bit_operand" "rK") 198490075Sobrien (match_operand:SI 2 "gr_register_operand" "r")))] 198590075Sobrien "" 198690075Sobrien "sub %0 = %1, %2" 198790075Sobrien [(set_attr "itanium_class" "ialu")]) 198890075Sobrien 198990075Sobrien(define_insn "*subsi3_minus1" 199090075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 199190075Sobrien (plus:SI (not:SI (match_operand:SI 1 "gr_register_operand" "r")) 199290075Sobrien (match_operand:SI 2 "gr_register_operand" "r")))] 199390075Sobrien "" 199490075Sobrien "sub %0 = %2, %1, 1" 199590075Sobrien [(set_attr "itanium_class" "ialu")]) 199690075Sobrien 199790075Sobrien;; ??? Could add maddsi3 patterns patterned after the madddi3 patterns. 199890075Sobrien 199990075Sobrien(define_insn "mulsi3" 200090075Sobrien [(set (match_operand:SI 0 "fr_register_operand" "=f") 200190075Sobrien (mult:SI (match_operand:SI 1 "grfr_register_operand" "f") 200290075Sobrien (match_operand:SI 2 "grfr_register_operand" "f")))] 200390075Sobrien "" 200490075Sobrien "xmpy.l %0 = %1, %2" 200590075Sobrien [(set_attr "itanium_class" "xmpy")]) 200690075Sobrien 200790075Sobrien(define_insn "maddsi4" 200890075Sobrien [(set (match_operand:SI 0 "fr_register_operand" "=f") 200990075Sobrien (plus:SI (mult:SI (match_operand:SI 1 "grfr_register_operand" "f") 201090075Sobrien (match_operand:SI 2 "grfr_register_operand" "f")) 201190075Sobrien (match_operand:SI 3 "grfr_register_operand" "f")))] 201290075Sobrien "" 201390075Sobrien "xma.l %0 = %1, %2, %3" 201490075Sobrien [(set_attr "itanium_class" "xmpy")]) 201590075Sobrien 201690075Sobrien(define_insn "negsi2" 201790075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 201890075Sobrien (neg:SI (match_operand:SI 1 "gr_register_operand" "r")))] 201990075Sobrien "" 202090075Sobrien "sub %0 = r0, %1" 202190075Sobrien [(set_attr "itanium_class" "ialu")]) 202290075Sobrien 202390075Sobrien(define_expand "abssi2" 202490075Sobrien [(set (match_dup 2) 202590075Sobrien (ge:BI (match_operand:SI 1 "gr_register_operand" "") (const_int 0))) 202690075Sobrien (set (match_operand:SI 0 "gr_register_operand" "") 202790075Sobrien (if_then_else:SI (eq (match_dup 2) (const_int 0)) 202890075Sobrien (neg:SI (match_dup 1)) 202990075Sobrien (match_dup 1)))] 203090075Sobrien "" 2031117395Skan { operands[2] = gen_reg_rtx (BImode); }) 203290075Sobrien 203390075Sobrien(define_expand "sminsi3" 203490075Sobrien [(set (match_dup 3) 203590075Sobrien (ge:BI (match_operand:SI 1 "gr_register_operand" "") 203690075Sobrien (match_operand:SI 2 "gr_register_operand" ""))) 203790075Sobrien (set (match_operand:SI 0 "gr_register_operand" "") 203890075Sobrien (if_then_else:SI (ne (match_dup 3) (const_int 0)) 203990075Sobrien (match_dup 2) (match_dup 1)))] 204090075Sobrien "" 2041117395Skan { operands[3] = gen_reg_rtx (BImode); }) 204290075Sobrien 204390075Sobrien(define_expand "smaxsi3" 204490075Sobrien [(set (match_dup 3) 204590075Sobrien (ge:BI (match_operand:SI 1 "gr_register_operand" "") 204690075Sobrien (match_operand:SI 2 "gr_register_operand" ""))) 204790075Sobrien (set (match_operand:SI 0 "gr_register_operand" "") 204890075Sobrien (if_then_else:SI (ne (match_dup 3) (const_int 0)) 204990075Sobrien (match_dup 1) (match_dup 2)))] 205090075Sobrien "" 2051117395Skan { operands[3] = gen_reg_rtx (BImode); }) 205290075Sobrien 205390075Sobrien(define_expand "uminsi3" 205490075Sobrien [(set (match_dup 3) 205590075Sobrien (geu:BI (match_operand:SI 1 "gr_register_operand" "") 205690075Sobrien (match_operand:SI 2 "gr_register_operand" ""))) 205790075Sobrien (set (match_operand:SI 0 "gr_register_operand" "") 205890075Sobrien (if_then_else:SI (ne (match_dup 3) (const_int 0)) 205990075Sobrien (match_dup 2) (match_dup 1)))] 206090075Sobrien "" 2061117395Skan { operands[3] = gen_reg_rtx (BImode); }) 206290075Sobrien 206390075Sobrien(define_expand "umaxsi3" 206490075Sobrien [(set (match_dup 3) 206590075Sobrien (geu:BI (match_operand:SI 1 "gr_register_operand" "") 206690075Sobrien (match_operand:SI 2 "gr_register_operand" ""))) 206790075Sobrien (set (match_operand:SI 0 "gr_register_operand" "") 206890075Sobrien (if_then_else:SI (ne (match_dup 3) (const_int 0)) 206990075Sobrien (match_dup 1) (match_dup 2)))] 207090075Sobrien "" 2071117395Skan { operands[3] = gen_reg_rtx (BImode); }) 207290075Sobrien 207390075Sobrien(define_expand "divsi3" 207490075Sobrien [(set (match_operand:SI 0 "register_operand" "") 207590075Sobrien (div:SI (match_operand:SI 1 "general_operand" "") 207690075Sobrien (match_operand:SI 2 "general_operand" "")))] 2077132718Skan "TARGET_INLINE_INT_DIV" 207890075Sobrien{ 2079169689Skan rtx op1_xf, op2_xf, op0_xf, op0_di, twon34, twon34_exp; 208090075Sobrien 2081132718Skan op0_xf = gen_reg_rtx (XFmode); 208290075Sobrien op0_di = gen_reg_rtx (DImode); 208390075Sobrien 208490075Sobrien if (CONSTANT_P (operands[1])) 208590075Sobrien operands[1] = force_reg (SImode, operands[1]); 2086132718Skan op1_xf = gen_reg_rtx (XFmode); 2087132718Skan expand_float (op1_xf, operands[1], 0); 208890075Sobrien 208990075Sobrien if (CONSTANT_P (operands[2])) 209090075Sobrien operands[2] = force_reg (SImode, operands[2]); 2091132718Skan op2_xf = gen_reg_rtx (XFmode); 2092132718Skan expand_float (op2_xf, operands[2], 0); 209390075Sobrien 209490075Sobrien /* 2^-34 */ 2095169689Skan twon34_exp = gen_reg_rtx (DImode); 2096169689Skan emit_move_insn (twon34_exp, GEN_INT (65501)); 2097169689Skan twon34 = gen_reg_rtx (XFmode); 2098169689Skan emit_insn (gen_setf_exp_xf (twon34, twon34_exp)); 209990075Sobrien 2100169689Skan emit_insn (gen_cond_trap (EQ, operands[2], CONST0_RTX (SImode), 2101169689Skan CONST1_RTX (SImode))); 2102169689Skan 2103132718Skan emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34)); 210490075Sobrien 2105132718Skan emit_insn (gen_fix_truncxfdi2_alts (op0_di, op0_xf, const1_rtx)); 210690075Sobrien emit_move_insn (operands[0], gen_lowpart (SImode, op0_di)); 210790075Sobrien DONE; 2108117395Skan}) 210990075Sobrien 211090075Sobrien(define_expand "modsi3" 211190075Sobrien [(set (match_operand:SI 0 "register_operand" "") 211290075Sobrien (mod:SI (match_operand:SI 1 "general_operand" "") 211390075Sobrien (match_operand:SI 2 "general_operand" "")))] 2114132718Skan "TARGET_INLINE_INT_DIV" 211590075Sobrien{ 211690075Sobrien rtx op2_neg, op1_di, div; 211790075Sobrien 211890075Sobrien div = gen_reg_rtx (SImode); 211990075Sobrien emit_insn (gen_divsi3 (div, operands[1], operands[2])); 212090075Sobrien 212190075Sobrien op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0); 212290075Sobrien 212390075Sobrien /* This is a trick to get us to reuse the value that we're sure to 212490075Sobrien have already copied to the FP regs. */ 212590075Sobrien op1_di = gen_reg_rtx (DImode); 212690075Sobrien convert_move (op1_di, operands[1], 0); 212790075Sobrien 212890075Sobrien emit_insn (gen_maddsi4 (operands[0], div, op2_neg, 212990075Sobrien gen_lowpart (SImode, op1_di))); 213090075Sobrien DONE; 2131117395Skan}) 213290075Sobrien 213390075Sobrien(define_expand "udivsi3" 213490075Sobrien [(set (match_operand:SI 0 "register_operand" "") 213590075Sobrien (udiv:SI (match_operand:SI 1 "general_operand" "") 213690075Sobrien (match_operand:SI 2 "general_operand" "")))] 2137132718Skan "TARGET_INLINE_INT_DIV" 213890075Sobrien{ 2139169689Skan rtx op1_xf, op2_xf, op0_xf, op0_di, twon34, twon34_exp; 214090075Sobrien 2141132718Skan op0_xf = gen_reg_rtx (XFmode); 214290075Sobrien op0_di = gen_reg_rtx (DImode); 214390075Sobrien 214490075Sobrien if (CONSTANT_P (operands[1])) 214590075Sobrien operands[1] = force_reg (SImode, operands[1]); 2146132718Skan op1_xf = gen_reg_rtx (XFmode); 2147132718Skan expand_float (op1_xf, operands[1], 1); 214890075Sobrien 214990075Sobrien if (CONSTANT_P (operands[2])) 215090075Sobrien operands[2] = force_reg (SImode, operands[2]); 2151132718Skan op2_xf = gen_reg_rtx (XFmode); 2152132718Skan expand_float (op2_xf, operands[2], 1); 215390075Sobrien 215490075Sobrien /* 2^-34 */ 2155169689Skan twon34_exp = gen_reg_rtx (DImode); 2156169689Skan emit_move_insn (twon34_exp, GEN_INT (65501)); 2157169689Skan twon34 = gen_reg_rtx (XFmode); 2158169689Skan emit_insn (gen_setf_exp_xf (twon34, twon34_exp)); 215990075Sobrien 2160169689Skan emit_insn (gen_cond_trap (EQ, operands[2], CONST0_RTX (SImode), 2161169689Skan CONST1_RTX (SImode))); 2162169689Skan 2163132718Skan emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34)); 216490075Sobrien 2165132718Skan emit_insn (gen_fixuns_truncxfdi2_alts (op0_di, op0_xf, const1_rtx)); 216690075Sobrien emit_move_insn (operands[0], gen_lowpart (SImode, op0_di)); 216790075Sobrien DONE; 2168117395Skan}) 216990075Sobrien 217090075Sobrien(define_expand "umodsi3" 217190075Sobrien [(set (match_operand:SI 0 "register_operand" "") 217290075Sobrien (umod:SI (match_operand:SI 1 "general_operand" "") 217390075Sobrien (match_operand:SI 2 "general_operand" "")))] 2174132718Skan "TARGET_INLINE_INT_DIV" 217590075Sobrien{ 217690075Sobrien rtx op2_neg, op1_di, div; 217790075Sobrien 217890075Sobrien div = gen_reg_rtx (SImode); 217990075Sobrien emit_insn (gen_udivsi3 (div, operands[1], operands[2])); 218090075Sobrien 218190075Sobrien op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0); 218290075Sobrien 218390075Sobrien /* This is a trick to get us to reuse the value that we're sure to 218490075Sobrien have already copied to the FP regs. */ 218590075Sobrien op1_di = gen_reg_rtx (DImode); 218690075Sobrien convert_move (op1_di, operands[1], 1); 218790075Sobrien 218890075Sobrien emit_insn (gen_maddsi4 (operands[0], div, op2_neg, 218990075Sobrien gen_lowpart (SImode, op1_di))); 219090075Sobrien DONE; 2191117395Skan}) 219290075Sobrien 219390075Sobrien(define_insn_and_split "divsi3_internal" 2194132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=&f") 2195132718Skan (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f") 2196132718Skan (match_operand:XF 2 "fr_register_operand" "f")))) 2197132718Skan (clobber (match_scratch:XF 4 "=&f")) 2198132718Skan (clobber (match_scratch:XF 5 "=&f")) 219990075Sobrien (clobber (match_scratch:BI 6 "=c")) 2200132718Skan (use (match_operand:XF 3 "fr_register_operand" "f"))] 2201132718Skan "TARGET_INLINE_INT_DIV" 220290075Sobrien "#" 220390075Sobrien "&& reload_completed" 2204132718Skan [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2))) 2205117395Skan (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)] 2206117395Skan UNSPEC_FR_RECIP_APPROX)) 220790075Sobrien (use (const_int 1))]) 220890075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 2209132718Skan (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0))) 221090075Sobrien (use (const_int 1))])) 221190075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 221290075Sobrien (parallel [(set (match_dup 5) 2213169689Skan (minus:XF (match_dup 7) 2214169689Skan (mult:XF (match_dup 2) (match_dup 0)))) 221590075Sobrien (use (const_int 1))])) 221690075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 221790075Sobrien (parallel [(set (match_dup 4) 2218132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 4)) 221990075Sobrien (match_dup 4))) 222090075Sobrien (use (const_int 1))])) 222190075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 222290075Sobrien (parallel [(set (match_dup 5) 2223132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 5)) 222490075Sobrien (match_dup 3))) 222590075Sobrien (use (const_int 1))])) 222690075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 222790075Sobrien (parallel [(set (match_dup 0) 2228132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 4)) 222990075Sobrien (match_dup 4))) 223090075Sobrien (use (const_int 1))])) 223190075Sobrien ] 2232132718Skan "operands[7] = CONST1_RTX (XFmode);" 223390075Sobrien [(set_attr "predicable" "no")]) 223490075Sobrien 223590075Sobrien;; :::::::::::::::::::: 223690075Sobrien;; :: 223790075Sobrien;; :: 64 bit Integer arithmetic 223890075Sobrien;; :: 223990075Sobrien;; :::::::::::::::::::: 224090075Sobrien 224190075Sobrien(define_insn "adddi3" 224290075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r") 224390075Sobrien (plus:DI (match_operand:DI 1 "gr_register_operand" "%r,r,a") 224490075Sobrien (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))] 224590075Sobrien "" 224690075Sobrien "@ 2247117395Skan add %0 = %1, %2 2248117395Skan adds %0 = %2, %1 2249117395Skan addl %0 = %2, %1" 225090075Sobrien [(set_attr "itanium_class" "ialu")]) 225190075Sobrien 225290075Sobrien(define_insn "*adddi3_plus1" 225390075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 225490075Sobrien (plus:DI (plus:DI (match_operand:DI 1 "gr_register_operand" "r") 225590075Sobrien (match_operand:DI 2 "gr_register_operand" "r")) 225690075Sobrien (const_int 1)))] 225790075Sobrien "" 225890075Sobrien "add %0 = %1, %2, 1" 225990075Sobrien [(set_attr "itanium_class" "ialu")]) 226090075Sobrien 226190075Sobrien;; This has some of the same problems as shladd. We let the shladd 226290075Sobrien;; eliminator hack handle it, which results in the 1 being forced into 226390075Sobrien;; a register, but not more ugliness here. 226490075Sobrien(define_insn "*adddi3_plus1_alt" 226590075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 226690075Sobrien (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r") 226790075Sobrien (const_int 2)) 226890075Sobrien (const_int 1)))] 226990075Sobrien "" 227090075Sobrien "add %0 = %1, %1, 1" 227190075Sobrien [(set_attr "itanium_class" "ialu")]) 227290075Sobrien 227390075Sobrien(define_insn "subdi3" 227490075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 227590075Sobrien (minus:DI (match_operand:DI 1 "gr_reg_or_8bit_operand" "rK") 227690075Sobrien (match_operand:DI 2 "gr_register_operand" "r")))] 227790075Sobrien "" 227890075Sobrien "sub %0 = %1, %2" 227990075Sobrien [(set_attr "itanium_class" "ialu")]) 228090075Sobrien 228190075Sobrien(define_insn "*subdi3_minus1" 228290075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 228390075Sobrien (plus:DI (not:DI (match_operand:DI 1 "gr_register_operand" "r")) 228490075Sobrien (match_operand:DI 2 "gr_register_operand" "r")))] 228590075Sobrien "" 228690075Sobrien "sub %0 = %2, %1, 1" 228790075Sobrien [(set_attr "itanium_class" "ialu")]) 228890075Sobrien 228990075Sobrien;; ??? Use grfr instead of fr because of virtual register elimination 229090075Sobrien;; and silly test cases multiplying by the frame pointer. 229190075Sobrien(define_insn "muldi3" 229290075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 229390075Sobrien (mult:DI (match_operand:DI 1 "grfr_register_operand" "f") 229490075Sobrien (match_operand:DI 2 "grfr_register_operand" "f")))] 229590075Sobrien "" 229690075Sobrien "xmpy.l %0 = %1, %2" 229790075Sobrien [(set_attr "itanium_class" "xmpy")]) 229890075Sobrien 229990075Sobrien;; ??? If operand 3 is an eliminable reg, then register elimination causes the 230090075Sobrien;; same problem that we have with shladd below. Unfortunately, this case is 230190075Sobrien;; much harder to fix because the multiply puts the result in an FP register, 230290075Sobrien;; but the add needs inputs from a general register. We add a spurious clobber 230390075Sobrien;; here so that it will be present just in case register elimination gives us 230490075Sobrien;; the funny result. 230590075Sobrien 230690075Sobrien;; ??? Maybe validate_changes should try adding match_scratch clobbers? 230790075Sobrien 230890075Sobrien;; ??? Maybe we should change how adds are canonicalized. 230990075Sobrien 231090075Sobrien(define_insn "madddi4" 231190075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 231290075Sobrien (plus:DI (mult:DI (match_operand:DI 1 "grfr_register_operand" "f") 231390075Sobrien (match_operand:DI 2 "grfr_register_operand" "f")) 231490075Sobrien (match_operand:DI 3 "grfr_register_operand" "f"))) 231590075Sobrien (clobber (match_scratch:DI 4 "=X"))] 231690075Sobrien "" 231790075Sobrien "xma.l %0 = %1, %2, %3" 231890075Sobrien [(set_attr "itanium_class" "xmpy")]) 231990075Sobrien 232090075Sobrien;; This can be created by register elimination if operand3 of shladd is an 232190075Sobrien;; eliminable register or has reg_equiv_constant set. 232290075Sobrien 232390075Sobrien;; We have to use nonmemory_operand for operand 4, to ensure that the 232490075Sobrien;; validate_changes call inside eliminate_regs will always succeed. If it 232590075Sobrien;; doesn't succeed, then this remain a madddi4 pattern, and will be reloaded 232690075Sobrien;; incorrectly. 232790075Sobrien 232890075Sobrien(define_insn "*madddi4_elim" 232990075Sobrien [(set (match_operand:DI 0 "register_operand" "=&r") 233090075Sobrien (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "f") 233190075Sobrien (match_operand:DI 2 "register_operand" "f")) 233290075Sobrien (match_operand:DI 3 "register_operand" "f")) 233390075Sobrien (match_operand:DI 4 "nonmemory_operand" "rI"))) 233490075Sobrien (clobber (match_scratch:DI 5 "=f"))] 233590075Sobrien "reload_in_progress" 233690075Sobrien "#" 233790075Sobrien [(set_attr "itanium_class" "unknown")]) 233890075Sobrien 233990075Sobrien(define_split 234090075Sobrien [(set (match_operand:DI 0 "register_operand" "") 234190075Sobrien (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "") 234290075Sobrien (match_operand:DI 2 "register_operand" "")) 234390075Sobrien (match_operand:DI 3 "register_operand" "")) 234490075Sobrien (match_operand:DI 4 "gr_reg_or_14bit_operand" ""))) 234590075Sobrien (clobber (match_scratch:DI 5 ""))] 234690075Sobrien "reload_completed" 234790075Sobrien [(parallel [(set (match_dup 5) (plus:DI (mult:DI (match_dup 1) (match_dup 2)) 234890075Sobrien (match_dup 3))) 234990075Sobrien (clobber (match_dup 0))]) 235090075Sobrien (set (match_dup 0) (match_dup 5)) 235190075Sobrien (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))] 235290075Sobrien "") 235390075Sobrien 235490075Sobrien(define_insn "smuldi3_highpart" 235590075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 235690075Sobrien (truncate:DI 235790075Sobrien (lshiftrt:TI 235890075Sobrien (mult:TI (sign_extend:TI 235990075Sobrien (match_operand:DI 1 "fr_register_operand" "f")) 236090075Sobrien (sign_extend:TI 236190075Sobrien (match_operand:DI 2 "fr_register_operand" "f"))) 236290075Sobrien (const_int 64))))] 236390075Sobrien "" 236490075Sobrien "xmpy.h %0 = %1, %2" 236590075Sobrien [(set_attr "itanium_class" "xmpy")]) 236690075Sobrien 236790075Sobrien(define_insn "umuldi3_highpart" 236890075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 236990075Sobrien (truncate:DI 237090075Sobrien (lshiftrt:TI 237190075Sobrien (mult:TI (zero_extend:TI 237290075Sobrien (match_operand:DI 1 "fr_register_operand" "f")) 237390075Sobrien (zero_extend:TI 237490075Sobrien (match_operand:DI 2 "fr_register_operand" "f"))) 237590075Sobrien (const_int 64))))] 237690075Sobrien "" 237790075Sobrien "xmpy.hu %0 = %1, %2" 237890075Sobrien [(set_attr "itanium_class" "xmpy")]) 237990075Sobrien 238090075Sobrien(define_insn "negdi2" 238190075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 238290075Sobrien (neg:DI (match_operand:DI 1 "gr_register_operand" "r")))] 238390075Sobrien "" 238490075Sobrien "sub %0 = r0, %1" 238590075Sobrien [(set_attr "itanium_class" "ialu")]) 238690075Sobrien 238790075Sobrien(define_expand "absdi2" 238890075Sobrien [(set (match_dup 2) 238990075Sobrien (ge:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0))) 239090075Sobrien (set (match_operand:DI 0 "gr_register_operand" "") 239190075Sobrien (if_then_else:DI (eq (match_dup 2) (const_int 0)) 239290075Sobrien (neg:DI (match_dup 1)) 239390075Sobrien (match_dup 1)))] 239490075Sobrien "" 2395117395Skan { operands[2] = gen_reg_rtx (BImode); }) 239690075Sobrien 239790075Sobrien(define_expand "smindi3" 239890075Sobrien [(set (match_dup 3) 239990075Sobrien (ge:BI (match_operand:DI 1 "gr_register_operand" "") 240090075Sobrien (match_operand:DI 2 "gr_register_operand" ""))) 240190075Sobrien (set (match_operand:DI 0 "gr_register_operand" "") 240290075Sobrien (if_then_else:DI (ne (match_dup 3) (const_int 0)) 240390075Sobrien (match_dup 2) (match_dup 1)))] 240490075Sobrien "" 2405117395Skan { operands[3] = gen_reg_rtx (BImode); }) 240690075Sobrien 240790075Sobrien(define_expand "smaxdi3" 240890075Sobrien [(set (match_dup 3) 240990075Sobrien (ge:BI (match_operand:DI 1 "gr_register_operand" "") 241090075Sobrien (match_operand:DI 2 "gr_register_operand" ""))) 241190075Sobrien (set (match_operand:DI 0 "gr_register_operand" "") 241290075Sobrien (if_then_else:DI (ne (match_dup 3) (const_int 0)) 241390075Sobrien (match_dup 1) (match_dup 2)))] 241490075Sobrien "" 2415117395Skan { operands[3] = gen_reg_rtx (BImode); }) 241690075Sobrien 241790075Sobrien(define_expand "umindi3" 241890075Sobrien [(set (match_dup 3) 241990075Sobrien (geu:BI (match_operand:DI 1 "gr_register_operand" "") 242090075Sobrien (match_operand:DI 2 "gr_register_operand" ""))) 242190075Sobrien (set (match_operand:DI 0 "gr_register_operand" "") 242290075Sobrien (if_then_else:DI (ne (match_dup 3) (const_int 0)) 242390075Sobrien (match_dup 2) (match_dup 1)))] 242490075Sobrien "" 2425117395Skan { operands[3] = gen_reg_rtx (BImode); }) 242690075Sobrien 242790075Sobrien(define_expand "umaxdi3" 242890075Sobrien [(set (match_dup 3) 242990075Sobrien (geu:BI (match_operand:DI 1 "gr_register_operand" "") 243090075Sobrien (match_operand:DI 2 "gr_register_operand" ""))) 243190075Sobrien (set (match_operand:DI 0 "gr_register_operand" "") 243290075Sobrien (if_then_else:DI (ne (match_dup 3) (const_int 0)) 243390075Sobrien (match_dup 1) (match_dup 2)))] 243490075Sobrien "" 2435117395Skan { operands[3] = gen_reg_rtx (BImode); }) 243690075Sobrien 243790075Sobrien(define_expand "ffsdi2" 243890075Sobrien [(set (match_dup 6) 243990075Sobrien (eq:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0))) 244090075Sobrien (set (match_dup 2) (plus:DI (match_dup 1) (const_int -1))) 244190075Sobrien (set (match_dup 5) (const_int 0)) 244290075Sobrien (set (match_dup 3) (xor:DI (match_dup 1) (match_dup 2))) 2443132718Skan (set (match_dup 4) (popcount:DI (match_dup 3))) 244490075Sobrien (set (match_operand:DI 0 "gr_register_operand" "") 244590075Sobrien (if_then_else:DI (ne (match_dup 6) (const_int 0)) 244690075Sobrien (match_dup 5) (match_dup 4)))] 244790075Sobrien "" 244890075Sobrien{ 244990075Sobrien operands[2] = gen_reg_rtx (DImode); 245090075Sobrien operands[3] = gen_reg_rtx (DImode); 245190075Sobrien operands[4] = gen_reg_rtx (DImode); 245290075Sobrien operands[5] = gen_reg_rtx (DImode); 245390075Sobrien operands[6] = gen_reg_rtx (BImode); 2454117395Skan}) 245590075Sobrien 2456132718Skan(define_expand "ctzdi2" 2457132718Skan [(set (match_dup 2) (plus:DI (match_operand:DI 1 "gr_register_operand" "") 2458132718Skan (const_int -1))) 2459132718Skan (set (match_dup 3) (not:DI (match_dup 1))) 2460132718Skan (set (match_dup 4) (and:DI (match_dup 2) (match_dup 3))) 2461132718Skan (set (match_operand:DI 0 "gr_register_operand" "") 2462132718Skan (popcount:DI (match_dup 4)))] 2463132718Skan "" 2464132718Skan{ 2465132718Skan operands[2] = gen_reg_rtx (DImode); 2466132718Skan operands[3] = gen_reg_rtx (DImode); 2467132718Skan operands[4] = gen_reg_rtx (DImode); 2468132718Skan}) 2469132718Skan 2470132718Skan;; Note the computation here is op0 = 63 - (exp - 0xffff). 2471132718Skan(define_expand "clzdi2" 2472132718Skan [(set (match_dup 2) 2473132718Skan (unsigned_float:XF (match_operand:DI 1 "fr_register_operand" ""))) 2474132718Skan (set (match_dup 3) 2475132718Skan (unspec:DI [(match_dup 2)] UNSPEC_GETF_EXP)) 2476132718Skan (set (match_dup 4) (const_int 65598)) 2477132718Skan (set (match_operand:DI 0 "gr_register_operand" "") 2478132718Skan (minus:DI (match_dup 4) (match_dup 3)))] 2479132718Skan "" 2480132718Skan{ 2481132718Skan operands[2] = gen_reg_rtx (XFmode); 2482132718Skan operands[3] = gen_reg_rtx (DImode); 2483132718Skan operands[4] = gen_reg_rtx (DImode); 2484132718Skan}) 2485132718Skan 2486132718Skan(define_insn "popcountdi2" 248790075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 2488132718Skan (popcount:DI (match_operand:DI 1 "gr_register_operand" "r")))] 248990075Sobrien "" 249090075Sobrien "popcnt %0 = %1" 249190075Sobrien [(set_attr "itanium_class" "mmmul")]) 249290075Sobrien 2493132718Skan(define_insn "*getf_exp_xf" 2494132718Skan [(set (match_operand:DI 0 "gr_register_operand" "=r") 2495132718Skan (unspec:DI [(match_operand:XF 1 "fr_register_operand" "f")] 2496132718Skan UNSPEC_GETF_EXP))] 2497132718Skan "" 2498132718Skan "getf.exp %0 = %1" 2499132718Skan [(set_attr "itanium_class" "frfr")]) 2500132718Skan 250190075Sobrien(define_expand "divdi3" 250290075Sobrien [(set (match_operand:DI 0 "register_operand" "") 250390075Sobrien (div:DI (match_operand:DI 1 "general_operand" "") 250490075Sobrien (match_operand:DI 2 "general_operand" "")))] 2505132718Skan "TARGET_INLINE_INT_DIV" 250690075Sobrien{ 2507132718Skan rtx op1_xf, op2_xf, op0_xf; 250890075Sobrien 2509132718Skan op0_xf = gen_reg_rtx (XFmode); 251090075Sobrien 251190075Sobrien if (CONSTANT_P (operands[1])) 251290075Sobrien operands[1] = force_reg (DImode, operands[1]); 2513132718Skan op1_xf = gen_reg_rtx (XFmode); 2514132718Skan expand_float (op1_xf, operands[1], 0); 251590075Sobrien 251690075Sobrien if (CONSTANT_P (operands[2])) 251790075Sobrien operands[2] = force_reg (DImode, operands[2]); 2518132718Skan op2_xf = gen_reg_rtx (XFmode); 2519132718Skan expand_float (op2_xf, operands[2], 0); 252090075Sobrien 2521169689Skan emit_insn (gen_cond_trap (EQ, operands[2], CONST0_RTX (DImode), 2522169689Skan CONST1_RTX (DImode))); 2523169689Skan 2524169689Skan if (TARGET_INLINE_INT_DIV == INL_MIN_LAT) 2525132718Skan emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf)); 252690075Sobrien else 2527132718Skan emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf)); 252890075Sobrien 2529132718Skan emit_insn (gen_fix_truncxfdi2_alts (operands[0], op0_xf, const1_rtx)); 253090075Sobrien DONE; 2531117395Skan}) 253290075Sobrien 253390075Sobrien(define_expand "moddi3" 253490075Sobrien [(set (match_operand:DI 0 "register_operand" "") 253590075Sobrien (mod:SI (match_operand:DI 1 "general_operand" "") 253690075Sobrien (match_operand:DI 2 "general_operand" "")))] 2537132718Skan "TARGET_INLINE_INT_DIV" 253890075Sobrien{ 253990075Sobrien rtx op2_neg, div; 254090075Sobrien 254190075Sobrien div = gen_reg_rtx (DImode); 254290075Sobrien emit_insn (gen_divdi3 (div, operands[1], operands[2])); 254390075Sobrien 254490075Sobrien op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0); 254590075Sobrien 254690075Sobrien emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1])); 254790075Sobrien DONE; 2548117395Skan}) 254990075Sobrien 255090075Sobrien(define_expand "udivdi3" 255190075Sobrien [(set (match_operand:DI 0 "register_operand" "") 255290075Sobrien (udiv:DI (match_operand:DI 1 "general_operand" "") 255390075Sobrien (match_operand:DI 2 "general_operand" "")))] 2554132718Skan "TARGET_INLINE_INT_DIV" 255590075Sobrien{ 2556132718Skan rtx op1_xf, op2_xf, op0_xf; 255790075Sobrien 2558132718Skan op0_xf = gen_reg_rtx (XFmode); 255990075Sobrien 256090075Sobrien if (CONSTANT_P (operands[1])) 256190075Sobrien operands[1] = force_reg (DImode, operands[1]); 2562132718Skan op1_xf = gen_reg_rtx (XFmode); 2563132718Skan expand_float (op1_xf, operands[1], 1); 256490075Sobrien 256590075Sobrien if (CONSTANT_P (operands[2])) 256690075Sobrien operands[2] = force_reg (DImode, operands[2]); 2567132718Skan op2_xf = gen_reg_rtx (XFmode); 2568132718Skan expand_float (op2_xf, operands[2], 1); 256990075Sobrien 2570169689Skan emit_insn (gen_cond_trap (EQ, operands[2], CONST0_RTX (DImode), 2571169689Skan CONST1_RTX (DImode))); 2572169689Skan 2573169689Skan if (TARGET_INLINE_INT_DIV == INL_MIN_LAT) 2574132718Skan emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf)); 257590075Sobrien else 2576132718Skan emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf)); 257790075Sobrien 2578132718Skan emit_insn (gen_fixuns_truncxfdi2_alts (operands[0], op0_xf, const1_rtx)); 257990075Sobrien DONE; 2580117395Skan}) 258190075Sobrien 258290075Sobrien(define_expand "umoddi3" 258390075Sobrien [(set (match_operand:DI 0 "register_operand" "") 258490075Sobrien (umod:DI (match_operand:DI 1 "general_operand" "") 258590075Sobrien (match_operand:DI 2 "general_operand" "")))] 2586132718Skan "TARGET_INLINE_INT_DIV" 258790075Sobrien{ 258890075Sobrien rtx op2_neg, div; 258990075Sobrien 259090075Sobrien div = gen_reg_rtx (DImode); 259190075Sobrien emit_insn (gen_udivdi3 (div, operands[1], operands[2])); 259290075Sobrien 259390075Sobrien op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0); 259490075Sobrien 259590075Sobrien emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1])); 259690075Sobrien DONE; 2597117395Skan}) 259890075Sobrien 259990075Sobrien(define_insn_and_split "divdi3_internal_lat" 2600132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=&f") 2601132718Skan (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f") 2602132718Skan (match_operand:XF 2 "fr_register_operand" "f")))) 2603132718Skan (clobber (match_scratch:XF 3 "=&f")) 2604132718Skan (clobber (match_scratch:XF 4 "=&f")) 2605132718Skan (clobber (match_scratch:XF 5 "=&f")) 260690075Sobrien (clobber (match_scratch:BI 6 "=c"))] 2607169689Skan "TARGET_INLINE_INT_DIV == INL_MIN_LAT" 260890075Sobrien "#" 260990075Sobrien "&& reload_completed" 2610132718Skan [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2))) 2611117395Skan (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)] 2612117395Skan UNSPEC_FR_RECIP_APPROX)) 261390075Sobrien (use (const_int 1))]) 261490075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 261590075Sobrien (parallel [(set (match_dup 3) 2616169689Skan (minus:XF (match_dup 7) 2617169689Skan (mult:XF (match_dup 2) (match_dup 0)))) 261890075Sobrien (use (const_int 1))])) 261990075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 2620132718Skan (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0))) 262190075Sobrien (use (const_int 1))])) 262290075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 2623132718Skan (parallel [(set (match_dup 5) (mult:XF (match_dup 3) (match_dup 3))) 262490075Sobrien (use (const_int 1))])) 262590075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 262690075Sobrien (parallel [(set (match_dup 4) 2627132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 4)) 262890075Sobrien (match_dup 4))) 262990075Sobrien (use (const_int 1))])) 263090075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 263190075Sobrien (parallel [(set (match_dup 0) 2632132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 0)) 263390075Sobrien (match_dup 0))) 263490075Sobrien (use (const_int 1))])) 263590075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 263690075Sobrien (parallel [(set (match_dup 3) 2637132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 4)) 263890075Sobrien (match_dup 4))) 263990075Sobrien (use (const_int 1))])) 264090075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 264190075Sobrien (parallel [(set (match_dup 0) 2642132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 0)) 264390075Sobrien (match_dup 0))) 264490075Sobrien (use (const_int 1))])) 264590075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 264690075Sobrien (parallel [(set (match_dup 4) 2647169689Skan (minus:XF (match_dup 1) 2648169689Skan (mult:XF (match_dup 2) (match_dup 3)))) 264990075Sobrien (use (const_int 1))])) 265090075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 265190075Sobrien (parallel [(set (match_dup 0) 2652132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 0)) 265390075Sobrien (match_dup 3))) 265490075Sobrien (use (const_int 1))])) 265590075Sobrien ] 2656132718Skan "operands[7] = CONST1_RTX (XFmode);" 265790075Sobrien [(set_attr "predicable" "no")]) 265890075Sobrien 265990075Sobrien(define_insn_and_split "divdi3_internal_thr" 2660132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=&f") 2661132718Skan (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f") 2662132718Skan (match_operand:XF 2 "fr_register_operand" "f")))) 2663132718Skan (clobber (match_scratch:XF 3 "=&f")) 2664132718Skan (clobber (match_scratch:XF 4 "=f")) 266590075Sobrien (clobber (match_scratch:BI 5 "=c"))] 2666169689Skan "TARGET_INLINE_INT_DIV == INL_MAX_THR" 266790075Sobrien "#" 266890075Sobrien "&& reload_completed" 2669132718Skan [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2))) 2670117395Skan (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)] 2671117395Skan UNSPEC_FR_RECIP_APPROX)) 267290075Sobrien (use (const_int 1))]) 267390075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 267490075Sobrien (parallel [(set (match_dup 3) 2675169689Skan (minus:XF (match_dup 6) 2676169689Skan (mult:XF (match_dup 2) (match_dup 0)))) 267790075Sobrien (use (const_int 1))])) 267890075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 267990075Sobrien (parallel [(set (match_dup 0) 2680132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 0)) 268190075Sobrien (match_dup 0))) 268290075Sobrien (use (const_int 1))])) 268390075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 2684132718Skan (parallel [(set (match_dup 3) (mult:XF (match_dup 3) (match_dup 3))) 268590075Sobrien (use (const_int 1))])) 268690075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 268790075Sobrien (parallel [(set (match_dup 0) 2688132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 0)) 268990075Sobrien (match_dup 0))) 269090075Sobrien (use (const_int 1))])) 269190075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 2692132718Skan (parallel [(set (match_dup 3) (mult:XF (match_dup 0) (match_dup 1))) 269390075Sobrien (use (const_int 1))])) 269490075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 269590075Sobrien (parallel [(set (match_dup 4) 2696169689Skan (minus:XF (match_dup 1) 2697169689Skan (mult:XF (match_dup 2) (match_dup 3)))) 269890075Sobrien (use (const_int 1))])) 269990075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 270090075Sobrien (parallel [(set (match_dup 0) 2701132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 0)) 270290075Sobrien (match_dup 3))) 270390075Sobrien (use (const_int 1))])) 270490075Sobrien ] 2705132718Skan "operands[6] = CONST1_RTX (XFmode);" 270690075Sobrien [(set_attr "predicable" "no")]) 270790075Sobrien 270890075Sobrien;; :::::::::::::::::::: 270990075Sobrien;; :: 2710169689Skan;; :: 128 bit Integer arithmetic 2711169689Skan;; :: 2712169689Skan;; :::::::::::::::::::: 2713169689Skan 2714169689Skan(define_insn "addti3" 2715169689Skan [(set (match_operand:TI 0 "gr_register_operand" "=&r") 2716169689Skan (plus:TI (match_operand:TI 1 "gr_register_operand" "%r") 2717169689Skan (match_operand:TI 2 "gr_reg_or_14bit_operand" "rI"))) 2718169689Skan (clobber (match_scratch:BI 3 "=&c"))] 2719169689Skan "" 2720169689Skan "#" 2721169689Skan [(set_attr "itanium_class" "unknown")]) 2722169689Skan 2723169689Skan(define_split 2724169689Skan [(set (match_operand:TI 0 "register_operand" "") 2725169689Skan (plus:TI (match_operand:TI 1 "register_operand" "") 2726169689Skan (match_operand:TI 2 "register_operand" ""))) 2727169689Skan (clobber (match_scratch:BI 3 ""))] 2728169689Skan "reload_completed" 2729169689Skan [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2))) 2730169689Skan (set (match_dup 3) (ltu:BI (match_dup 0) (match_dup 1))) 2731169689Skan (cond_exec (eq (match_dup 3) (const_int 0)) 2732169689Skan (set (match_dup 4) (plus:DI (match_dup 5) (match_dup 6)))) 2733169689Skan (cond_exec (ne (match_dup 3) (const_int 0)) 2734169689Skan (set (match_dup 4) 2735169689Skan (plus:DI (plus:DI (match_dup 5) (match_dup 6)) 2736169689Skan (const_int 1))))] 2737169689Skan{ 2738169689Skan operands[4] = gen_highpart (DImode, operands[0]); 2739169689Skan operands[0] = gen_lowpart (DImode, operands[0]); 2740169689Skan operands[5] = gen_highpart (DImode, operands[1]); 2741169689Skan operands[1] = gen_lowpart (DImode, operands[1]); 2742169689Skan operands[6] = gen_highpart (DImode, operands[2]); 2743169689Skan operands[2] = gen_lowpart (DImode, operands[2]); 2744169689Skan}) 2745169689Skan 2746169689Skan(define_split 2747169689Skan [(set (match_operand:TI 0 "register_operand" "") 2748169689Skan (plus:TI (match_operand:TI 1 "register_operand" "") 2749169689Skan (match_operand:TI 2 "immediate_operand" ""))) 2750169689Skan (clobber (match_scratch:BI 3 ""))] 2751169689Skan "reload_completed" 2752169689Skan [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2))) 2753169689Skan (set (match_dup 3) (ltu:BI (match_dup 0) (match_dup 1))) 2754169689Skan (cond_exec (eq (match_dup 3) (const_int 0)) 2755169689Skan (set (match_dup 4) 2756169689Skan (plus:DI (match_dup 5) (match_dup 6)))) 2757169689Skan (cond_exec (ne (match_dup 3) (const_int 0)) 2758169689Skan (set (match_dup 4) 2759169689Skan (plus:DI (match_dup 5) (match_dup 7))))] 2760169689Skan{ 2761169689Skan operands[4] = gen_highpart (DImode, operands[0]); 2762169689Skan operands[0] = gen_lowpart (DImode, operands[0]); 2763169689Skan operands[5] = gen_highpart (DImode, operands[1]); 2764169689Skan operands[1] = gen_lowpart (DImode, operands[1]); 2765169689Skan operands[6] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx; 2766169689Skan operands[7] = INTVAL (operands[2]) < 0 ? const0_rtx : const1_rtx; 2767169689Skan}) 2768169689Skan 2769169689Skan(define_insn "subti3" 2770169689Skan [(set (match_operand:TI 0 "gr_register_operand" "=&r") 2771169689Skan (minus:TI (match_operand:TI 1 "gr_reg_or_8bit_operand" "rK") 2772169689Skan (match_operand:TI 2 "gr_register_operand" "r"))) 2773169689Skan (clobber (match_scratch:BI 3 "=&c"))] 2774169689Skan "" 2775169689Skan "#" 2776169689Skan [(set_attr "itanium_class" "unknown")]) 2777169689Skan 2778169689Skan(define_split 2779169689Skan [(set (match_operand:TI 0 "register_operand" "") 2780169689Skan (minus:TI (match_operand:TI 1 "register_operand" "") 2781169689Skan (match_operand:TI 2 "register_operand" ""))) 2782169689Skan (clobber (match_scratch:BI 3 "=&c"))] 2783169689Skan "reload_completed" 2784169689Skan [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2))) 2785169689Skan (set (match_dup 3) (ltu:BI (match_dup 1) (match_dup 0))) 2786169689Skan (cond_exec (eq (match_dup 3) (const_int 0)) 2787169689Skan (set (match_dup 4) (minus:DI (match_dup 5) (match_dup 6)))) 2788169689Skan (cond_exec (ne (match_dup 3) (const_int 0)) 2789169689Skan (set (match_dup 4) 2790169689Skan (plus:DI (not:DI (match_dup 6)) (match_dup 5))))] 2791169689Skan{ 2792169689Skan operands[4] = gen_highpart (DImode, operands[0]); 2793169689Skan operands[0] = gen_lowpart (DImode, operands[0]); 2794169689Skan operands[5] = gen_highpart (DImode, operands[1]); 2795169689Skan operands[1] = gen_lowpart (DImode, operands[1]); 2796169689Skan operands[6] = gen_highpart (DImode, operands[2]); 2797169689Skan operands[2] = gen_lowpart (DImode, operands[2]); 2798169689Skan}) 2799169689Skan 2800169689Skan(define_split 2801169689Skan [(set (match_operand:TI 0 "register_operand" "") 2802169689Skan (minus:TI (match_operand:TI 1 "immediate_operand" "") 2803169689Skan (match_operand:TI 2 "register_operand" ""))) 2804169689Skan (clobber (match_scratch:BI 3 "=&c"))] 2805169689Skan "reload_completed && CONST_OK_FOR_K (INTVAL (operands[1]))" 2806169689Skan [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2))) 2807169689Skan (set (match_dup 3) (gtu:BI (match_dup 0) (match_dup 1))) 2808169689Skan (cond_exec (ne (match_dup 3) (const_int 0)) 2809169689Skan (set (match_dup 4) (minus:DI (match_dup 6) (match_dup 5)))) 2810169689Skan (cond_exec (eq (match_dup 3) (const_int 0)) 2811169689Skan (set (match_dup 4) (minus:DI (match_dup 7) (match_dup 5))))] 2812169689Skan{ 2813169689Skan operands[4] = gen_highpart (DImode, operands[0]); 2814169689Skan operands[0] = gen_lowpart (DImode, operands[0]); 2815169689Skan operands[5] = gen_highpart (DImode, operands[2]); 2816169689Skan operands[2] = gen_lowpart (DImode, operands[2]); 2817169689Skan operands[6] = INTVAL (operands[1]) < 0 ? GEN_INT (-2) : constm1_rtx; 2818169689Skan operands[7] = INTVAL (operands[1]) < 0 ? constm1_rtx : const0_rtx; 2819169689Skan}) 2820169689Skan 2821169689Skan(define_expand "mulditi3" 2822169689Skan [(set (match_operand:TI 0 "fr_register_operand" "") 2823169689Skan (mult:TI (sign_extend:TI 2824169689Skan (match_operand:DI 1 "fr_register_operand" "")) 2825169689Skan (sign_extend:TI 2826169689Skan (match_operand:DI 2 "fr_register_operand" ""))))] 2827169689Skan "" 2828169689Skan "") 2829169689Skan 2830169689Skan(define_insn_and_split "*mulditi3_internal" 2831169689Skan [(set (match_operand:TI 0 "fr_register_operand" "=&f") 2832169689Skan (mult:TI (sign_extend:TI 2833169689Skan (match_operand:DI 1 "fr_register_operand" "%f")) 2834169689Skan (sign_extend:TI 2835169689Skan (match_operand:DI 2 "fr_register_operand" "f"))))] 2836169689Skan "" 2837169689Skan "#" 2838169689Skan "reload_completed" 2839169689Skan [(set (match_dup 0) (mult:DI (match_dup 1) (match_dup 2))) 2840169689Skan (set (match_dup 3) (truncate:DI 2841169689Skan (lshiftrt:TI 2842169689Skan (mult:TI (sign_extend:TI (match_dup 1)) 2843169689Skan (sign_extend:TI (match_dup 2))) 2844169689Skan (const_int 64))))] 2845169689Skan{ 2846169689Skan operands[3] = gen_highpart (DImode, operands[0]); 2847169689Skan operands[0] = gen_lowpart (DImode, operands[0]); 2848169689Skan} 2849169689Skan [(set_attr "itanium_class" "unknown")]) 2850169689Skan 2851169689Skan(define_expand "umulditi3" 2852169689Skan [(set (match_operand:TI 0 "fr_register_operand" "") 2853169689Skan (mult:TI (zero_extend:TI 2854169689Skan (match_operand:DI 1 "fr_register_operand" "")) 2855169689Skan (zero_extend:TI 2856169689Skan (match_operand:DI 2 "fr_register_operand" ""))))] 2857169689Skan "" 2858169689Skan "") 2859169689Skan 2860169689Skan(define_insn_and_split "*umulditi3_internal" 2861169689Skan [(set (match_operand:TI 0 "fr_register_operand" "=&f") 2862169689Skan (mult:TI (zero_extend:TI 2863169689Skan (match_operand:DI 1 "fr_register_operand" "%f")) 2864169689Skan (zero_extend:TI 2865169689Skan (match_operand:DI 2 "fr_register_operand" "f"))))] 2866169689Skan "" 2867169689Skan "#" 2868169689Skan "reload_completed" 2869169689Skan [(set (match_dup 0) (mult:DI (match_dup 1) (match_dup 2))) 2870169689Skan (set (match_dup 3) (truncate:DI 2871169689Skan (lshiftrt:TI 2872169689Skan (mult:TI (zero_extend:TI (match_dup 1)) 2873169689Skan (zero_extend:TI (match_dup 2))) 2874169689Skan (const_int 64))))] 2875169689Skan{ 2876169689Skan operands[3] = gen_highpart (DImode, operands[0]); 2877169689Skan operands[0] = gen_lowpart (DImode, operands[0]); 2878169689Skan} 2879169689Skan [(set_attr "itanium_class" "unknown")]) 2880169689Skan 2881169689Skan(define_insn_and_split "negti2" 2882169689Skan [(set (match_operand:TI 0 "gr_register_operand" "=&r") 2883169689Skan (neg:TI (match_operand:TI 1 "gr_register_operand" "r"))) 2884169689Skan (clobber (match_scratch:BI 2 "=&c"))] 2885169689Skan "" 2886169689Skan "#" 2887169689Skan "reload_completed" 2888169689Skan [(set (match_dup 2) (eq:BI (match_dup 1) (const_int 0))) 2889169689Skan (set (match_dup 0) (minus:DI (const_int 0) (match_dup 1))) 2890169689Skan (cond_exec (eq (match_dup 2) (const_int 0)) 2891169689Skan (set (match_dup 3) (minus:DI (const_int -1) (match_dup 4)))) 2892169689Skan (cond_exec (ne (match_dup 2) (const_int 0)) 2893169689Skan (set (match_dup 3) (minus:DI (const_int 0) (match_dup 4))))] 2894169689Skan{ 2895169689Skan operands[3] = gen_highpart (DImode, operands[0]); 2896169689Skan operands[0] = gen_lowpart (DImode, operands[0]); 2897169689Skan operands[4] = gen_highpart (DImode, operands[1]); 2898169689Skan operands[1] = gen_lowpart (DImode, operands[1]); 2899169689Skan} 2900169689Skan [(set_attr "itanium_class" "unknown")]) 2901169689Skan 2902169689Skan;; :::::::::::::::::::: 2903169689Skan;; :: 290490075Sobrien;; :: 32 bit floating point arithmetic 290590075Sobrien;; :: 290690075Sobrien;; :::::::::::::::::::: 290790075Sobrien 290890075Sobrien(define_insn "addsf3" 290990075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 291090075Sobrien (plus:SF (match_operand:SF 1 "fr_register_operand" "%f") 291190075Sobrien (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))] 291290075Sobrien "" 291390075Sobrien "fadd.s %0 = %1, %F2" 291490075Sobrien [(set_attr "itanium_class" "fmac")]) 291590075Sobrien 291690075Sobrien(define_insn "subsf3" 291790075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 291890075Sobrien (minus:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG") 291990075Sobrien (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))] 292090075Sobrien "" 292190075Sobrien "fsub.s %0 = %F1, %F2" 292290075Sobrien [(set_attr "itanium_class" "fmac")]) 292390075Sobrien 292490075Sobrien(define_insn "mulsf3" 292590075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 292690075Sobrien (mult:SF (match_operand:SF 1 "fr_register_operand" "%f") 292790075Sobrien (match_operand:SF 2 "fr_register_operand" "f")))] 292890075Sobrien "" 292990075Sobrien "fmpy.s %0 = %1, %2" 293090075Sobrien [(set_attr "itanium_class" "fmac")]) 293190075Sobrien 293290075Sobrien(define_insn "abssf2" 293390075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 293490075Sobrien (abs:SF (match_operand:SF 1 "fr_register_operand" "f")))] 293590075Sobrien "" 293690075Sobrien "fabs %0 = %1" 293790075Sobrien [(set_attr "itanium_class" "fmisc")]) 293890075Sobrien 293990075Sobrien(define_insn "negsf2" 294090075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 294190075Sobrien (neg:SF (match_operand:SF 1 "fr_register_operand" "f")))] 294290075Sobrien "" 294390075Sobrien "fneg %0 = %1" 294490075Sobrien [(set_attr "itanium_class" "fmisc")]) 294590075Sobrien 294690075Sobrien(define_insn "*nabssf2" 294790075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 294890075Sobrien (neg:SF (abs:SF (match_operand:SF 1 "fr_register_operand" "f"))))] 294990075Sobrien "" 295090075Sobrien "fnegabs %0 = %1" 295190075Sobrien [(set_attr "itanium_class" "fmisc")]) 295290075Sobrien 2953169689Skan(define_insn "copysignsf3" 2954169689Skan [(set (match_operand:SF 0 "register_operand" "=f") 2955169689Skan (unspec:SF [(match_operand:SF 1 "fr_reg_or_fp01_operand" "fG") 2956169689Skan (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")] 2957169689Skan UNSPEC_COPYSIGN))] 2958169689Skan "" 2959169689Skan "fmerge.s %0 = %F2, %F1" 2960169689Skan [(set_attr "itanium_class" "fmisc")]) 2961169689Skan 2962169689Skan(define_insn "*ncopysignsf3" 2963169689Skan [(set (match_operand:SF 0 "register_operand" "=f") 2964169689Skan (neg:SF (unspec:SF [(match_operand:SF 1 "fr_reg_or_fp01_operand" "fG") 2965169689Skan (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")] 2966169689Skan UNSPEC_COPYSIGN)))] 2967169689Skan "" 2968169689Skan "fmerge.ns %0 = %F2, %F1" 2969169689Skan [(set_attr "itanium_class" "fmisc")]) 2970169689Skan 2971169689Skan(define_insn "sminsf3" 297290075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 297390075Sobrien (smin:SF (match_operand:SF 1 "fr_register_operand" "f") 297490075Sobrien (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))] 297590075Sobrien "" 297690075Sobrien "fmin %0 = %1, %F2" 297790075Sobrien [(set_attr "itanium_class" "fmisc")]) 297890075Sobrien 2979169689Skan(define_insn "smaxsf3" 298090075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 298190075Sobrien (smax:SF (match_operand:SF 1 "fr_register_operand" "f") 298290075Sobrien (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))] 298390075Sobrien "" 298490075Sobrien "fmax %0 = %1, %F2" 298590075Sobrien [(set_attr "itanium_class" "fmisc")]) 298690075Sobrien 298790075Sobrien(define_insn "*maddsf4" 298890075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 298990075Sobrien (plus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f") 299090075Sobrien (match_operand:SF 2 "fr_register_operand" "f")) 299190075Sobrien (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))] 299290075Sobrien "" 299390075Sobrien "fma.s %0 = %1, %2, %F3" 299490075Sobrien [(set_attr "itanium_class" "fmac")]) 299590075Sobrien 299690075Sobrien(define_insn "*msubsf4" 299790075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 299890075Sobrien (minus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f") 299990075Sobrien (match_operand:SF 2 "fr_register_operand" "f")) 300090075Sobrien (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))] 300190075Sobrien "" 300290075Sobrien "fms.s %0 = %1, %2, %F3" 300390075Sobrien [(set_attr "itanium_class" "fmac")]) 300490075Sobrien 300590075Sobrien(define_insn "*nmulsf3" 300690075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 300790075Sobrien (neg:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f") 300890075Sobrien (match_operand:SF 2 "fr_register_operand" "f"))))] 300990075Sobrien "" 301090075Sobrien "fnmpy.s %0 = %1, %2" 301190075Sobrien [(set_attr "itanium_class" "fmac")]) 301290075Sobrien 301390075Sobrien(define_insn "*nmaddsf4" 301490075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 3015169689Skan (minus:SF (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG") 3016169689Skan (mult:SF (match_operand:SF 1 "fr_register_operand" "f") 3017169689Skan (match_operand:SF 2 "fr_register_operand" "f"))))] 301890075Sobrien "" 301990075Sobrien "fnma.s %0 = %1, %2, %F3" 302090075Sobrien [(set_attr "itanium_class" "fmac")]) 302190075Sobrien 3022169689Skan(define_insn "*nmaddsf4_alts" 3023169689Skan [(set (match_operand:SF 0 "fr_register_operand" "=f") 3024169689Skan (minus:SF (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG") 3025169689Skan (mult:SF (match_operand:SF 1 "fr_register_operand" "f") 3026169689Skan (match_operand:SF 2 "fr_register_operand" "f")))) 3027169689Skan (use (match_operand:SI 4 "const_int_operand" ""))] 3028169689Skan "" 3029169689Skan "fnma.s.s%4 %0 = %1, %2, %F3" 3030169689Skan [(set_attr "itanium_class" "fmac")]) 3031169689Skan 303290075Sobrien(define_expand "divsf3" 303390075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "") 303490075Sobrien (div:SF (match_operand:SF 1 "fr_register_operand" "") 303590075Sobrien (match_operand:SF 2 "fr_register_operand" "")))] 3036132718Skan "TARGET_INLINE_FLOAT_DIV" 303790075Sobrien{ 303890075Sobrien rtx insn; 3039169689Skan if (TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT) 304090075Sobrien insn = gen_divsf3_internal_lat (operands[0], operands[1], operands[2]); 304190075Sobrien else 304290075Sobrien insn = gen_divsf3_internal_thr (operands[0], operands[1], operands[2]); 304390075Sobrien emit_insn (insn); 304490075Sobrien DONE; 3045117395Skan}) 304690075Sobrien 304790075Sobrien(define_insn_and_split "divsf3_internal_lat" 304890075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=&f") 304990075Sobrien (div:SF (match_operand:SF 1 "fr_register_operand" "f") 305090075Sobrien (match_operand:SF 2 "fr_register_operand" "f"))) 3051132718Skan (clobber (match_scratch:XF 3 "=&f")) 3052132718Skan (clobber (match_scratch:XF 4 "=f")) 305390075Sobrien (clobber (match_scratch:BI 5 "=c"))] 3054169689Skan "TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT" 305590075Sobrien "#" 305690075Sobrien "&& reload_completed" 3057132718Skan [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8))) 3058117395Skan (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)] 3059117395Skan UNSPEC_FR_RECIP_APPROX)) 3060169689Skan (use (const_int 0))]) 306190075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 3062132718Skan (parallel [(set (match_dup 3) (mult:XF (match_dup 7) (match_dup 6))) 306390075Sobrien (use (const_int 1))])) 306490075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 306590075Sobrien (parallel [(set (match_dup 4) 3066169689Skan (minus:XF (match_dup 10) 3067169689Skan (mult:XF (match_dup 8) (match_dup 6)))) 306890075Sobrien (use (const_int 1))])) 306990075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 307090075Sobrien (parallel [(set (match_dup 3) 3071132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 3)) 307290075Sobrien (match_dup 3))) 307390075Sobrien (use (const_int 1))])) 307490075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 3075132718Skan (parallel [(set (match_dup 4) (mult:XF (match_dup 4) (match_dup 4))) 307690075Sobrien (use (const_int 1))])) 307790075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 307890075Sobrien (parallel [(set (match_dup 3) 3079132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 3)) 308090075Sobrien (match_dup 3))) 308190075Sobrien (use (const_int 1))])) 308290075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 3083132718Skan (parallel [(set (match_dup 4) (mult:XF (match_dup 4) (match_dup 4))) 308490075Sobrien (use (const_int 1))])) 308590075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 308690075Sobrien (parallel [(set (match_dup 9) 308790075Sobrien (float_truncate:DF 3088132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 3)) 308990075Sobrien (match_dup 3)))) 309090075Sobrien (use (const_int 1))])) 309190075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 309290075Sobrien (set (match_dup 0) 309390075Sobrien (float_truncate:SF (match_dup 6)))) 309490075Sobrien ] 3095117395Skan{ 3096132718Skan operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0])); 3097132718Skan operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1])); 3098132718Skan operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2])); 3099117395Skan operands[9] = gen_rtx_REG (DFmode, REGNO (operands[0])); 3100132718Skan operands[10] = CONST1_RTX (XFmode); 3101117395Skan} 310290075Sobrien [(set_attr "predicable" "no")]) 310390075Sobrien 310490075Sobrien(define_insn_and_split "divsf3_internal_thr" 310590075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=&f") 310690075Sobrien (div:SF (match_operand:SF 1 "fr_register_operand" "f") 310790075Sobrien (match_operand:SF 2 "fr_register_operand" "f"))) 3108132718Skan (clobber (match_scratch:XF 3 "=&f")) 3109132718Skan (clobber (match_scratch:XF 4 "=f")) 311090075Sobrien (clobber (match_scratch:BI 5 "=c"))] 3111169689Skan "TARGET_INLINE_FLOAT_DIV == INL_MAX_THR" 311290075Sobrien "#" 311390075Sobrien "&& reload_completed" 3114132718Skan [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8))) 3115117395Skan (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)] 3116117395Skan UNSPEC_FR_RECIP_APPROX)) 3117169689Skan (use (const_int 0))]) 311890075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 311990075Sobrien (parallel [(set (match_dup 3) 3120169689Skan (minus:XF (match_dup 10) 3121169689Skan (mult:XF (match_dup 8) (match_dup 6)))) 312290075Sobrien (use (const_int 1))])) 312390075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 312490075Sobrien (parallel [(set (match_dup 3) 3125132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 3)) 312690075Sobrien (match_dup 3))) 312790075Sobrien (use (const_int 1))])) 312890075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 312990075Sobrien (parallel [(set (match_dup 6) 3130132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 6)) 313190075Sobrien (match_dup 6))) 313290075Sobrien (use (const_int 1))])) 313390075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 313490075Sobrien (parallel [(set (match_dup 9) 313590075Sobrien (float_truncate:SF 3136132718Skan (mult:XF (match_dup 7) (match_dup 6)))) 313790075Sobrien (use (const_int 1))])) 313890075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 313990075Sobrien (parallel [(set (match_dup 4) 3140169689Skan (minus:XF (match_dup 7) 3141169689Skan (mult:XF (match_dup 8) (match_dup 3)))) 314290075Sobrien (use (const_int 1))])) 314390075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 314490075Sobrien (set (match_dup 0) 314590075Sobrien (float_truncate:SF 3146132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 6)) 314790075Sobrien (match_dup 3))))) 314890075Sobrien ] 3149117395Skan{ 3150132718Skan operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0])); 3151132718Skan operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1])); 3152132718Skan operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2])); 3153117395Skan operands[9] = gen_rtx_REG (SFmode, REGNO (operands[3])); 3154132718Skan operands[10] = CONST1_RTX (XFmode); 3155117395Skan} 315690075Sobrien [(set_attr "predicable" "no")]) 3157132718Skan 3158132718Skan;; Inline square root. 3159132718Skan 3160132718Skan(define_insn "*sqrt_approx" 3161132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3162132718Skan (div:XF (const_int 1) 3163132718Skan (sqrt:XF (match_operand:XF 2 "fr_register_operand" "f")))) 3164132718Skan (set (match_operand:BI 1 "register_operand" "=c") 3165132718Skan (unspec:BI [(match_dup 2)] UNSPEC_FR_SQRT_RECIP_APPROX)) 3166132718Skan (use (match_operand:SI 3 "const_int_operand" "")) ] 3167132718Skan "" 3168132718Skan "frsqrta.s%3 %0, %1 = %2" 3169132718Skan [(set_attr "itanium_class" "fmisc") 3170132718Skan (set_attr "predicable" "no")]) 3171132718Skan 3172169689Skan(define_insn "setf_exp_xf" 3173132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3174132718Skan (unspec:XF [(match_operand:DI 1 "register_operand" "r")] 3175132718Skan UNSPEC_SETF_EXP))] 3176132718Skan "" 3177132718Skan "setf.exp %0 = %1" 3178132718Skan [(set_attr "itanium_class" "frfr")]) 3179132718Skan 3180132718Skan(define_expand "sqrtsf2" 3181132718Skan [(set (match_operand:SF 0 "fr_register_operand" "=&f") 3182132718Skan (sqrt:SF (match_operand:SF 1 "fr_register_operand" "f")))] 3183132718Skan "TARGET_INLINE_SQRT" 3184132718Skan{ 3185132718Skan rtx insn; 3186132718Skan#if 0 3187169689Skan if (TARGET_INLINE_SQRT == INL_MIN_LAT) 3188132718Skan insn = gen_sqrtsf2_internal_lat (operands[0], operands[1]); 3189169689Skan else 3190132718Skan#else 3191169689Skan gcc_assert (TARGET_INLINE_SQRT != INL_MIN_LAT); 3192132718Skan#endif 3193169689Skan insn = gen_sqrtsf2_internal_thr (operands[0], operands[1]); 3194132718Skan emit_insn (insn); 3195132718Skan DONE; 3196132718Skan}) 3197132718Skan 3198132718Skan;; Latency-optimized square root. 3199132718Skan;; FIXME: Implement. 3200132718Skan 3201132718Skan;; Throughput-optimized square root. 3202132718Skan 3203132718Skan(define_insn_and_split "sqrtsf2_internal_thr" 3204132718Skan [(set (match_operand:SF 0 "fr_register_operand" "=&f") 3205132718Skan (sqrt:SF (match_operand:SF 1 "fr_register_operand" "f"))) 3206132718Skan ;; Register r2 in optimization guide. 3207132718Skan (clobber (match_scratch:DI 2 "=r")) 3208132718Skan ;; Register f8 in optimization guide 3209132718Skan (clobber (match_scratch:XF 3 "=&f")) 3210132718Skan ;; Register f9 in optimization guide 3211132718Skan (clobber (match_scratch:XF 4 "=&f")) 3212132718Skan ;; Register f10 in optimization guide 3213132718Skan (clobber (match_scratch:XF 5 "=&f")) 3214132718Skan ;; Register p6 in optimization guide. 3215132718Skan (clobber (match_scratch:BI 6 "=c"))] 3216169689Skan "TARGET_INLINE_SQRT == INL_MAX_THR" 3217132718Skan "#" 3218132718Skan "&& reload_completed" 3219132718Skan [ ;; exponent of +1/2 in r2 3220132718Skan (set (match_dup 2) (const_int 65534)) 3221132718Skan ;; +1/2 in f8 3222132718Skan (set (match_dup 3) 3223132718Skan (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP)) 3224132718Skan ;; Step 1 3225132718Skan ;; y0 = 1/sqrt(a) in f7 3226132718Skan (parallel [(set (match_dup 7) 3227132718Skan (div:XF (const_int 1) 3228132718Skan (sqrt:XF (match_dup 8)))) 3229132718Skan (set (match_dup 6) 3230132718Skan (unspec:BI [(match_dup 8)] 3231132718Skan UNSPEC_FR_SQRT_RECIP_APPROX)) 3232132718Skan (use (const_int 0))]) 3233132718Skan ;; Step 2 3234132718Skan ;; H0 = 1/2 * y0 in f9 3235132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3236132718Skan (parallel [(set (match_dup 4) 3237132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 7)) 3238132718Skan (match_dup 9))) 3239132718Skan (use (const_int 1))])) 3240132718Skan ;; Step 3 3241132718Skan ;; S0 = a * y0 in f7 3242132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3243132718Skan (parallel [(set (match_dup 7) 3244132718Skan (plus:XF (mult:XF (match_dup 8) (match_dup 7)) 3245132718Skan (match_dup 9))) 3246132718Skan (use (const_int 1))])) 3247132718Skan ;; Step 4 3248132718Skan ;; d = 1/2 - S0 * H0 in f10 3249132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3250132718Skan (parallel [(set (match_dup 5) 3251169689Skan (minus:XF (match_dup 3) 3252169689Skan (mult:XF (match_dup 7) (match_dup 4)))) 3253132718Skan (use (const_int 1))])) 3254132718Skan ;; Step 5 3255132718Skan ;; d' = d + 1/2 * d in f8 3256132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3257132718Skan (parallel [(set (match_dup 3) 3258132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 5)) 3259132718Skan (match_dup 5))) 3260132718Skan (use (const_int 1))])) 3261132718Skan ;; Step 6 3262132718Skan ;; e = d + d * d' in f8 3263132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3264132718Skan (parallel [(set (match_dup 3) 3265132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 3)) 3266132718Skan (match_dup 5))) 3267132718Skan (use (const_int 1))])) 3268132718Skan ;; Step 7 3269132718Skan ;; S1 = S0 + e * S0 in f7 3270132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3271132718Skan (parallel [(set (match_dup 0) 3272132718Skan (float_truncate:SF 3273132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 7)) 3274132718Skan (match_dup 7)))) 3275132718Skan (use (const_int 1))])) 3276132718Skan ;; Step 8 3277132718Skan ;; H1 = H0 + e * H0 in f8 3278132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3279132718Skan (parallel [(set (match_dup 3) 3280132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 4)) 3281132718Skan (match_dup 4))) 3282132718Skan (use (const_int 1))])) 3283132718Skan ;; Step 9 3284132718Skan ;; d1 = a - S1 * S1 in f9 3285132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3286132718Skan (parallel [(set (match_dup 4) 3287169689Skan (minus:XF (match_dup 8) 3288169689Skan (mult:XF (match_dup 7) (match_dup 7)))) 3289132718Skan (use (const_int 1))])) 3290132718Skan ;; Step 10 3291132718Skan ;; S = S1 + d1 * H1 in f7 3292132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3293132718Skan (parallel [(set (match_dup 0) 3294132718Skan (float_truncate:SF 3295132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 3)) 3296132718Skan (match_dup 7)))) 3297132718Skan (use (const_int 0))]))] 3298132718Skan{ 3299132718Skan /* Generate 82-bit versions of the input and output operands. */ 3300132718Skan operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0])); 3301132718Skan operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1])); 3302132718Skan /* Generate required floating-point constants. */ 3303132718Skan operands[9] = CONST0_RTX (XFmode); 3304132718Skan} 3305132718Skan [(set_attr "predicable" "no")]) 330690075Sobrien 330790075Sobrien;; :::::::::::::::::::: 330890075Sobrien;; :: 330990075Sobrien;; :: 64 bit floating point arithmetic 331090075Sobrien;; :: 331190075Sobrien;; :::::::::::::::::::: 331290075Sobrien 331390075Sobrien(define_insn "adddf3" 331490075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 331590075Sobrien (plus:DF (match_operand:DF 1 "fr_register_operand" "%f") 331690075Sobrien (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))] 331790075Sobrien "" 331890075Sobrien "fadd.d %0 = %1, %F2" 331990075Sobrien [(set_attr "itanium_class" "fmac")]) 332090075Sobrien 332190075Sobrien(define_insn "*adddf3_trunc" 332290075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 332390075Sobrien (float_truncate:SF 332490075Sobrien (plus:DF (match_operand:DF 1 "fr_register_operand" "%f") 332590075Sobrien (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))] 332690075Sobrien "" 332790075Sobrien "fadd.s %0 = %1, %F2" 332890075Sobrien [(set_attr "itanium_class" "fmac")]) 332990075Sobrien 333090075Sobrien(define_insn "subdf3" 333190075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 333290075Sobrien (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG") 333390075Sobrien (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))] 333490075Sobrien "" 333590075Sobrien "fsub.d %0 = %F1, %F2" 333690075Sobrien [(set_attr "itanium_class" "fmac")]) 333790075Sobrien 333890075Sobrien(define_insn "*subdf3_trunc" 333990075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 334090075Sobrien (float_truncate:SF 334190075Sobrien (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG") 334290075Sobrien (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))] 334390075Sobrien "" 334490075Sobrien "fsub.s %0 = %F1, %F2" 334590075Sobrien [(set_attr "itanium_class" "fmac")]) 334690075Sobrien 334790075Sobrien(define_insn "muldf3" 334890075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 334990075Sobrien (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 335090075Sobrien (match_operand:DF 2 "fr_register_operand" "f")))] 335190075Sobrien "" 335290075Sobrien "fmpy.d %0 = %1, %2" 335390075Sobrien [(set_attr "itanium_class" "fmac")]) 335490075Sobrien 335590075Sobrien(define_insn "*muldf3_trunc" 335690075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 335790075Sobrien (float_truncate:SF 335890075Sobrien (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 335990075Sobrien (match_operand:DF 2 "fr_register_operand" "f"))))] 336090075Sobrien "" 336190075Sobrien "fmpy.s %0 = %1, %2" 336290075Sobrien [(set_attr "itanium_class" "fmac")]) 336390075Sobrien 336490075Sobrien(define_insn "absdf2" 336590075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 336690075Sobrien (abs:DF (match_operand:DF 1 "fr_register_operand" "f")))] 336790075Sobrien "" 336890075Sobrien "fabs %0 = %1" 336990075Sobrien [(set_attr "itanium_class" "fmisc")]) 337090075Sobrien 337190075Sobrien(define_insn "negdf2" 337290075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 337390075Sobrien (neg:DF (match_operand:DF 1 "fr_register_operand" "f")))] 337490075Sobrien "" 337590075Sobrien "fneg %0 = %1" 337690075Sobrien [(set_attr "itanium_class" "fmisc")]) 337790075Sobrien 337890075Sobrien(define_insn "*nabsdf2" 337990075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 338090075Sobrien (neg:DF (abs:DF (match_operand:DF 1 "fr_register_operand" "f"))))] 338190075Sobrien "" 338290075Sobrien "fnegabs %0 = %1" 338390075Sobrien [(set_attr "itanium_class" "fmisc")]) 338490075Sobrien 3385169689Skan(define_insn "copysigndf3" 3386169689Skan [(set (match_operand:DF 0 "register_operand" "=f") 3387169689Skan (unspec:DF [(match_operand:DF 1 "fr_reg_or_fp01_operand" "fG") 3388169689Skan (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")] 3389169689Skan UNSPEC_COPYSIGN))] 3390169689Skan "" 3391169689Skan "fmerge.s %0 = %F2, %F1" 3392169689Skan [(set_attr "itanium_class" "fmisc")]) 3393169689Skan 3394169689Skan(define_insn "*ncopysigndf3" 3395169689Skan [(set (match_operand:DF 0 "register_operand" "=f") 3396169689Skan (neg:DF (unspec:DF [(match_operand:DF 1 "fr_reg_or_fp01_operand" "fG") 3397169689Skan (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")] 3398169689Skan UNSPEC_COPYSIGN)))] 3399169689Skan "" 3400169689Skan "fmerge.ns %0 = %F2, %F1" 3401169689Skan [(set_attr "itanium_class" "fmisc")]) 3402169689Skan 3403169689Skan(define_insn "smindf3" 340490075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 340590075Sobrien (smin:DF (match_operand:DF 1 "fr_register_operand" "f") 340690075Sobrien (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))] 340790075Sobrien "" 340890075Sobrien "fmin %0 = %1, %F2" 340990075Sobrien [(set_attr "itanium_class" "fmisc")]) 341090075Sobrien 3411169689Skan(define_insn "smaxdf3" 341290075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 341390075Sobrien (smax:DF (match_operand:DF 1 "fr_register_operand" "f") 341490075Sobrien (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))] 341590075Sobrien "" 341690075Sobrien "fmax %0 = %1, %F2" 341790075Sobrien [(set_attr "itanium_class" "fmisc")]) 341890075Sobrien 341990075Sobrien(define_insn "*madddf4" 342090075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 342190075Sobrien (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 342290075Sobrien (match_operand:DF 2 "fr_register_operand" "f")) 342390075Sobrien (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))] 342490075Sobrien "" 342590075Sobrien "fma.d %0 = %1, %2, %F3" 342690075Sobrien [(set_attr "itanium_class" "fmac")]) 342790075Sobrien 342890075Sobrien(define_insn "*madddf4_trunc" 342990075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 343090075Sobrien (float_truncate:SF 343190075Sobrien (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 343290075Sobrien (match_operand:DF 2 "fr_register_operand" "f")) 343390075Sobrien (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))] 343490075Sobrien "" 343590075Sobrien "fma.s %0 = %1, %2, %F3" 343690075Sobrien [(set_attr "itanium_class" "fmac")]) 343790075Sobrien 343890075Sobrien(define_insn "*msubdf4" 343990075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 344090075Sobrien (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 344190075Sobrien (match_operand:DF 2 "fr_register_operand" "f")) 344290075Sobrien (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))] 344390075Sobrien "" 344490075Sobrien "fms.d %0 = %1, %2, %F3" 344590075Sobrien [(set_attr "itanium_class" "fmac")]) 344690075Sobrien 344790075Sobrien(define_insn "*msubdf4_trunc" 344890075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 344990075Sobrien (float_truncate:SF 345090075Sobrien (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 345190075Sobrien (match_operand:DF 2 "fr_register_operand" "f")) 345290075Sobrien (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))] 345390075Sobrien "" 345490075Sobrien "fms.s %0 = %1, %2, %F3" 345590075Sobrien [(set_attr "itanium_class" "fmac")]) 345690075Sobrien 345790075Sobrien(define_insn "*nmuldf3" 345890075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 345990075Sobrien (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 346090075Sobrien (match_operand:DF 2 "fr_register_operand" "f"))))] 346190075Sobrien "" 346290075Sobrien "fnmpy.d %0 = %1, %2" 346390075Sobrien [(set_attr "itanium_class" "fmac")]) 346490075Sobrien 346590075Sobrien(define_insn "*nmuldf3_trunc" 346690075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 346790075Sobrien (float_truncate:SF 346890075Sobrien (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 346990075Sobrien (match_operand:DF 2 "fr_register_operand" "f")))))] 347090075Sobrien "" 347190075Sobrien "fnmpy.s %0 = %1, %2" 347290075Sobrien [(set_attr "itanium_class" "fmac")]) 347390075Sobrien 347490075Sobrien(define_insn "*nmadddf4" 347590075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 3476169689Skan (minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG") 3477169689Skan (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 3478169689Skan (match_operand:DF 2 "fr_register_operand" "f"))))] 347990075Sobrien "" 348090075Sobrien "fnma.d %0 = %1, %2, %F3" 348190075Sobrien [(set_attr "itanium_class" "fmac")]) 348290075Sobrien 348390075Sobrien(define_insn "*nmadddf4_alts" 348490075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 3485169689Skan (minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG") 3486169689Skan (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 3487169689Skan (match_operand:DF 2 "fr_register_operand" "f")))) 348890075Sobrien (use (match_operand:SI 4 "const_int_operand" ""))] 348990075Sobrien "" 349090075Sobrien "fnma.d.s%4 %0 = %1, %2, %F3" 349190075Sobrien [(set_attr "itanium_class" "fmac")]) 349290075Sobrien 3493169689Skan(define_insn "*nmadddf4_truncsf" 349490075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 349590075Sobrien (float_truncate:SF 3496169689Skan (minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG") 3497169689Skan (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 3498169689Skan (match_operand:DF 2 "fr_register_operand" "f")))))] 349990075Sobrien "" 350090075Sobrien "fnma.s %0 = %1, %2, %F3" 350190075Sobrien [(set_attr "itanium_class" "fmac")]) 350290075Sobrien 3503169689Skan(define_insn "*nmadddf4_truncsf_alts" 3504169689Skan [(set (match_operand:SF 0 "fr_register_operand" "=f") 3505169689Skan (float_truncate:SF 3506169689Skan (minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG") 3507169689Skan (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 3508169689Skan (match_operand:DF 2 "fr_register_operand" "f"))))) 3509169689Skan (use (match_operand:SI 4 "const_int_operand" ""))] 3510169689Skan "" 3511169689Skan "fnma.s.s%4 %0 = %1, %2, %F3" 3512169689Skan [(set_attr "itanium_class" "fmac")]) 3513169689Skan 351490075Sobrien(define_expand "divdf3" 351590075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "") 351690075Sobrien (div:DF (match_operand:DF 1 "fr_register_operand" "") 351790075Sobrien (match_operand:DF 2 "fr_register_operand" "")))] 3518132718Skan "TARGET_INLINE_FLOAT_DIV" 351990075Sobrien{ 352090075Sobrien rtx insn; 3521169689Skan if (TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT) 352290075Sobrien insn = gen_divdf3_internal_lat (operands[0], operands[1], operands[2]); 352390075Sobrien else 352490075Sobrien insn = gen_divdf3_internal_thr (operands[0], operands[1], operands[2]); 352590075Sobrien emit_insn (insn); 352690075Sobrien DONE; 3527117395Skan}) 352890075Sobrien 352990075Sobrien(define_insn_and_split "divdf3_internal_lat" 353090075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=&f") 353190075Sobrien (div:DF (match_operand:DF 1 "fr_register_operand" "f") 353290075Sobrien (match_operand:DF 2 "fr_register_operand" "f"))) 3533132718Skan (clobber (match_scratch:XF 3 "=&f")) 3534132718Skan (clobber (match_scratch:XF 4 "=&f")) 3535132718Skan (clobber (match_scratch:XF 5 "=&f")) 353690075Sobrien (clobber (match_scratch:BI 6 "=c"))] 3537169689Skan "TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT" 353890075Sobrien "#" 353990075Sobrien "&& reload_completed" 3540132718Skan [(parallel [(set (match_dup 7) (div:XF (const_int 1) (match_dup 9))) 3541117395Skan (set (match_dup 6) (unspec:BI [(match_dup 8) (match_dup 9)] 3542117395Skan UNSPEC_FR_RECIP_APPROX)) 3543169689Skan (use (const_int 0))]) 354490075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 3545132718Skan (parallel [(set (match_dup 3) (mult:XF (match_dup 8) (match_dup 7))) 354690075Sobrien (use (const_int 1))])) 354790075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 354890075Sobrien (parallel [(set (match_dup 4) 3549169689Skan (minus:XF (match_dup 12) 3550169689Skan (mult:XF (match_dup 9) (match_dup 7)))) 355190075Sobrien (use (const_int 1))])) 355290075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 355390075Sobrien (parallel [(set (match_dup 3) 3554132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 3)) 355590075Sobrien (match_dup 3))) 355690075Sobrien (use (const_int 1))])) 355790075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 3558132718Skan (parallel [(set (match_dup 5) (mult:XF (match_dup 4) (match_dup 4))) 355990075Sobrien (use (const_int 1))])) 356090075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 356190075Sobrien (parallel [(set (match_dup 7) 3562132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 7)) 356390075Sobrien (match_dup 7))) 356490075Sobrien (use (const_int 1))])) 356590075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 356690075Sobrien (parallel [(set (match_dup 3) 3567132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 3)) 356890075Sobrien (match_dup 3))) 356990075Sobrien (use (const_int 1))])) 357090075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 3571132718Skan (parallel [(set (match_dup 4) (mult:XF (match_dup 5) (match_dup 5))) 357290075Sobrien (use (const_int 1))])) 357390075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 357490075Sobrien (parallel [(set (match_dup 7) 3575132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 7)) 357690075Sobrien (match_dup 7))) 357790075Sobrien (use (const_int 1))])) 357890075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 357990075Sobrien (parallel [(set (match_dup 10) 358090075Sobrien (float_truncate:DF 3581132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 3)) 358290075Sobrien (match_dup 3)))) 358390075Sobrien (use (const_int 1))])) 358490075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 358590075Sobrien (parallel [(set (match_dup 7) 3586132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 7)) 358790075Sobrien (match_dup 7))) 358890075Sobrien (use (const_int 1))])) 358990075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 359090075Sobrien (parallel [(set (match_dup 11) 359190075Sobrien (float_truncate:DF 3592169689Skan (minus:XF (match_dup 8) 3593169689Skan (mult:XF (match_dup 9) (match_dup 3))))) 359490075Sobrien (use (const_int 1))])) 359590075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 359690075Sobrien (set (match_dup 0) 3597132718Skan (float_truncate:DF (plus:XF (mult:XF (match_dup 5) (match_dup 7)) 359890075Sobrien (match_dup 3))))) 359990075Sobrien ] 3600117395Skan{ 3601132718Skan operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0])); 3602132718Skan operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1])); 3603132718Skan operands[9] = gen_rtx_REG (XFmode, REGNO (operands[2])); 3604117395Skan operands[10] = gen_rtx_REG (DFmode, REGNO (operands[3])); 3605117395Skan operands[11] = gen_rtx_REG (DFmode, REGNO (operands[5])); 3606132718Skan operands[12] = CONST1_RTX (XFmode); 3607117395Skan} 360890075Sobrien [(set_attr "predicable" "no")]) 360990075Sobrien 361090075Sobrien(define_insn_and_split "divdf3_internal_thr" 361190075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=&f") 361290075Sobrien (div:DF (match_operand:DF 1 "fr_register_operand" "f") 361390075Sobrien (match_operand:DF 2 "fr_register_operand" "f"))) 3614132718Skan (clobber (match_scratch:XF 3 "=&f")) 361590075Sobrien (clobber (match_scratch:DF 4 "=f")) 361690075Sobrien (clobber (match_scratch:BI 5 "=c"))] 3617169689Skan "TARGET_INLINE_FLOAT_DIV == INL_MAX_THR" 361890075Sobrien "#" 361990075Sobrien "&& reload_completed" 3620132718Skan [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8))) 3621117395Skan (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)] 3622117395Skan UNSPEC_FR_RECIP_APPROX)) 3623169689Skan (use (const_int 0))]) 362490075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 362590075Sobrien (parallel [(set (match_dup 3) 3626169689Skan (minus:XF (match_dup 10) 3627169689Skan (mult:XF (match_dup 8) (match_dup 6)))) 362890075Sobrien (use (const_int 1))])) 362990075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 363090075Sobrien (parallel [(set (match_dup 6) 3631132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 6)) 363290075Sobrien (match_dup 6))) 363390075Sobrien (use (const_int 1))])) 363490075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 363590075Sobrien (parallel [(set (match_dup 3) 3636132718Skan (mult:XF (match_dup 3) (match_dup 3))) 363790075Sobrien (use (const_int 1))])) 363890075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 363990075Sobrien (parallel [(set (match_dup 6) 3640132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 6)) 364190075Sobrien (match_dup 6))) 364290075Sobrien (use (const_int 1))])) 364390075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 364490075Sobrien (parallel [(set (match_dup 3) 3645132718Skan (mult:XF (match_dup 3) (match_dup 3))) 364690075Sobrien (use (const_int 1))])) 364790075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 364890075Sobrien (parallel [(set (match_dup 6) 3649132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 6)) 365090075Sobrien (match_dup 6))) 365190075Sobrien (use (const_int 1))])) 365290075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 365390075Sobrien (parallel [(set (match_dup 9) 365490075Sobrien (float_truncate:DF 3655169689Skan (mult:XF (match_dup 7) (match_dup 6)))) 365690075Sobrien (use (const_int 1))])) 365790075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 365890075Sobrien (parallel [(set (match_dup 4) 3659169689Skan (minus:DF (match_dup 1) 3660169689Skan (mult:DF (match_dup 2) (match_dup 9)))) 366190075Sobrien (use (const_int 1))])) 366290075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 366390075Sobrien (set (match_dup 0) 366490075Sobrien (plus:DF (mult:DF (match_dup 4) (match_dup 0)) 366590075Sobrien (match_dup 9)))) 366690075Sobrien ] 3667117395Skan{ 3668132718Skan operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0])); 3669132718Skan operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1])); 3670132718Skan operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2])); 3671117395Skan operands[9] = gen_rtx_REG (DFmode, REGNO (operands[3])); 3672132718Skan operands[10] = CONST1_RTX (XFmode); 3673117395Skan} 367490075Sobrien [(set_attr "predicable" "no")]) 3675132718Skan 3676132718Skan;; Inline square root. 3677132718Skan 3678132718Skan(define_expand "sqrtdf2" 3679132718Skan [(set (match_operand:DF 0 "fr_register_operand" "=&f") 3680132718Skan (sqrt:DF (match_operand:DF 1 "fr_register_operand" "f")))] 3681132718Skan "TARGET_INLINE_SQRT" 3682132718Skan{ 3683132718Skan rtx insn; 3684132718Skan#if 0 3685169689Skan if (TARGET_INLINE_SQRT == INL_MIN_LAT) 3686132718Skan insn = gen_sqrtdf2_internal_lat (operands[0], operands[1]); 3687169689Skan else 3688132718Skan#else 3689169689Skan gcc_assert (TARGET_INLINE_SQRT != INL_MIN_LAT); 3690132718Skan#endif 3691169689Skan insn = gen_sqrtdf2_internal_thr (operands[0], operands[1]); 3692132718Skan emit_insn (insn); 3693132718Skan DONE; 3694132718Skan}) 3695132718Skan 3696132718Skan;; Latency-optimized square root. 3697132718Skan;; FIXME: Implement. 3698132718Skan 3699132718Skan;; Throughput-optimized square root. 3700132718Skan 3701132718Skan(define_insn_and_split "sqrtdf2_internal_thr" 3702132718Skan [(set (match_operand:DF 0 "fr_register_operand" "=&f") 3703132718Skan (sqrt:DF (match_operand:DF 1 "fr_register_operand" "f"))) 3704132718Skan ;; Register r2 in optimization guide. 3705132718Skan (clobber (match_scratch:DI 2 "=r")) 3706132718Skan ;; Register f8 in optimization guide 3707132718Skan (clobber (match_scratch:XF 3 "=&f")) 3708132718Skan ;; Register f9 in optimization guide 3709132718Skan (clobber (match_scratch:XF 4 "=&f")) 3710132718Skan ;; Register f10 in optimization guide 3711132718Skan (clobber (match_scratch:XF 5 "=&f")) 3712132718Skan ;; Register p6 in optimization guide. 3713132718Skan (clobber (match_scratch:BI 6 "=c"))] 3714169689Skan "TARGET_INLINE_SQRT == INL_MAX_THR" 3715132718Skan "#" 3716132718Skan "&& reload_completed" 3717132718Skan [ ;; exponent of +1/2 in r2 3718132718Skan (set (match_dup 2) (const_int 65534)) 3719132718Skan ;; +1/2 in f10 3720132718Skan (set (match_dup 5) 3721132718Skan (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP)) 3722132718Skan ;; Step 1 3723132718Skan ;; y0 = 1/sqrt(a) in f7 3724132718Skan (parallel [(set (match_dup 7) 3725132718Skan (div:XF (const_int 1) 3726132718Skan (sqrt:XF (match_dup 8)))) 3727132718Skan (set (match_dup 6) 3728132718Skan (unspec:BI [(match_dup 8)] 3729132718Skan UNSPEC_FR_SQRT_RECIP_APPROX)) 3730132718Skan (use (const_int 0))]) 3731132718Skan ;; Step 2 3732132718Skan ;; H0 = 1/2 * y0 in f8 3733132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3734132718Skan (parallel [(set (match_dup 3) 3735132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 7)) 3736132718Skan (match_dup 9))) 3737132718Skan (use (const_int 1))])) 3738132718Skan ;; Step 3 3739132718Skan ;; G0 = a * y0 in f7 3740132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3741132718Skan (parallel [(set (match_dup 7) 3742132718Skan (plus:XF (mult:XF (match_dup 8) (match_dup 7)) 3743132718Skan (match_dup 9))) 3744132718Skan (use (const_int 1))])) 3745132718Skan ;; Step 4 3746132718Skan ;; r0 = 1/2 - G0 * H0 in f9 3747132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3748132718Skan (parallel [(set (match_dup 4) 3749169689Skan (minus:XF (match_dup 5) 3750169689Skan (mult:XF (match_dup 7) (match_dup 3)))) 3751132718Skan (use (const_int 1))])) 3752132718Skan ;; Step 5 3753132718Skan ;; H1 = H0 + r0 * H0 in f8 3754132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3755132718Skan (parallel [(set (match_dup 3) 3756132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 3)) 3757132718Skan (match_dup 3))) 3758132718Skan (use (const_int 1))])) 3759132718Skan ;; Step 6 3760132718Skan ;; G1 = G0 + r0 * G0 in f7 3761132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3762132718Skan (parallel [(set (match_dup 7) 3763132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 7)) 3764132718Skan (match_dup 7))) 3765132718Skan (use (const_int 1))])) 3766132718Skan ;; Step 7 3767132718Skan ;; r1 = 1/2 - G1 * H1 in f9 3768132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3769132718Skan (parallel [(set (match_dup 4) 3770169689Skan (minus:XF (match_dup 5) 3771169689Skan (mult:XF (match_dup 7) (match_dup 3)))) 3772132718Skan (use (const_int 1))])) 3773132718Skan ;; Step 8 3774132718Skan ;; H2 = H1 + r1 * H1 in f8 3775132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3776132718Skan (parallel [(set (match_dup 3) 3777132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 3)) 3778132718Skan (match_dup 3))) 3779132718Skan (use (const_int 1))])) 3780132718Skan ;; Step 9 3781132718Skan ;; G2 = G1 + r1 * G1 in f7 3782132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3783132718Skan (parallel [(set (match_dup 7) 3784132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 7)) 3785132718Skan (match_dup 7))) 3786132718Skan (use (const_int 1))])) 3787132718Skan ;; Step 10 3788132718Skan ;; d2 = a - G2 * G2 in f9 3789132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3790132718Skan (parallel [(set (match_dup 4) 3791169689Skan (minus:XF (match_dup 8) 3792169689Skan (mult:XF (match_dup 7) (match_dup 7)))) 3793132718Skan (use (const_int 1))])) 3794132718Skan ;; Step 11 3795132718Skan ;; G3 = G2 + d2 * H2 in f7 3796132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3797132718Skan (parallel [(set (match_dup 7) 3798132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 3)) 3799132718Skan (match_dup 7))) 3800132718Skan (use (const_int 1))])) 3801132718Skan ;; Step 12 3802132718Skan ;; d3 = a - G3 * G3 in f9 3803132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3804132718Skan (parallel [(set (match_dup 4) 3805169689Skan (minus:XF (match_dup 8) 3806169689Skan (mult:XF (match_dup 7) (match_dup 7)))) 3807132718Skan (use (const_int 1))])) 3808132718Skan ;; Step 13 3809132718Skan ;; S = G3 + d3 * H2 in f7 3810132718Skan (cond_exec (ne (match_dup 6) (const_int 0)) 3811132718Skan (parallel [(set (match_dup 0) 3812132718Skan (float_truncate:DF 3813132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 3)) 3814132718Skan (match_dup 7)))) 3815132718Skan (use (const_int 0))]))] 3816132718Skan{ 3817132718Skan /* Generate 82-bit versions of the input and output operands. */ 3818132718Skan operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0])); 3819132718Skan operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1])); 3820132718Skan /* Generate required floating-point constants. */ 3821132718Skan operands[9] = CONST0_RTX (XFmode); 3822132718Skan} 3823132718Skan [(set_attr "predicable" "no")]) 382490075Sobrien 382590075Sobrien;; :::::::::::::::::::: 382690075Sobrien;; :: 382790075Sobrien;; :: 80 bit floating point arithmetic 382890075Sobrien;; :: 382990075Sobrien;; :::::::::::::::::::: 383090075Sobrien 3831132718Skan(define_insn "addxf3" 3832132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3833132718Skan (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3834132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))] 3835132718Skan "" 383690075Sobrien "fadd %0 = %F1, %F2" 383790075Sobrien [(set_attr "itanium_class" "fmac")]) 383890075Sobrien 3839132718Skan(define_insn "*addxf3_truncsf" 384090075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 384190075Sobrien (float_truncate:SF 3842132718Skan (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3843132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))] 3844132718Skan "" 384590075Sobrien "fadd.s %0 = %F1, %F2" 384690075Sobrien [(set_attr "itanium_class" "fmac")]) 384790075Sobrien 3848132718Skan(define_insn "*addxf3_truncdf" 384990075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 385090075Sobrien (float_truncate:DF 3851132718Skan (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3852132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))] 3853132718Skan "" 385490075Sobrien "fadd.d %0 = %F1, %F2" 385590075Sobrien [(set_attr "itanium_class" "fmac")]) 385690075Sobrien 3857132718Skan(define_insn "subxf3" 3858132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3859132718Skan (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3860132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))] 3861132718Skan "" 386290075Sobrien "fsub %0 = %F1, %F2" 386390075Sobrien [(set_attr "itanium_class" "fmac")]) 386490075Sobrien 3865132718Skan(define_insn "*subxf3_truncsf" 386690075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 386790075Sobrien (float_truncate:SF 3868132718Skan (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3869132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))] 3870132718Skan "" 387190075Sobrien "fsub.s %0 = %F1, %F2" 387290075Sobrien [(set_attr "itanium_class" "fmac")]) 387390075Sobrien 3874132718Skan(define_insn "*subxf3_truncdf" 387590075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 387690075Sobrien (float_truncate:DF 3877132718Skan (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3878132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))] 3879132718Skan "" 388090075Sobrien "fsub.d %0 = %F1, %F2" 388190075Sobrien [(set_attr "itanium_class" "fmac")]) 388290075Sobrien 3883132718Skan(define_insn "mulxf3" 3884132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3885132718Skan (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3886132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))] 3887132718Skan "" 388890075Sobrien "fmpy %0 = %F1, %F2" 388990075Sobrien [(set_attr "itanium_class" "fmac")]) 389090075Sobrien 3891132718Skan(define_insn "*mulxf3_truncsf" 389290075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 389390075Sobrien (float_truncate:SF 3894132718Skan (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3895132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))] 3896132718Skan "" 389790075Sobrien "fmpy.s %0 = %F1, %F2" 389890075Sobrien [(set_attr "itanium_class" "fmac")]) 389990075Sobrien 3900132718Skan(define_insn "*mulxf3_truncdf" 390190075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 390290075Sobrien (float_truncate:DF 3903132718Skan (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3904132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))] 3905132718Skan "" 390690075Sobrien "fmpy.d %0 = %F1, %F2" 390790075Sobrien [(set_attr "itanium_class" "fmac")]) 390890075Sobrien 3909132718Skan(define_insn "*mulxf3_alts" 3910132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3911132718Skan (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3912132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))) 391390075Sobrien (use (match_operand:SI 3 "const_int_operand" ""))] 3914132718Skan "" 391590075Sobrien "fmpy.s%3 %0 = %F1, %F2" 391690075Sobrien [(set_attr "itanium_class" "fmac")]) 391790075Sobrien 3918132718Skan(define_insn "*mulxf3_truncsf_alts" 391990075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 392090075Sobrien (float_truncate:SF 3921132718Skan (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3922132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))) 392390075Sobrien (use (match_operand:SI 3 "const_int_operand" ""))] 3924132718Skan "" 392590075Sobrien "fmpy.s.s%3 %0 = %F1, %F2" 392690075Sobrien [(set_attr "itanium_class" "fmac")]) 392790075Sobrien 3928132718Skan(define_insn "*mulxf3_truncdf_alts" 392990075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 393090075Sobrien (float_truncate:DF 3931132718Skan (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3932132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))) 393390075Sobrien (use (match_operand:SI 3 "const_int_operand" ""))] 3934132718Skan "" 393590075Sobrien "fmpy.d.s%3 %0 = %F1, %F2" 393690075Sobrien [(set_attr "itanium_class" "fmac")]) 393790075Sobrien 3938132718Skan(define_insn "absxf2" 3939132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3940132718Skan (abs:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")))] 3941132718Skan "" 394290075Sobrien "fabs %0 = %F1" 394390075Sobrien [(set_attr "itanium_class" "fmisc")]) 394490075Sobrien 3945132718Skan(define_insn "negxf2" 3946132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3947132718Skan (neg:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")))] 3948132718Skan "" 394990075Sobrien "fneg %0 = %F1" 395090075Sobrien [(set_attr "itanium_class" "fmisc")]) 395190075Sobrien 3952132718Skan(define_insn "*nabsxf2" 3953132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3954132718Skan (neg:XF (abs:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG"))))] 3955132718Skan "" 395690075Sobrien "fnegabs %0 = %F1" 395790075Sobrien [(set_attr "itanium_class" "fmisc")]) 395890075Sobrien 3959169689Skan(define_insn "copysignxf3" 3960169689Skan [(set (match_operand:XF 0 "register_operand" "=f") 3961169689Skan (unspec:XF [(match_operand:XF 1 "fr_reg_or_fp01_operand" "fG") 3962169689Skan (match_operand:XF 2 "fr_reg_or_fp01_operand" "fG")] 3963169689Skan UNSPEC_COPYSIGN))] 3964169689Skan "" 3965169689Skan "fmerge.s %0 = %F2, %F1" 3966169689Skan [(set_attr "itanium_class" "fmisc")]) 3967169689Skan 3968169689Skan(define_insn "*ncopysignxf3" 3969169689Skan [(set (match_operand:XF 0 "register_operand" "=f") 3970169689Skan (neg:XF (unspec:XF [(match_operand:XF 1 "fr_reg_or_fp01_operand" "fG") 3971169689Skan (match_operand:XF 2 "fr_reg_or_fp01_operand" "fG")] 3972169689Skan UNSPEC_COPYSIGN)))] 3973169689Skan "" 3974169689Skan "fmerge.ns %0 = %F2, %F1" 3975169689Skan [(set_attr "itanium_class" "fmisc")]) 3976169689Skan 3977169689Skan(define_insn "sminxf3" 3978132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3979132718Skan (smin:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3980132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))] 3981132718Skan "" 398290075Sobrien "fmin %0 = %F1, %F2" 398390075Sobrien [(set_attr "itanium_class" "fmisc")]) 398490075Sobrien 3985169689Skan(define_insn "smaxxf3" 3986132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3987132718Skan (smax:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3988132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))] 3989132718Skan "" 399090075Sobrien "fmax %0 = %F1, %F2" 399190075Sobrien [(set_attr "itanium_class" "fmisc")]) 399290075Sobrien 3993132718Skan(define_insn "*maddxf4" 3994132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 3995132718Skan (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 3996132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) 3997132718Skan (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))] 3998132718Skan "" 399990075Sobrien "fma %0 = %F1, %F2, %F3" 400090075Sobrien [(set_attr "itanium_class" "fmac")]) 400190075Sobrien 4002132718Skan(define_insn "*maddxf4_truncsf" 400390075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 400490075Sobrien (float_truncate:SF 4005132718Skan (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 4006132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) 4007132718Skan (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))] 4008132718Skan "" 400990075Sobrien "fma.s %0 = %F1, %F2, %F3" 401090075Sobrien [(set_attr "itanium_class" "fmac")]) 401190075Sobrien 4012132718Skan(define_insn "*maddxf4_truncdf" 401390075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 401490075Sobrien (float_truncate:DF 4015132718Skan (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 4016132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) 4017132718Skan (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))] 4018132718Skan "" 401990075Sobrien "fma.d %0 = %F1, %F2, %F3" 402090075Sobrien [(set_attr "itanium_class" "fmac")]) 402190075Sobrien 4022132718Skan(define_insn "*maddxf4_alts" 4023132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 4024132718Skan (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 4025132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) 4026132718Skan (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))) 402790075Sobrien (use (match_operand:SI 4 "const_int_operand" ""))] 4028132718Skan "" 402990075Sobrien "fma.s%4 %0 = %F1, %F2, %F3" 403090075Sobrien [(set_attr "itanium_class" "fmac")]) 403190075Sobrien 4032132718Skan(define_insn "*maddxf4_alts_truncsf" 4033132718Skan [(set (match_operand:SF 0 "fr_register_operand" "=f") 4034132718Skan (float_truncate:SF 4035132718Skan (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 4036132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) 4037132718Skan (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))) 4038132718Skan (use (match_operand:SI 4 "const_int_operand" ""))] 4039132718Skan "" 4040132718Skan "fma.s.s%4 %0 = %F1, %F2, %F3" 4041132718Skan [(set_attr "itanium_class" "fmac")]) 4042132718Skan 4043132718Skan(define_insn "*maddxf4_alts_truncdf" 404490075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 404590075Sobrien (float_truncate:DF 4046132718Skan (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 4047132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) 4048132718Skan (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))) 404990075Sobrien (use (match_operand:SI 4 "const_int_operand" ""))] 4050132718Skan "" 405190075Sobrien "fma.d.s%4 %0 = %F1, %F2, %F3" 405290075Sobrien [(set_attr "itanium_class" "fmac")]) 405390075Sobrien 4054132718Skan(define_insn "*msubxf4" 4055132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 4056132718Skan (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 4057132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) 4058132718Skan (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))] 4059132718Skan "" 406090075Sobrien "fms %0 = %F1, %F2, %F3" 406190075Sobrien [(set_attr "itanium_class" "fmac")]) 406290075Sobrien 4063132718Skan(define_insn "*msubxf4_truncsf" 406490075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 406590075Sobrien (float_truncate:SF 4066132718Skan (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 4067132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) 4068132718Skan (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))] 4069132718Skan "" 407090075Sobrien "fms.s %0 = %F1, %F2, %F3" 407190075Sobrien [(set_attr "itanium_class" "fmac")]) 407290075Sobrien 4073132718Skan(define_insn "*msubxf4_truncdf" 407490075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 407590075Sobrien (float_truncate:DF 4076132718Skan (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 4077132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) 4078132718Skan (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))] 4079132718Skan "" 408090075Sobrien "fms.d %0 = %F1, %F2, %F3" 408190075Sobrien [(set_attr "itanium_class" "fmac")]) 408290075Sobrien 4083132718Skan(define_insn "*nmulxf3" 4084132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 4085132718Skan (neg:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 4086132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))] 4087132718Skan "" 408890075Sobrien "fnmpy %0 = %F1, %F2" 408990075Sobrien [(set_attr "itanium_class" "fmac")]) 409090075Sobrien 4091132718Skan(define_insn "*nmulxf3_truncsf" 409290075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 409390075Sobrien (float_truncate:SF 4094132718Skan (neg:XF (mult:XF 4095132718Skan (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 4096132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))))] 4097132718Skan "" 409890075Sobrien "fnmpy.s %0 = %F1, %F2" 409990075Sobrien [(set_attr "itanium_class" "fmac")]) 410090075Sobrien 4101132718Skan(define_insn "*nmulxf3_truncdf" 410290075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 410390075Sobrien (float_truncate:DF 4104132718Skan (neg:XF (mult:XF 4105132718Skan (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 4106132718Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))))] 4107132718Skan "" 410890075Sobrien "fnmpy.d %0 = %F1, %F2" 410990075Sobrien [(set_attr "itanium_class" "fmac")]) 411090075Sobrien 4111132718Skan(define_insn "*nmaddxf4" 4112132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 4113169689Skan (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG") 4114169689Skan (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 4115169689Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG") 4116169689Skan )))] 4117132718Skan "" 411890075Sobrien "fnma %0 = %F1, %F2, %F3" 411990075Sobrien [(set_attr "itanium_class" "fmac")]) 412090075Sobrien 4121132718Skan(define_insn "*nmaddxf4_truncsf" 412290075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 412390075Sobrien (float_truncate:SF 4124169689Skan (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG") 4125169689Skan (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 4126169689Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG") 4127169689Skan ))))] 4128132718Skan "" 412990075Sobrien "fnma.s %0 = %F1, %F2, %F3" 413090075Sobrien [(set_attr "itanium_class" "fmac")]) 413190075Sobrien 4132132718Skan(define_insn "*nmaddxf4_truncdf" 413390075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 413490075Sobrien (float_truncate:DF 4135169689Skan (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG") 4136169689Skan (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 4137169689Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG") 4138169689Skan ))))] 4139132718Skan "" 414090075Sobrien "fnma.d %0 = %F1, %F2, %F3" 414190075Sobrien [(set_attr "itanium_class" "fmac")]) 414290075Sobrien 4143132718Skan(define_insn "*nmaddxf4_alts" 4144132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 4145169689Skan (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG") 4146169689Skan (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 4147169689Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG") 4148169689Skan ))) 414990075Sobrien (use (match_operand:SI 4 "const_int_operand" ""))] 4150132718Skan "" 415190075Sobrien "fnma.s%4 %0 = %F1, %F2, %F3" 415290075Sobrien [(set_attr "itanium_class" "fmac")]) 415390075Sobrien 4154169689Skan(define_insn "*nmaddxf4_truncsf_alts" 4155169689Skan [(set (match_operand:SF 0 "fr_register_operand" "=f") 4156169689Skan (float_truncate:SF 4157169689Skan (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG") 4158169689Skan (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 4159169689Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG") 4160169689Skan )))) 4161169689Skan (use (match_operand:SI 4 "const_int_operand" ""))] 4162169689Skan "" 4163169689Skan "fnma.s.s%4 %0 = %F1, %F2, %F3" 4164169689Skan [(set_attr "itanium_class" "fmac")]) 4165169689Skan 4166132718Skan(define_insn "*nmaddxf4_truncdf_alts" 416790075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 416890075Sobrien (float_truncate:DF 4169169689Skan (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG") 4170169689Skan (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") 4171169689Skan (match_operand:XF 2 "xfreg_or_fp01_operand" "fG") 4172169689Skan )))) 417390075Sobrien (use (match_operand:SI 4 "const_int_operand" ""))] 4174132718Skan "" 417590075Sobrien "fnma.d.s%4 %0 = %F1, %F2, %F3" 417690075Sobrien [(set_attr "itanium_class" "fmac")]) 417790075Sobrien 4178132718Skan(define_expand "divxf3" 4179132718Skan [(set (match_operand:XF 0 "fr_register_operand" "") 4180132718Skan (div:XF (match_operand:XF 1 "fr_register_operand" "") 4181132718Skan (match_operand:XF 2 "fr_register_operand" "")))] 4182132718Skan "TARGET_INLINE_FLOAT_DIV" 418390075Sobrien{ 418490075Sobrien rtx insn; 4185169689Skan if (TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT) 4186132718Skan insn = gen_divxf3_internal_lat (operands[0], operands[1], operands[2]); 418790075Sobrien else 4188132718Skan insn = gen_divxf3_internal_thr (operands[0], operands[1], operands[2]); 418990075Sobrien emit_insn (insn); 419090075Sobrien DONE; 4191117395Skan}) 419290075Sobrien 4193132718Skan(define_insn_and_split "divxf3_internal_lat" 4194132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=&f") 4195132718Skan (div:XF (match_operand:XF 1 "fr_register_operand" "f") 4196132718Skan (match_operand:XF 2 "fr_register_operand" "f"))) 4197132718Skan (clobber (match_scratch:XF 3 "=&f")) 4198132718Skan (clobber (match_scratch:XF 4 "=&f")) 4199132718Skan (clobber (match_scratch:XF 5 "=&f")) 4200132718Skan (clobber (match_scratch:XF 6 "=&f")) 420190075Sobrien (clobber (match_scratch:BI 7 "=c"))] 4202169689Skan "TARGET_INLINE_FLOAT_DIV == INL_MIN_LAT" 420390075Sobrien "#" 420490075Sobrien "&& reload_completed" 4205132718Skan [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2))) 4206117395Skan (set (match_dup 7) (unspec:BI [(match_dup 1) (match_dup 2)] 4207117395Skan UNSPEC_FR_RECIP_APPROX)) 4208169689Skan (use (const_int 0))]) 420990075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 421090075Sobrien (parallel [(set (match_dup 3) 4211169689Skan (minus:XF (match_dup 8) 4212169689Skan (mult:XF (match_dup 2) (match_dup 0)))) 421390075Sobrien (use (const_int 1))])) 421490075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 4215132718Skan (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0))) 421690075Sobrien (use (const_int 1))])) 421790075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 4218132718Skan (parallel [(set (match_dup 5) (mult:XF (match_dup 3) (match_dup 3))) 421990075Sobrien (use (const_int 1))])) 422090075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 422190075Sobrien (parallel [(set (match_dup 6) 4222132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 3)) 422390075Sobrien (match_dup 3))) 422490075Sobrien (use (const_int 1))])) 422590075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 422690075Sobrien (parallel [(set (match_dup 3) 4227132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 5)) 422890075Sobrien (match_dup 3))) 422990075Sobrien (use (const_int 1))])) 423090075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 423190075Sobrien (parallel [(set (match_dup 5) 4232132718Skan (plus:XF (mult:XF (match_dup 6) (match_dup 0)) 423390075Sobrien (match_dup 0))) 423490075Sobrien (use (const_int 1))])) 423590075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 423690075Sobrien (parallel [(set (match_dup 0) 4237132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 3)) 423890075Sobrien (match_dup 0))) 423990075Sobrien (use (const_int 1))])) 424090075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 424190075Sobrien (parallel [(set (match_dup 4) 4242169689Skan (minus:XF (match_dup 1) 4243169689Skan (mult:XF (match_dup 2) (match_dup 4)))) 424490075Sobrien (use (const_int 1))])) 424590075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 424690075Sobrien (parallel [(set (match_dup 3) 4247132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 0)) 424890075Sobrien (match_dup 4))) 424990075Sobrien (use (const_int 1))])) 425090075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 425190075Sobrien (parallel [(set (match_dup 5) 4252169689Skan (minus:XF (match_dup 8) 4253169689Skan (mult:XF (match_dup 2) (match_dup 0)))) 425490075Sobrien (use (const_int 1))])) 425590075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 425690075Sobrien (parallel [(set (match_dup 0) 4257132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 0)) 425890075Sobrien (match_dup 0))) 425990075Sobrien (use (const_int 1))])) 426090075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 426190075Sobrien (parallel [(set (match_dup 4) 4262169689Skan (minus:XF (match_dup 1) 4263169689Skan (mult:XF (match_dup 2) (match_dup 3)))) 426490075Sobrien (use (const_int 1))])) 426590075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 426690075Sobrien (set (match_dup 0) 4267132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 0)) 426890075Sobrien (match_dup 3)))) 426990075Sobrien ] 4270132718Skan "operands[8] = CONST1_RTX (XFmode);" 427190075Sobrien [(set_attr "predicable" "no")]) 427290075Sobrien 4273132718Skan(define_insn_and_split "divxf3_internal_thr" 4274132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=&f") 4275132718Skan (div:XF (match_operand:XF 1 "fr_register_operand" "f") 4276132718Skan (match_operand:XF 2 "fr_register_operand" "f"))) 4277132718Skan (clobber (match_scratch:XF 3 "=&f")) 4278132718Skan (clobber (match_scratch:XF 4 "=&f")) 427990075Sobrien (clobber (match_scratch:BI 5 "=c"))] 4280169689Skan "TARGET_INLINE_FLOAT_DIV == INL_MAX_THR" 428190075Sobrien "#" 428290075Sobrien "&& reload_completed" 4283132718Skan [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2))) 4284117395Skan (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)] 4285117395Skan UNSPEC_FR_RECIP_APPROX)) 4286169689Skan (use (const_int 0))]) 428790075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 428890075Sobrien (parallel [(set (match_dup 3) 4289169689Skan (minus:XF (match_dup 6) 4290169689Skan (mult:XF (match_dup 2) (match_dup 0)))) 429190075Sobrien (use (const_int 1))])) 429290075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 429390075Sobrien (parallel [(set (match_dup 4) 4294132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 0)) 429590075Sobrien (match_dup 0))) 429690075Sobrien (use (const_int 1))])) 429790075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 4298132718Skan (parallel [(set (match_dup 3) (mult:XF (match_dup 3) (match_dup 3))) 429990075Sobrien (use (const_int 1))])) 430090075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 430190075Sobrien (parallel [(set (match_dup 3) 4302132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 4)) 430390075Sobrien (match_dup 4))) 430490075Sobrien (use (const_int 1))])) 430590075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 4306132718Skan (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0))) 430790075Sobrien (use (const_int 1))])) 430890075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 430990075Sobrien (parallel [(set (match_dup 0) 4310169689Skan (minus:XF (match_dup 6) 4311169689Skan (mult:XF (match_dup 2) (match_dup 3)))) 431290075Sobrien (use (const_int 1))])) 431390075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 431490075Sobrien (parallel [(set (match_dup 0) 4315132718Skan (plus:XF (mult:XF (match_dup 0) (match_dup 3)) 431690075Sobrien (match_dup 3))) 431790075Sobrien (use (const_int 1))])) 431890075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 431990075Sobrien (parallel [(set (match_dup 3) 4320169689Skan (minus:XF (match_dup 1) 4321169689Skan (mult:XF (match_dup 2) (match_dup 4)))) 432290075Sobrien (use (const_int 1))])) 432390075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 432490075Sobrien (parallel [(set (match_dup 3) 4325132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 0)) 432690075Sobrien (match_dup 4))) 432790075Sobrien (use (const_int 1))])) 432890075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 432990075Sobrien (parallel [(set (match_dup 4) 4330169689Skan (minus:XF (match_dup 6) 4331169689Skan (mult:XF (match_dup 2) (match_dup 0)))) 433290075Sobrien (use (const_int 1))])) 433390075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 433490075Sobrien (parallel [(set (match_dup 0) 4335132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 0)) 433690075Sobrien (match_dup 0))) 433790075Sobrien (use (const_int 1))])) 433890075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 433990075Sobrien (parallel [(set (match_dup 4) 4340169689Skan (minus:XF (match_dup 1) 4341169689Skan (mult:XF (match_dup 2) (match_dup 3)))) 434290075Sobrien (use (const_int 1))])) 434390075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 434490075Sobrien (set (match_dup 0) 4345132718Skan (plus:XF (mult:XF (match_dup 4) (match_dup 0)) 434690075Sobrien (match_dup 3)))) 434790075Sobrien ] 4348132718Skan "operands[6] = CONST1_RTX (XFmode);" 434990075Sobrien [(set_attr "predicable" "no")]) 435090075Sobrien 4351132718Skan;; Inline square root. 4352132718Skan 4353132718Skan(define_expand "sqrtxf2" 4354132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=&f") 4355132718Skan (sqrt:XF (match_operand:XF 1 "fr_register_operand" "f")))] 4356132718Skan "TARGET_INLINE_SQRT" 4357132718Skan{ 4358132718Skan rtx insn; 4359132718Skan#if 0 4360169689Skan if (TARGET_INLINE_SQRT == INL_MIN_LAT) 4361132718Skan insn = gen_sqrtxf2_internal_lat (operands[0], operands[1]); 4362169689Skan else 4363132718Skan#else 4364169689Skan gcc_assert (TARGET_INLINE_SQRT != INL_MIN_LAT); 4365132718Skan#endif 4366169689Skan insn = gen_sqrtxf2_internal_thr (operands[0], operands[1]); 4367132718Skan emit_insn (insn); 4368132718Skan DONE; 4369132718Skan}) 4370132718Skan 4371132718Skan;; Latency-optimized square root. 4372132718Skan;; FIXME: Implement. 4373132718Skan 4374132718Skan;; Throughput-optimized square root. 4375132718Skan 4376132718Skan(define_insn_and_split "sqrtxf2_internal_thr" 4377132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=&f") 4378132718Skan (sqrt:XF (match_operand:XF 1 "fr_register_operand" "f"))) 4379132718Skan ;; Register r2 in optimization guide. 4380132718Skan (clobber (match_scratch:DI 2 "=r")) 4381132718Skan ;; Register f8 in optimization guide 4382132718Skan (clobber (match_scratch:XF 3 "=&f")) 4383132718Skan ;; Register f9 in optimization guide 4384132718Skan (clobber (match_scratch:XF 4 "=&f")) 4385132718Skan ;; Register f10 in optimization guide 4386132718Skan (clobber (match_scratch:XF 5 "=&f")) 4387132718Skan ;; Register f11 in optimization guide 4388132718Skan (clobber (match_scratch:XF 6 "=&f")) 4389132718Skan ;; Register p6 in optimization guide. 4390132718Skan (clobber (match_scratch:BI 7 "=c"))] 4391169689Skan "TARGET_INLINE_SQRT == INL_MAX_THR" 4392132718Skan "#" 4393132718Skan "&& reload_completed" 4394132718Skan [ ;; exponent of +1/2 in r2 4395132718Skan (set (match_dup 2) (const_int 65534)) 4396132718Skan ;; +1/2 in f8. The Intel manual mistakenly specifies f10. 4397132718Skan (set (match_dup 3) 4398132718Skan (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP)) 4399132718Skan ;; Step 1 4400132718Skan ;; y0 = 1/sqrt(a) in f7 4401132718Skan (parallel [(set (match_dup 8) 4402132718Skan (div:XF (const_int 1) 4403132718Skan (sqrt:XF (match_dup 9)))) 4404132718Skan (set (match_dup 7) 4405132718Skan (unspec:BI [(match_dup 9)] 4406132718Skan UNSPEC_FR_SQRT_RECIP_APPROX)) 4407132718Skan (use (const_int 0))]) 4408132718Skan ;; Step 2 4409132718Skan ;; H0 = 1/2 * y0 in f9 4410132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 4411132718Skan (parallel [(set (match_dup 4) 4412132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 8)) 4413132718Skan (match_dup 10))) 4414132718Skan (use (const_int 1))])) 4415132718Skan ;; Step 3 4416132718Skan ;; S0 = a * y0 in f7 4417132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 4418132718Skan (parallel [(set (match_dup 8) 4419132718Skan (plus:XF (mult:XF (match_dup 9) (match_dup 8)) 4420132718Skan (match_dup 10))) 4421132718Skan (use (const_int 1))])) 4422132718Skan ;; Step 4 4423132718Skan ;; d0 = 1/2 - S0 * H0 in f10 4424132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 4425132718Skan (parallel [(set (match_dup 5) 4426169689Skan (minus:XF (match_dup 3) 4427169689Skan (mult:XF (match_dup 8) (match_dup 4)))) 4428132718Skan (use (const_int 1))])) 4429132718Skan ;; Step 5 4430132718Skan ;; H1 = H0 + d0 * H0 in f9 4431132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 4432132718Skan (parallel [(set (match_dup 4) 4433132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 4)) 4434132718Skan (match_dup 4))) 4435132718Skan (use (const_int 1))])) 4436132718Skan ;; Step 6 4437132718Skan ;; S1 = S0 + d0 * S0 in f7 4438132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 4439132718Skan (parallel [(set (match_dup 8) 4440132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 8)) 4441132718Skan (match_dup 8))) 4442132718Skan (use (const_int 1))])) 4443132718Skan ;; Step 7 4444132718Skan ;; d1 = 1/2 - S1 * H1 in f10 4445132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 4446132718Skan (parallel [(set (match_dup 5) 4447169689Skan (minus:XF (match_dup 3) 4448169689Skan (mult:XF (match_dup 8) (match_dup 4)))) 4449132718Skan (use (const_int 1))])) 4450132718Skan ;; Step 8 4451132718Skan ;; H2 = H1 + d1 * H1 in f9 4452132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 4453132718Skan (parallel [(set (match_dup 4) 4454132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 4)) 4455132718Skan (match_dup 4))) 4456132718Skan (use (const_int 1))])) 4457132718Skan ;; Step 9 4458132718Skan ;; S2 = S1 + d1 * S1 in f7 4459132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 4460132718Skan (parallel [(set (match_dup 8) 4461132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 8)) 4462132718Skan (match_dup 8))) 4463132718Skan (use (const_int 1))])) 4464132718Skan ;; Step 10 4465132718Skan ;; d2 = 1/2 - S2 * H2 in f10 4466132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 4467132718Skan (parallel [(set (match_dup 5) 4468169689Skan (minus:XF (match_dup 3) 4469169689Skan (mult:XF (match_dup 8) (match_dup 4)))) 4470132718Skan (use (const_int 1))])) 4471132718Skan ;; Step 11 4472132718Skan ;; e2 = a - S2 * S2 in f8 4473132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 4474132718Skan (parallel [(set (match_dup 3) 4475169689Skan (minus:XF (match_dup 9) 4476169689Skan (mult:XF (match_dup 8) (match_dup 8)))) 4477132718Skan (use (const_int 1))])) 4478132718Skan ;; Step 12 4479132718Skan ;; S3 = S2 + e2 * H2 in f7 4480132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 4481132718Skan (parallel [(set (match_dup 8) 4482132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 4)) 4483132718Skan (match_dup 8))) 4484132718Skan (use (const_int 1))])) 4485132718Skan ;; Step 13 4486132718Skan ;; H3 = H2 + d2 * H2 in f9 4487132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 4488132718Skan (parallel [(set (match_dup 4) 4489132718Skan (plus:XF (mult:XF (match_dup 5) (match_dup 4)) 4490132718Skan (match_dup 4))) 4491132718Skan (use (const_int 1))])) 4492132718Skan ;; Step 14 4493132718Skan ;; e3 = a - S3 * S3 in f8 4494132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 4495132718Skan (parallel [(set (match_dup 3) 4496169689Skan (minus:XF (match_dup 9) 4497169689Skan (mult:XF (match_dup 8) (match_dup 8)))) 4498132718Skan (use (const_int 1))])) 4499132718Skan ;; Step 15 4500132718Skan ;; S = S3 + e3 * H3 in f7 4501132718Skan (cond_exec (ne (match_dup 7) (const_int 0)) 4502132718Skan (parallel [(set (match_dup 0) 4503132718Skan (plus:XF (mult:XF (match_dup 3) (match_dup 4)) 4504132718Skan (match_dup 8))) 4505132718Skan (use (const_int 0))]))] 4506132718Skan{ 4507132718Skan /* Generate 82-bit versions of the input and output operands. */ 4508132718Skan operands[8] = gen_rtx_REG (XFmode, REGNO (operands[0])); 4509132718Skan operands[9] = gen_rtx_REG (XFmode, REGNO (operands[1])); 4510132718Skan /* Generate required floating-point constants. */ 4511132718Skan operands[10] = CONST0_RTX (XFmode); 4512132718Skan} 4513132718Skan [(set_attr "predicable" "no")]) 4514132718Skan 451590075Sobrien;; ??? frcpa works like cmp.foo.unc. 451690075Sobrien 451790075Sobrien(define_insn "*recip_approx" 4518132718Skan [(set (match_operand:XF 0 "fr_register_operand" "=f") 4519132718Skan (div:XF (const_int 1) 4520132718Skan (match_operand:XF 3 "fr_register_operand" "f"))) 452190075Sobrien (set (match_operand:BI 1 "register_operand" "=c") 4522132718Skan (unspec:BI [(match_operand:XF 2 "fr_register_operand" "f") 4523117395Skan (match_dup 3)] UNSPEC_FR_RECIP_APPROX)) 452490075Sobrien (use (match_operand:SI 4 "const_int_operand" ""))] 4525132718Skan "" 452690075Sobrien "frcpa.s%4 %0, %1 = %2, %3" 452790075Sobrien [(set_attr "itanium_class" "fmisc") 452890075Sobrien (set_attr "predicable" "no")]) 452990075Sobrien 453090075Sobrien;; :::::::::::::::::::: 453190075Sobrien;; :: 453290075Sobrien;; :: 32 bit Integer Shifts and Rotates 453390075Sobrien;; :: 453490075Sobrien;; :::::::::::::::::::: 453590075Sobrien 453690075Sobrien(define_expand "ashlsi3" 453790075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "") 453890075Sobrien (ashift:SI (match_operand:SI 1 "gr_register_operand" "") 453990075Sobrien (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))] 454090075Sobrien "" 454190075Sobrien{ 454290075Sobrien if (GET_CODE (operands[2]) != CONST_INT) 454390075Sobrien { 454490075Sobrien /* Why oh why didn't Intel arrange for SHIFT_COUNT_TRUNCATED? Now 454590075Sobrien we've got to get rid of stray bits outside the SImode register. */ 454690075Sobrien rtx subshift = gen_reg_rtx (DImode); 454790075Sobrien emit_insn (gen_zero_extendsidi2 (subshift, operands[2])); 454890075Sobrien operands[2] = subshift; 454990075Sobrien } 4550117395Skan}) 455190075Sobrien 455290075Sobrien(define_insn "*ashlsi3_internal" 455390075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r") 455490075Sobrien (ashift:SI (match_operand:SI 1 "gr_register_operand" "r,r,r") 455590075Sobrien (match_operand:DI 2 "gr_reg_or_5bit_operand" "R,n,r")))] 455690075Sobrien "" 455790075Sobrien "@ 455890075Sobrien shladd %0 = %1, %2, r0 455990075Sobrien dep.z %0 = %1, %2, %E2 456090075Sobrien shl %0 = %1, %2" 456190075Sobrien [(set_attr "itanium_class" "ialu,ishf,mmshf")]) 456290075Sobrien 456390075Sobrien(define_expand "ashrsi3" 456490075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "") 456590075Sobrien (ashiftrt:SI (match_operand:SI 1 "gr_register_operand" "") 456690075Sobrien (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))] 456790075Sobrien "" 456890075Sobrien{ 456990075Sobrien rtx subtarget = gen_reg_rtx (DImode); 457090075Sobrien if (GET_CODE (operands[2]) == CONST_INT) 457190075Sobrien emit_insn (gen_extv (subtarget, gen_lowpart (DImode, operands[1]), 457290075Sobrien GEN_INT (32 - INTVAL (operands[2])), operands[2])); 457390075Sobrien else 457490075Sobrien { 457590075Sobrien rtx subshift = gen_reg_rtx (DImode); 457690075Sobrien emit_insn (gen_extendsidi2 (subtarget, operands[1])); 457790075Sobrien emit_insn (gen_zero_extendsidi2 (subshift, operands[2])); 457890075Sobrien emit_insn (gen_ashrdi3 (subtarget, subtarget, subshift)); 457990075Sobrien } 458090075Sobrien emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget); 458190075Sobrien DONE; 4582117395Skan}) 458390075Sobrien 458490075Sobrien(define_expand "lshrsi3" 458590075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "") 458690075Sobrien (lshiftrt:SI (match_operand:SI 1 "gr_register_operand" "") 458790075Sobrien (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))] 458890075Sobrien "" 458990075Sobrien{ 459090075Sobrien rtx subtarget = gen_reg_rtx (DImode); 459190075Sobrien if (GET_CODE (operands[2]) == CONST_INT) 459290075Sobrien emit_insn (gen_extzv (subtarget, gen_lowpart (DImode, operands[1]), 459390075Sobrien GEN_INT (32 - INTVAL (operands[2])), operands[2])); 459490075Sobrien else 459590075Sobrien { 459690075Sobrien rtx subshift = gen_reg_rtx (DImode); 459790075Sobrien emit_insn (gen_zero_extendsidi2 (subtarget, operands[1])); 459890075Sobrien emit_insn (gen_zero_extendsidi2 (subshift, operands[2])); 459990075Sobrien emit_insn (gen_lshrdi3 (subtarget, subtarget, subshift)); 460090075Sobrien } 460190075Sobrien emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget); 460290075Sobrien DONE; 4603117395Skan}) 460490075Sobrien 460590075Sobrien;; Use mix4.r/shr to implement rotrsi3. We only get 32 bits of valid result 460690075Sobrien;; here, instead of 64 like the patterns above. Keep the pattern together 460790075Sobrien;; until after combine; otherwise it won't get matched often. 460890075Sobrien 460990075Sobrien(define_expand "rotrsi3" 461090075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "") 461190075Sobrien (rotatert:SI (match_operand:SI 1 "gr_register_operand" "") 461290075Sobrien (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))] 461390075Sobrien "" 461490075Sobrien{ 461590075Sobrien if (GET_MODE (operands[2]) != VOIDmode) 461690075Sobrien { 461790075Sobrien rtx tmp = gen_reg_rtx (DImode); 461890075Sobrien emit_insn (gen_zero_extendsidi2 (tmp, operands[2])); 461990075Sobrien operands[2] = tmp; 462090075Sobrien } 4621117395Skan}) 462290075Sobrien 462390075Sobrien(define_insn_and_split "*rotrsi3_internal" 462490075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=&r") 462590075Sobrien (rotatert:SI (match_operand:SI 1 "gr_register_operand" "r") 462690075Sobrien (match_operand:DI 2 "gr_reg_or_5bit_operand" "rM")))] 462790075Sobrien "" 462890075Sobrien "#" 462990075Sobrien "reload_completed" 463090075Sobrien [(set (match_dup 3) 463190075Sobrien (ior:DI (zero_extend:DI (match_dup 1)) 463290075Sobrien (ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32)))) 463390075Sobrien (set (match_dup 3) 463490075Sobrien (lshiftrt:DI (match_dup 3) (match_dup 2)))] 463590075Sobrien "operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));") 463690075Sobrien 463790075Sobrien(define_expand "rotlsi3" 463890075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "") 463990075Sobrien (rotate:SI (match_operand:SI 1 "gr_register_operand" "") 464090075Sobrien (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))] 464190075Sobrien "" 464290075Sobrien{ 464390075Sobrien if (! shift_32bit_count_operand (operands[2], SImode)) 464490075Sobrien { 464590075Sobrien rtx tmp = gen_reg_rtx (SImode); 464690075Sobrien emit_insn (gen_subsi3 (tmp, GEN_INT (32), operands[2])); 464790075Sobrien emit_insn (gen_rotrsi3 (operands[0], operands[1], tmp)); 464890075Sobrien DONE; 464990075Sobrien } 4650117395Skan}) 465190075Sobrien 465290075Sobrien(define_insn_and_split "*rotlsi3_internal" 465390075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 465490075Sobrien (rotate:SI (match_operand:SI 1 "gr_register_operand" "r") 465590075Sobrien (match_operand:SI 2 "shift_32bit_count_operand" "n")))] 465690075Sobrien "" 4657169689Skan "mux2 %0 = %1, 0xe1" 4658169689Skan "reload_completed && INTVAL (operands[2]) != 16" 465990075Sobrien [(set (match_dup 3) 466090075Sobrien (ior:DI (zero_extend:DI (match_dup 1)) 466190075Sobrien (ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32)))) 466290075Sobrien (set (match_dup 3) 466390075Sobrien (lshiftrt:DI (match_dup 3) (match_dup 2)))] 4664117395Skan{ 4665117395Skan operands[3] = gen_rtx_REG (DImode, REGNO (operands[0])); 4666117395Skan operands[2] = GEN_INT (32 - INTVAL (operands[2])); 4667169689Skan} 4668169689Skan [(set_attr "itanium_class" "mmshf")]) 466990075Sobrien 467090075Sobrien;; :::::::::::::::::::: 467190075Sobrien;; :: 467290075Sobrien;; :: 64 bit Integer Shifts and Rotates 467390075Sobrien;; :: 467490075Sobrien;; :::::::::::::::::::: 467590075Sobrien 467690075Sobrien(define_insn "ashldi3" 467790075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r") 467890075Sobrien (ashift:DI (match_operand:DI 1 "gr_register_operand" "r,r,r") 467990075Sobrien (match_operand:DI 2 "gr_reg_or_6bit_operand" "R,r,rM")))] 468090075Sobrien "" 468190075Sobrien "@ 468290075Sobrien shladd %0 = %1, %2, r0 468390075Sobrien shl %0 = %1, %2 468490075Sobrien shl %0 = %1, %2" 468590075Sobrien [(set_attr "itanium_class" "ialu,mmshf,mmshfi")]) 468690075Sobrien 468790075Sobrien;; ??? Maybe combine this with the multiply and add instruction? 468890075Sobrien 468990075Sobrien(define_insn "*shladd" 469090075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 469190075Sobrien (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r") 469290075Sobrien (match_operand:DI 2 "shladd_operand" "n")) 469390075Sobrien (match_operand:DI 3 "gr_register_operand" "r")))] 469490075Sobrien "" 469590075Sobrien "shladd %0 = %1, %S2, %3" 469690075Sobrien [(set_attr "itanium_class" "ialu")]) 469790075Sobrien 469890075Sobrien;; This can be created by register elimination if operand3 of shladd is an 469990075Sobrien;; eliminable register or has reg_equiv_constant set. 470090075Sobrien 470190075Sobrien;; We have to use nonmemory_operand for operand 4, to ensure that the 470290075Sobrien;; validate_changes call inside eliminate_regs will always succeed. If it 470390075Sobrien;; doesn't succeed, then this remain a shladd pattern, and will be reloaded 470490075Sobrien;; incorrectly. 470590075Sobrien 470690075Sobrien(define_insn_and_split "*shladd_elim" 470790075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=&r") 470890075Sobrien (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r") 470990075Sobrien (match_operand:DI 2 "shladd_operand" "n")) 471090075Sobrien (match_operand:DI 3 "nonmemory_operand" "r")) 471190075Sobrien (match_operand:DI 4 "nonmemory_operand" "rI")))] 471290075Sobrien "reload_in_progress" 4713169689Skan "* gcc_unreachable ();" 471490075Sobrien "reload_completed" 471590075Sobrien [(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (match_dup 2)) 471690075Sobrien (match_dup 3))) 471790075Sobrien (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))] 471890075Sobrien "" 471990075Sobrien [(set_attr "itanium_class" "unknown")]) 472090075Sobrien 472190075Sobrien(define_insn "ashrdi3" 472290075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r,r") 472390075Sobrien (ashiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r") 472490075Sobrien (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))] 472590075Sobrien "" 472690075Sobrien "@ 472790075Sobrien shr %0 = %1, %2 472890075Sobrien shr %0 = %1, %2" 472990075Sobrien [(set_attr "itanium_class" "mmshf,mmshfi")]) 473090075Sobrien 473190075Sobrien(define_insn "lshrdi3" 473290075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r,r") 473390075Sobrien (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r") 473490075Sobrien (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))] 473590075Sobrien "" 473690075Sobrien "@ 473790075Sobrien shr.u %0 = %1, %2 473890075Sobrien shr.u %0 = %1, %2" 473990075Sobrien [(set_attr "itanium_class" "mmshf,mmshfi")]) 474090075Sobrien 474190075Sobrien;; Using a predicate that accepts only constants doesn't work, because optabs 474290075Sobrien;; will load the operand into a register and call the pattern if the predicate 474390075Sobrien;; did not accept it on the first try. So we use nonmemory_operand and then 474490075Sobrien;; verify that we have an appropriate constant in the expander. 474590075Sobrien 474690075Sobrien(define_expand "rotrdi3" 474790075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") 474890075Sobrien (rotatert:DI (match_operand:DI 1 "gr_register_operand" "") 474990075Sobrien (match_operand:DI 2 "nonmemory_operand" "")))] 475090075Sobrien "" 475190075Sobrien{ 475290075Sobrien if (! shift_count_operand (operands[2], DImode)) 475390075Sobrien FAIL; 4754117395Skan}) 475590075Sobrien 475690075Sobrien(define_insn "*rotrdi3_internal" 475790075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 475890075Sobrien (rotatert:DI (match_operand:DI 1 "gr_register_operand" "r") 475990075Sobrien (match_operand:DI 2 "shift_count_operand" "M")))] 476090075Sobrien "" 476190075Sobrien "shrp %0 = %1, %1, %2" 476290075Sobrien [(set_attr "itanium_class" "ishf")]) 476390075Sobrien 476490075Sobrien(define_expand "rotldi3" 476590075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") 476690075Sobrien (rotate:DI (match_operand:DI 1 "gr_register_operand" "") 476790075Sobrien (match_operand:DI 2 "nonmemory_operand" "")))] 476890075Sobrien "" 476990075Sobrien{ 477090075Sobrien if (! shift_count_operand (operands[2], DImode)) 477190075Sobrien FAIL; 4772117395Skan}) 477390075Sobrien 477490075Sobrien(define_insn "*rotldi3_internal" 477590075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 477690075Sobrien (rotate:DI (match_operand:DI 1 "gr_register_operand" "r") 477790075Sobrien (match_operand:DI 2 "shift_count_operand" "M")))] 477890075Sobrien "" 477990075Sobrien "shrp %0 = %1, %1, %e2" 478090075Sobrien [(set_attr "itanium_class" "ishf")]) 478190075Sobrien 478290075Sobrien;; :::::::::::::::::::: 478390075Sobrien;; :: 4784169689Skan;; :: 128 bit Integer Shifts and Rotates 4785169689Skan;; :: 4786169689Skan;; :::::::::::::::::::: 4787169689Skan 4788169689Skan(define_expand "ashlti3" 4789169689Skan [(set (match_operand:TI 0 "gr_register_operand" "") 4790169689Skan (ashift:TI (match_operand:TI 1 "gr_register_operand" "") 4791169689Skan (match_operand:DI 2 "nonmemory_operand" "")))] 4792169689Skan "" 4793169689Skan{ 4794169689Skan if (!dshift_count_operand (operands[2], DImode)) 4795169689Skan FAIL; 4796169689Skan}) 4797169689Skan 4798169689Skan(define_insn_and_split "*ashlti3_internal" 4799169689Skan [(set (match_operand:TI 0 "gr_register_operand" "=&r") 4800169689Skan (ashift:TI (match_operand:TI 1 "gr_register_operand" "r") 4801169689Skan (match_operand:DI 2 "dshift_count_operand" "n")))] 4802169689Skan "" 4803169689Skan "#" 4804169689Skan "reload_completed" 4805169689Skan [(const_int 0)] 4806169689Skan{ 4807169689Skan HOST_WIDE_INT shift = INTVAL (operands[2]); 4808169689Skan rtx rl = gen_lowpart (DImode, operands[0]); 4809169689Skan rtx rh = gen_highpart (DImode, operands[0]); 4810169689Skan rtx lo = gen_lowpart (DImode, operands[1]); 4811169689Skan rtx shiftlo = GEN_INT (shift & 63); 4812169689Skan 4813169689Skan if (shift & 64) 4814169689Skan { 4815169689Skan emit_move_insn (rl, const0_rtx); 4816169689Skan if (shift & 63) 4817169689Skan emit_insn (gen_ashldi3 (rh, lo, shiftlo)); 4818169689Skan else 4819169689Skan emit_move_insn (rh, lo); 4820169689Skan } 4821169689Skan else 4822169689Skan { 4823169689Skan rtx hi = gen_highpart (DImode, operands[1]); 4824169689Skan 4825169689Skan emit_insn (gen_shrp (rh, hi, lo, GEN_INT (-shift & 63))); 4826169689Skan emit_insn (gen_ashldi3 (rl, lo, shiftlo)); 4827169689Skan } 4828169689Skan DONE; 4829169689Skan}) 4830169689Skan 4831169689Skan(define_expand "ashrti3" 4832169689Skan [(set (match_operand:TI 0 "gr_register_operand" "") 4833169689Skan (ashiftrt:TI (match_operand:TI 1 "gr_register_operand" "") 4834169689Skan (match_operand:DI 2 "nonmemory_operand" "")))] 4835169689Skan "" 4836169689Skan{ 4837169689Skan if (!dshift_count_operand (operands[2], DImode)) 4838169689Skan FAIL; 4839169689Skan}) 4840169689Skan 4841169689Skan(define_insn_and_split "*ashrti3_internal" 4842169689Skan [(set (match_operand:TI 0 "gr_register_operand" "=&r") 4843169689Skan (ashiftrt:TI (match_operand:TI 1 "gr_register_operand" "r") 4844169689Skan (match_operand:DI 2 "dshift_count_operand" "n")))] 4845169689Skan "" 4846169689Skan "#" 4847169689Skan "reload_completed" 4848169689Skan [(const_int 0)] 4849169689Skan{ 4850169689Skan HOST_WIDE_INT shift = INTVAL (operands[2]); 4851169689Skan rtx rl = gen_lowpart (DImode, operands[0]); 4852169689Skan rtx rh = gen_highpart (DImode, operands[0]); 4853169689Skan rtx hi = gen_highpart (DImode, operands[1]); 4854169689Skan rtx shiftlo = GEN_INT (shift & 63); 4855169689Skan 4856169689Skan if (shift & 64) 4857169689Skan { 4858169689Skan if (shift & 63) 4859169689Skan emit_insn (gen_ashrdi3 (rl, hi, shiftlo)); 4860169689Skan else 4861169689Skan emit_move_insn (rl, hi); 4862169689Skan emit_insn (gen_ashrdi3 (rh, hi, GEN_INT (63))); 4863169689Skan } 4864169689Skan else 4865169689Skan { 4866169689Skan rtx lo = gen_lowpart (DImode, operands[1]); 4867169689Skan 4868169689Skan emit_insn (gen_shrp (rl, hi, lo, shiftlo)); 4869169689Skan emit_insn (gen_ashrdi3 (rh, hi, shiftlo)); 4870169689Skan } 4871169689Skan DONE; 4872169689Skan}) 4873169689Skan 4874169689Skan(define_expand "lshrti3" 4875169689Skan [(set (match_operand:TI 0 "gr_register_operand" "") 4876169689Skan (lshiftrt:TI (match_operand:TI 1 "gr_register_operand" "") 4877169689Skan (match_operand:DI 2 "nonmemory_operand" "")))] 4878169689Skan "" 4879169689Skan{ 4880169689Skan if (!dshift_count_operand (operands[2], DImode)) 4881169689Skan FAIL; 4882169689Skan}) 4883169689Skan 4884169689Skan(define_insn_and_split "*lshrti3_internal" 4885169689Skan [(set (match_operand:TI 0 "gr_register_operand" "=&r") 4886169689Skan (lshiftrt:TI (match_operand:TI 1 "gr_register_operand" "r") 4887169689Skan (match_operand:DI 2 "dshift_count_operand" "n")))] 4888169689Skan "" 4889169689Skan "#" 4890169689Skan "reload_completed" 4891169689Skan [(const_int 0)] 4892169689Skan{ 4893169689Skan HOST_WIDE_INT shift = INTVAL (operands[2]); 4894169689Skan rtx rl = gen_lowpart (DImode, operands[0]); 4895169689Skan rtx rh = gen_highpart (DImode, operands[0]); 4896169689Skan rtx hi = gen_highpart (DImode, operands[1]); 4897169689Skan rtx shiftlo = GEN_INT (shift & 63); 4898169689Skan 4899169689Skan if (shift & 64) 4900169689Skan { 4901169689Skan if (shift & 63) 4902169689Skan emit_insn (gen_lshrdi3 (rl, hi, shiftlo)); 4903169689Skan else 4904169689Skan emit_move_insn (rl, hi); 4905169689Skan emit_move_insn (rh, const0_rtx); 4906169689Skan } 4907169689Skan else 4908169689Skan { 4909169689Skan rtx lo = gen_lowpart (DImode, operands[1]); 4910169689Skan 4911169689Skan emit_insn (gen_shrp (rl, hi, lo, shiftlo)); 4912169689Skan emit_insn (gen_lshrdi3 (rh, hi, shiftlo)); 4913169689Skan } 4914169689Skan DONE; 4915169689Skan}) 4916169689Skan 4917169689Skan(define_expand "rotlti3" 4918169689Skan [(set (match_operand:TI 0 "gr_register_operand" "") 4919169689Skan (rotate:TI (match_operand:TI 1 "gr_register_operand" "") 4920169689Skan (match_operand:DI 2 "nonmemory_operand" "")))] 4921169689Skan "" 4922169689Skan{ 4923169689Skan if (! dshift_count_operand (operands[2], DImode)) 4924169689Skan FAIL; 4925169689Skan}) 4926169689Skan 4927169689Skan(define_insn_and_split "*rotlti3_internal" 4928169689Skan [(set (match_operand:TI 0 "gr_register_operand" "=&r") 4929169689Skan (rotate:TI (match_operand:TI 1 "gr_register_operand" "r") 4930169689Skan (match_operand:DI 2 "dshift_count_operand" "n")))] 4931169689Skan "" 4932169689Skan "#" 4933169689Skan "reload_completed" 4934169689Skan [(const_int 0)] 4935169689Skan{ 4936169689Skan HOST_WIDE_INT count = INTVAL (operands[2]); 4937169689Skan rtx rl = gen_lowpart (DImode, operands[0]); 4938169689Skan rtx rh = gen_highpart (DImode, operands[0]); 4939169689Skan rtx lo = gen_lowpart (DImode, operands[1]); 4940169689Skan rtx hi = gen_highpart (DImode, operands[1]); 4941169689Skan rtx countlo = GEN_INT (-count & 63); 4942169689Skan 4943169689Skan if (count & 64) 4944169689Skan { 4945169689Skan if (count & 63) 4946169689Skan { 4947169689Skan emit_insn (gen_shrp (rl, hi, lo, countlo)); 4948169689Skan emit_insn (gen_shrp (rh, lo, hi, countlo)); 4949169689Skan } 4950169689Skan else 4951169689Skan { 4952169689Skan emit_move_insn (rl, hi); 4953169689Skan emit_move_insn (rh, lo); 4954169689Skan } 4955169689Skan } 4956169689Skan else 4957169689Skan { 4958169689Skan emit_insn (gen_shrp (rl, lo, hi, countlo)); 4959169689Skan emit_insn (gen_shrp (rh, hi, lo, countlo)); 4960169689Skan } 4961169689Skan DONE; 4962169689Skan} 4963169689Skan [(set_attr "itanium_class" "unknown")]) 4964169689Skan 4965169689Skan(define_insn "shrp" 4966169689Skan [(set (match_operand:DI 0 "gr_register_operand" "=r") 4967169689Skan (unspec:DI [(match_operand:DI 1 "gr_register_operand" "r") 4968169689Skan (match_operand:DI 2 "gr_register_operand" "r") 4969169689Skan (match_operand:DI 3 "shift_count_operand" "M")] 4970169689Skan UNSPEC_SHRP))] 4971169689Skan "" 4972169689Skan "shrp %0 = %1, %2, %3" 4973169689Skan [(set_attr "itanium_class" "ishf")]) 4974169689Skan 4975169689Skan;; :::::::::::::::::::: 4976169689Skan;; :: 497790075Sobrien;; :: 32 bit Integer Logical operations 497890075Sobrien;; :: 497990075Sobrien;; :::::::::::::::::::: 498090075Sobrien 498190075Sobrien;; We don't seem to need any other 32-bit logical operations, because gcc 498290075Sobrien;; generates zero-extend;zero-extend;DImode-op, which combine optimizes to 498390075Sobrien;; DImode-op;zero-extend, and then we can optimize away the zero-extend. 498490075Sobrien;; This doesn't work for unary logical operations, because we don't call 498590075Sobrien;; apply_distributive_law for them. 498690075Sobrien 498790075Sobrien;; ??? Likewise, this doesn't work for andnot, which isn't handled by 498890075Sobrien;; apply_distributive_law. We get inefficient code for 498990075Sobrien;; int sub4 (int i, int j) { return i & ~j; } 499090075Sobrien;; We could convert (and (not (sign_extend A)) (sign_extend B)) to 499190075Sobrien;; (zero_extend (and (not A) B)) in combine. 499290075Sobrien;; Or maybe fix this by adding andsi3/iorsi3/xorsi3 patterns like the 499390075Sobrien;; one_cmplsi2 pattern. 499490075Sobrien 499590075Sobrien(define_insn "one_cmplsi2" 499690075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 499790075Sobrien (not:SI (match_operand:SI 1 "gr_register_operand" "r")))] 499890075Sobrien "" 499990075Sobrien "andcm %0 = -1, %1" 500090075Sobrien [(set_attr "itanium_class" "ilog")]) 500190075Sobrien 500290075Sobrien;; :::::::::::::::::::: 500390075Sobrien;; :: 500490075Sobrien;; :: 64 bit Integer Logical operations 500590075Sobrien;; :: 500690075Sobrien;; :::::::::::::::::::: 500790075Sobrien 500890075Sobrien(define_insn "anddi3" 500990075Sobrien [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f") 501090075Sobrien (and:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f") 501190075Sobrien (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))] 501290075Sobrien "" 501390075Sobrien "@ 501490075Sobrien and %0 = %2, %1 501590075Sobrien fand %0 = %2, %1" 501690075Sobrien [(set_attr "itanium_class" "ilog,fmisc")]) 501790075Sobrien 501890075Sobrien(define_insn "*andnot" 501990075Sobrien [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f") 502090075Sobrien (and:DI (not:DI (match_operand:DI 1 "grfr_register_operand" "r,*f")) 502190075Sobrien (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))] 502290075Sobrien "" 502390075Sobrien "@ 502490075Sobrien andcm %0 = %2, %1 502590075Sobrien fandcm %0 = %2, %1" 502690075Sobrien [(set_attr "itanium_class" "ilog,fmisc")]) 502790075Sobrien 502890075Sobrien(define_insn "iordi3" 502990075Sobrien [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f") 503090075Sobrien (ior:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f") 503190075Sobrien (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))] 503290075Sobrien "" 503390075Sobrien "@ 503490075Sobrien or %0 = %2, %1 503590075Sobrien for %0 = %2, %1" 503690075Sobrien [(set_attr "itanium_class" "ilog,fmisc")]) 503790075Sobrien 503890075Sobrien(define_insn "xordi3" 503990075Sobrien [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f") 504090075Sobrien (xor:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f") 504190075Sobrien (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))] 504290075Sobrien "" 504390075Sobrien "@ 504490075Sobrien xor %0 = %2, %1 504590075Sobrien fxor %0 = %2, %1" 504690075Sobrien [(set_attr "itanium_class" "ilog,fmisc")]) 504790075Sobrien 504890075Sobrien(define_insn "one_cmpldi2" 504990075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 505090075Sobrien (not:DI (match_operand:DI 1 "gr_register_operand" "r")))] 505190075Sobrien "" 505290075Sobrien "andcm %0 = -1, %1" 505390075Sobrien [(set_attr "itanium_class" "ilog")]) 505490075Sobrien 505590075Sobrien;; :::::::::::::::::::: 505690075Sobrien;; :: 505790075Sobrien;; :: Comparisons 505890075Sobrien;; :: 505990075Sobrien;; :::::::::::::::::::: 506090075Sobrien 506190075Sobrien(define_expand "cmpbi" 506290075Sobrien [(set (cc0) 506390075Sobrien (compare (match_operand:BI 0 "register_operand" "") 506490075Sobrien (match_operand:BI 1 "const_int_operand" "")))] 506590075Sobrien "" 506690075Sobrien{ 506790075Sobrien ia64_compare_op0 = operands[0]; 506890075Sobrien ia64_compare_op1 = operands[1]; 506990075Sobrien DONE; 5070117395Skan}) 507190075Sobrien 507290075Sobrien(define_expand "cmpsi" 507390075Sobrien [(set (cc0) 507490075Sobrien (compare (match_operand:SI 0 "gr_register_operand" "") 507590075Sobrien (match_operand:SI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))] 507690075Sobrien "" 507790075Sobrien{ 507890075Sobrien ia64_compare_op0 = operands[0]; 507990075Sobrien ia64_compare_op1 = operands[1]; 508090075Sobrien DONE; 5081117395Skan}) 508290075Sobrien 508390075Sobrien(define_expand "cmpdi" 508490075Sobrien [(set (cc0) 508590075Sobrien (compare (match_operand:DI 0 "gr_register_operand" "") 508690075Sobrien (match_operand:DI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))] 508790075Sobrien "" 508890075Sobrien{ 508990075Sobrien ia64_compare_op0 = operands[0]; 509090075Sobrien ia64_compare_op1 = operands[1]; 509190075Sobrien DONE; 5092117395Skan}) 509390075Sobrien 509490075Sobrien(define_expand "cmpsf" 509590075Sobrien [(set (cc0) 509690075Sobrien (compare (match_operand:SF 0 "fr_reg_or_fp01_operand" "") 509790075Sobrien (match_operand:SF 1 "fr_reg_or_fp01_operand" "")))] 509890075Sobrien "" 509990075Sobrien{ 510090075Sobrien ia64_compare_op0 = operands[0]; 510190075Sobrien ia64_compare_op1 = operands[1]; 510290075Sobrien DONE; 5103117395Skan}) 510490075Sobrien 510590075Sobrien(define_expand "cmpdf" 510690075Sobrien [(set (cc0) 510790075Sobrien (compare (match_operand:DF 0 "fr_reg_or_fp01_operand" "") 510890075Sobrien (match_operand:DF 1 "fr_reg_or_fp01_operand" "")))] 510990075Sobrien "" 511090075Sobrien{ 511190075Sobrien ia64_compare_op0 = operands[0]; 511290075Sobrien ia64_compare_op1 = operands[1]; 511390075Sobrien DONE; 5114117395Skan}) 511590075Sobrien 5116132718Skan(define_expand "cmpxf" 5117132718Skan [(set (cc0) 5118132718Skan (compare (match_operand:XF 0 "xfreg_or_fp01_operand" "") 5119132718Skan (match_operand:XF 1 "xfreg_or_fp01_operand" "")))] 5120132718Skan "" 5121132718Skan{ 5122132718Skan ia64_compare_op0 = operands[0]; 5123132718Skan ia64_compare_op1 = operands[1]; 5124132718Skan DONE; 5125132718Skan}) 5126132718Skan 512790075Sobrien(define_expand "cmptf" 512890075Sobrien [(set (cc0) 5129132718Skan (compare (match_operand:TF 0 "gr_register_operand" "") 5130132718Skan (match_operand:TF 1 "gr_register_operand" "")))] 5131132718Skan "TARGET_HPUX" 513290075Sobrien{ 513390075Sobrien ia64_compare_op0 = operands[0]; 513490075Sobrien ia64_compare_op1 = operands[1]; 513590075Sobrien DONE; 5136117395Skan}) 513790075Sobrien 513890075Sobrien(define_insn "*cmpsi_normal" 513990075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 514090075Sobrien (match_operator:BI 1 "normal_comparison_operator" 514190075Sobrien [(match_operand:SI 2 "gr_register_operand" "r") 514290075Sobrien (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))] 514390075Sobrien "" 514490075Sobrien "cmp4.%C1 %0, %I0 = %3, %2" 514590075Sobrien [(set_attr "itanium_class" "icmp")]) 514690075Sobrien 514790075Sobrien;; We use %r3 because it is possible for us to match a 0, and two of the 514890075Sobrien;; unsigned comparisons don't accept immediate operands of zero. 514990075Sobrien 515090075Sobrien(define_insn "*cmpsi_adjusted" 515190075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 515290075Sobrien (match_operator:BI 1 "adjusted_comparison_operator" 515390075Sobrien [(match_operand:SI 2 "gr_register_operand" "r") 515490075Sobrien (match_operand:SI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))] 515590075Sobrien "" 515690075Sobrien "cmp4.%C1 %0, %I0 = %r3, %2" 515790075Sobrien [(set_attr "itanium_class" "icmp")]) 515890075Sobrien 515990075Sobrien(define_insn "*cmpdi_normal" 516090075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 516190075Sobrien (match_operator:BI 1 "normal_comparison_operator" 516290075Sobrien [(match_operand:DI 2 "gr_reg_or_0_operand" "rO") 516390075Sobrien (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))] 516490075Sobrien "" 516590075Sobrien "cmp.%C1 %0, %I0 = %3, %r2" 516690075Sobrien [(set_attr "itanium_class" "icmp")]) 516790075Sobrien 516890075Sobrien;; We use %r3 because it is possible for us to match a 0, and two of the 516990075Sobrien;; unsigned comparisons don't accept immediate operands of zero. 517090075Sobrien 517190075Sobrien(define_insn "*cmpdi_adjusted" 517290075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 517390075Sobrien (match_operator:BI 1 "adjusted_comparison_operator" 517490075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 517590075Sobrien (match_operand:DI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))] 517690075Sobrien "" 517790075Sobrien "cmp.%C1 %0, %I0 = %r3, %2" 517890075Sobrien [(set_attr "itanium_class" "icmp")]) 517990075Sobrien 518090075Sobrien(define_insn "*cmpsf_internal" 518190075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 518290075Sobrien (match_operator:BI 1 "comparison_operator" 518390075Sobrien [(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG") 518490075Sobrien (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")]))] 518590075Sobrien "" 518690075Sobrien "fcmp.%D1 %0, %I0 = %F2, %F3" 518790075Sobrien [(set_attr "itanium_class" "fcmp")]) 518890075Sobrien 518990075Sobrien(define_insn "*cmpdf_internal" 519090075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 519190075Sobrien (match_operator:BI 1 "comparison_operator" 519290075Sobrien [(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG") 519390075Sobrien (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")]))] 519490075Sobrien "" 519590075Sobrien "fcmp.%D1 %0, %I0 = %F2, %F3" 519690075Sobrien [(set_attr "itanium_class" "fcmp")]) 519790075Sobrien 5198132718Skan(define_insn "*cmpxf_internal" 519990075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 520090075Sobrien (match_operator:BI 1 "comparison_operator" 5201132718Skan [(match_operand:XF 2 "xfreg_or_fp01_operand" "fG") 5202132718Skan (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")]))] 5203132718Skan "" 520490075Sobrien "fcmp.%D1 %0, %I0 = %F2, %F3" 520590075Sobrien [(set_attr "itanium_class" "fcmp")]) 520690075Sobrien 520790075Sobrien;; ??? Can this pattern be generated? 520890075Sobrien 520990075Sobrien(define_insn "*bit_zero" 521090075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 521190075Sobrien (eq:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r") 521290075Sobrien (const_int 1) 5213169689Skan (match_operand:DI 2 "shift_count_operand" "M")) 521490075Sobrien (const_int 0)))] 521590075Sobrien "" 521690075Sobrien "tbit.z %0, %I0 = %1, %2" 521790075Sobrien [(set_attr "itanium_class" "tbit")]) 521890075Sobrien 521990075Sobrien(define_insn "*bit_one" 522090075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 522190075Sobrien (ne:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r") 522290075Sobrien (const_int 1) 5223169689Skan (match_operand:DI 2 "shift_count_operand" "M")) 522490075Sobrien (const_int 0)))] 522590075Sobrien "" 522690075Sobrien "tbit.nz %0, %I0 = %1, %2" 522790075Sobrien [(set_attr "itanium_class" "tbit")]) 522890075Sobrien 522990075Sobrien;; :::::::::::::::::::: 523090075Sobrien;; :: 523190075Sobrien;; :: Branches 523290075Sobrien;; :: 523390075Sobrien;; :::::::::::::::::::: 523490075Sobrien 523590075Sobrien(define_expand "beq" 523690075Sobrien [(set (pc) 523790075Sobrien (if_then_else (match_dup 1) 523890075Sobrien (label_ref (match_operand 0 "" "")) 523990075Sobrien (pc)))] 524090075Sobrien "" 524190075Sobrien "operands[1] = ia64_expand_compare (EQ, VOIDmode);") 524290075Sobrien 524390075Sobrien(define_expand "bne" 524490075Sobrien [(set (pc) 524590075Sobrien (if_then_else (match_dup 1) 524690075Sobrien (label_ref (match_operand 0 "" "")) 524790075Sobrien (pc)))] 524890075Sobrien "" 524990075Sobrien "operands[1] = ia64_expand_compare (NE, VOIDmode);") 525090075Sobrien 525190075Sobrien(define_expand "blt" 525290075Sobrien [(set (pc) 525390075Sobrien (if_then_else (match_dup 1) 525490075Sobrien (label_ref (match_operand 0 "" "")) 525590075Sobrien (pc)))] 525690075Sobrien "" 525790075Sobrien "operands[1] = ia64_expand_compare (LT, VOIDmode);") 525890075Sobrien 525990075Sobrien(define_expand "ble" 526090075Sobrien [(set (pc) 526190075Sobrien (if_then_else (match_dup 1) 526290075Sobrien (label_ref (match_operand 0 "" "")) 526390075Sobrien (pc)))] 526490075Sobrien "" 526590075Sobrien "operands[1] = ia64_expand_compare (LE, VOIDmode);") 526690075Sobrien 526790075Sobrien(define_expand "bgt" 526890075Sobrien [(set (pc) 526990075Sobrien (if_then_else (match_dup 1) 527090075Sobrien (label_ref (match_operand 0 "" "")) 527190075Sobrien (pc)))] 527290075Sobrien "" 527390075Sobrien "operands[1] = ia64_expand_compare (GT, VOIDmode);") 527490075Sobrien 527590075Sobrien(define_expand "bge" 527690075Sobrien [(set (pc) 527790075Sobrien (if_then_else (match_dup 1) 527890075Sobrien (label_ref (match_operand 0 "" "")) 527990075Sobrien (pc)))] 528090075Sobrien "" 528190075Sobrien "operands[1] = ia64_expand_compare (GE, VOIDmode);") 528290075Sobrien 528390075Sobrien(define_expand "bltu" 528490075Sobrien [(set (pc) 528590075Sobrien (if_then_else (match_dup 1) 528690075Sobrien (label_ref (match_operand 0 "" "")) 528790075Sobrien (pc)))] 528890075Sobrien "" 528990075Sobrien "operands[1] = ia64_expand_compare (LTU, VOIDmode);") 529090075Sobrien 529190075Sobrien(define_expand "bleu" 529290075Sobrien [(set (pc) 529390075Sobrien (if_then_else (match_dup 1) 529490075Sobrien (label_ref (match_operand 0 "" "")) 529590075Sobrien (pc)))] 529690075Sobrien "" 529790075Sobrien "operands[1] = ia64_expand_compare (LEU, VOIDmode);") 529890075Sobrien 529990075Sobrien(define_expand "bgtu" 530090075Sobrien [(set (pc) 530190075Sobrien (if_then_else (match_dup 1) 530290075Sobrien (label_ref (match_operand 0 "" "")) 530390075Sobrien (pc)))] 530490075Sobrien "" 530590075Sobrien "operands[1] = ia64_expand_compare (GTU, VOIDmode);") 530690075Sobrien 530790075Sobrien(define_expand "bgeu" 530890075Sobrien [(set (pc) 530990075Sobrien (if_then_else (match_dup 1) 531090075Sobrien (label_ref (match_operand 0 "" "")) 531190075Sobrien (pc)))] 531290075Sobrien "" 531390075Sobrien "operands[1] = ia64_expand_compare (GEU, VOIDmode);") 531490075Sobrien 531590075Sobrien(define_expand "bunordered" 531690075Sobrien [(set (pc) 531790075Sobrien (if_then_else (match_dup 1) 531890075Sobrien (label_ref (match_operand 0 "" "")) 531990075Sobrien (pc)))] 532090075Sobrien "" 532190075Sobrien "operands[1] = ia64_expand_compare (UNORDERED, VOIDmode);") 532290075Sobrien 532390075Sobrien(define_expand "bordered" 532490075Sobrien [(set (pc) 532590075Sobrien (if_then_else (match_dup 1) 532690075Sobrien (label_ref (match_operand 0 "" "")) 532790075Sobrien (pc)))] 532890075Sobrien "" 532990075Sobrien "operands[1] = ia64_expand_compare (ORDERED, VOIDmode);") 533090075Sobrien 533190075Sobrien(define_insn "*br_true" 533290075Sobrien [(set (pc) 533390075Sobrien (if_then_else (match_operator 0 "predicate_operator" 533490075Sobrien [(match_operand:BI 1 "register_operand" "c") 533590075Sobrien (const_int 0)]) 533690075Sobrien (label_ref (match_operand 2 "" "")) 533790075Sobrien (pc)))] 533890075Sobrien "" 533990075Sobrien "(%J0) br.cond%+ %l2" 534090075Sobrien [(set_attr "itanium_class" "br") 534190075Sobrien (set_attr "predicable" "no")]) 534290075Sobrien 534390075Sobrien(define_insn "*br_false" 534490075Sobrien [(set (pc) 534590075Sobrien (if_then_else (match_operator 0 "predicate_operator" 534690075Sobrien [(match_operand:BI 1 "register_operand" "c") 534790075Sobrien (const_int 0)]) 534890075Sobrien (pc) 534990075Sobrien (label_ref (match_operand 2 "" ""))))] 535090075Sobrien "" 535190075Sobrien "(%j0) br.cond%+ %l2" 535290075Sobrien [(set_attr "itanium_class" "br") 535390075Sobrien (set_attr "predicable" "no")]) 535490075Sobrien 535590075Sobrien;; :::::::::::::::::::: 535690075Sobrien;; :: 535790075Sobrien;; :: Counted loop operations 535890075Sobrien;; :: 535990075Sobrien;; :::::::::::::::::::: 536090075Sobrien 536190075Sobrien(define_expand "doloop_end" 536290075Sobrien [(use (match_operand 0 "" "")) ; loop pseudo 536390075Sobrien (use (match_operand 1 "" "")) ; iterations; zero if unknown 536490075Sobrien (use (match_operand 2 "" "")) ; max iterations 536590075Sobrien (use (match_operand 3 "" "")) ; loop level 536690075Sobrien (use (match_operand 4 "" ""))] ; label 536790075Sobrien "" 536890075Sobrien{ 536990075Sobrien /* Only use cloop on innermost loops. */ 537090075Sobrien if (INTVAL (operands[3]) > 1) 537190075Sobrien FAIL; 537290075Sobrien emit_jump_insn (gen_doloop_end_internal (gen_rtx_REG (DImode, AR_LC_REGNUM), 537390075Sobrien operands[4])); 537490075Sobrien DONE; 5375117395Skan}) 537690075Sobrien 537790075Sobrien(define_insn "doloop_end_internal" 537890075Sobrien [(set (pc) (if_then_else (ne (match_operand:DI 0 "ar_lc_reg_operand" "") 537990075Sobrien (const_int 0)) 538090075Sobrien (label_ref (match_operand 1 "" "")) 538190075Sobrien (pc))) 538290075Sobrien (set (match_dup 0) (if_then_else:DI (ne (match_dup 0) (const_int 0)) 5383117395Skan (plus:DI (match_dup 0) (const_int -1)) 5384117395Skan (match_dup 0)))] 538590075Sobrien "" 538690075Sobrien "br.cloop.sptk.few %l1" 538790075Sobrien [(set_attr "itanium_class" "br") 538890075Sobrien (set_attr "predicable" "no")]) 538990075Sobrien 539090075Sobrien;; :::::::::::::::::::: 539190075Sobrien;; :: 539290075Sobrien;; :: Set flag operations 539390075Sobrien;; :: 539490075Sobrien;; :::::::::::::::::::: 539590075Sobrien 539690075Sobrien(define_expand "seq" 539790075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 539890075Sobrien "" 539990075Sobrien "operands[1] = ia64_expand_compare (EQ, DImode);") 540090075Sobrien 540190075Sobrien(define_expand "sne" 540290075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 540390075Sobrien "" 540490075Sobrien "operands[1] = ia64_expand_compare (NE, DImode);") 540590075Sobrien 540690075Sobrien(define_expand "slt" 540790075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 540890075Sobrien "" 540990075Sobrien "operands[1] = ia64_expand_compare (LT, DImode);") 541090075Sobrien 541190075Sobrien(define_expand "sle" 541290075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 541390075Sobrien "" 541490075Sobrien "operands[1] = ia64_expand_compare (LE, DImode);") 541590075Sobrien 541690075Sobrien(define_expand "sgt" 541790075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 541890075Sobrien "" 541990075Sobrien "operands[1] = ia64_expand_compare (GT, DImode);") 542090075Sobrien 542190075Sobrien(define_expand "sge" 542290075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 542390075Sobrien "" 542490075Sobrien "operands[1] = ia64_expand_compare (GE, DImode);") 542590075Sobrien 542690075Sobrien(define_expand "sltu" 542790075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 542890075Sobrien "" 542990075Sobrien "operands[1] = ia64_expand_compare (LTU, DImode);") 543090075Sobrien 543190075Sobrien(define_expand "sleu" 543290075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 543390075Sobrien "" 543490075Sobrien "operands[1] = ia64_expand_compare (LEU, DImode);") 543590075Sobrien 543690075Sobrien(define_expand "sgtu" 543790075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 543890075Sobrien "" 543990075Sobrien "operands[1] = ia64_expand_compare (GTU, DImode);") 544090075Sobrien 544190075Sobrien(define_expand "sgeu" 544290075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 544390075Sobrien "" 544490075Sobrien "operands[1] = ia64_expand_compare (GEU, DImode);") 544590075Sobrien 544690075Sobrien(define_expand "sunordered" 544790075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 544890075Sobrien "" 544990075Sobrien "operands[1] = ia64_expand_compare (UNORDERED, DImode);") 545090075Sobrien 545190075Sobrien(define_expand "sordered" 545290075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 545390075Sobrien "" 545490075Sobrien "operands[1] = ia64_expand_compare (ORDERED, DImode);") 545590075Sobrien 545690075Sobrien;; Don't allow memory as destination here, because cmov/cmov/st is more 545790075Sobrien;; efficient than mov/mov/cst/cst. 545890075Sobrien 545990075Sobrien(define_insn_and_split "*sne_internal" 546090075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 546190075Sobrien (ne:DI (match_operand:BI 1 "register_operand" "c") 546290075Sobrien (const_int 0)))] 546390075Sobrien "" 546490075Sobrien "#" 546590075Sobrien "reload_completed" 546690075Sobrien [(cond_exec (ne (match_dup 1) (const_int 0)) 546790075Sobrien (set (match_dup 0) (const_int 1))) 546890075Sobrien (cond_exec (eq (match_dup 1) (const_int 0)) 546990075Sobrien (set (match_dup 0) (const_int 0)))] 547090075Sobrien "" 547190075Sobrien [(set_attr "itanium_class" "unknown")]) 547290075Sobrien 547390075Sobrien(define_insn_and_split "*seq_internal" 547490075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 547590075Sobrien (eq:DI (match_operand:BI 1 "register_operand" "c") 547690075Sobrien (const_int 0)))] 547790075Sobrien "" 547890075Sobrien "#" 547990075Sobrien "reload_completed" 548090075Sobrien [(cond_exec (ne (match_dup 1) (const_int 0)) 548190075Sobrien (set (match_dup 0) (const_int 0))) 548290075Sobrien (cond_exec (eq (match_dup 1) (const_int 0)) 548390075Sobrien (set (match_dup 0) (const_int 1)))] 548490075Sobrien "" 548590075Sobrien [(set_attr "itanium_class" "unknown")]) 548690075Sobrien 548790075Sobrien;; :::::::::::::::::::: 548890075Sobrien;; :: 548990075Sobrien;; :: Conditional move instructions. 549090075Sobrien;; :: 549190075Sobrien;; :::::::::::::::::::: 549290075Sobrien 549390075Sobrien;; ??? Add movXXcc patterns? 549490075Sobrien 549590075Sobrien;; 549690075Sobrien;; DImode if_then_else patterns. 549790075Sobrien;; 549890075Sobrien 549990075Sobrien(define_insn "*cmovdi_internal" 550090075Sobrien [(set (match_operand:DI 0 "destination_operand" 550190075Sobrien "= r, r, r, r, r, r, r, r, r, r, m, Q, *f,*b,*d*e") 550290075Sobrien (if_then_else:DI 550390075Sobrien (match_operator 4 "predicate_operator" 550490075Sobrien [(match_operand:BI 1 "register_operand" 550590075Sobrien "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c") 550690075Sobrien (const_int 0)]) 550790075Sobrien (match_operand:DI 2 "move_operand" 5508132718Skan "rim, *f, *b,*d*e,rim,rim, rim,*f,*b,*d*e,rO,*f,rOQ,rO, rK") 550990075Sobrien (match_operand:DI 3 "move_operand" 5510132718Skan "rim,rim,rim, rim, *f, *b,*d*e,*f,*b,*d*e,rO,*f,rOQ,rO, rK")))] 551190075Sobrien "ia64_move_ok (operands[0], operands[2]) 551290075Sobrien && ia64_move_ok (operands[0], operands[3])" 5513169689Skan { gcc_unreachable (); } 551490075Sobrien [(set_attr "predicable" "no")]) 551590075Sobrien 551690075Sobrien(define_split 551790075Sobrien [(set (match_operand 0 "destination_operand" "") 551890075Sobrien (if_then_else 551990075Sobrien (match_operator 4 "predicate_operator" 552090075Sobrien [(match_operand:BI 1 "register_operand" "") 552190075Sobrien (const_int 0)]) 552290075Sobrien (match_operand 2 "move_operand" "") 552390075Sobrien (match_operand 3 "move_operand" "")))] 552490075Sobrien "reload_completed" 552590075Sobrien [(const_int 0)] 552690075Sobrien{ 5527132718Skan bool emitted_something = false; 5528132718Skan rtx dest = operands[0]; 5529132718Skan rtx srct = operands[2]; 5530132718Skan rtx srcf = operands[3]; 5531132718Skan rtx cond = operands[4]; 5532117395Skan 5533132718Skan if (! rtx_equal_p (dest, srct)) 553490075Sobrien { 5535132718Skan ia64_emit_cond_move (dest, srct, cond); 5536132718Skan emitted_something = true; 553790075Sobrien } 5538132718Skan if (! rtx_equal_p (dest, srcf)) 553990075Sobrien { 5540132718Skan cond = gen_rtx_fmt_ee (GET_CODE (cond) == NE ? EQ : NE, 5541132718Skan VOIDmode, operands[1], const0_rtx); 5542132718Skan ia64_emit_cond_move (dest, srcf, cond); 5543132718Skan emitted_something = true; 554490075Sobrien } 5545117395Skan if (! emitted_something) 5546132718Skan emit_note (NOTE_INSN_DELETED); 554790075Sobrien DONE; 5548117395Skan}) 554990075Sobrien 555090075Sobrien;; Absolute value pattern. 555190075Sobrien 555290075Sobrien(define_insn "*absdi2_internal" 555390075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r,r") 555490075Sobrien (if_then_else:DI 555590075Sobrien (match_operator 4 "predicate_operator" 555690075Sobrien [(match_operand:BI 1 "register_operand" "c,c") 555790075Sobrien (const_int 0)]) 555890075Sobrien (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" "rI,rI")) 555990075Sobrien (match_operand:DI 3 "gr_reg_or_22bit_operand" "0,rI")))] 556090075Sobrien "" 556190075Sobrien "#" 556290075Sobrien [(set_attr "itanium_class" "ialu,unknown") 556390075Sobrien (set_attr "predicable" "no")]) 556490075Sobrien 556590075Sobrien(define_split 556690075Sobrien [(set (match_operand:DI 0 "register_operand" "") 556790075Sobrien (if_then_else:DI 556890075Sobrien (match_operator 4 "predicate_operator" 556990075Sobrien [(match_operand:BI 1 "register_operand" "c,c") 557090075Sobrien (const_int 0)]) 557190075Sobrien (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" "")) 557290075Sobrien (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))] 557390075Sobrien "reload_completed && rtx_equal_p (operands[0], operands[3])" 557490075Sobrien [(cond_exec 557590075Sobrien (match_dup 4) 557690075Sobrien (set (match_dup 0) 557790075Sobrien (neg:DI (match_dup 2))))] 557890075Sobrien "") 557990075Sobrien 558090075Sobrien(define_split 558190075Sobrien [(set (match_operand:DI 0 "register_operand" "") 558290075Sobrien (if_then_else:DI 558390075Sobrien (match_operator 4 "predicate_operator" 558490075Sobrien [(match_operand:BI 1 "register_operand" "c,c") 558590075Sobrien (const_int 0)]) 558690075Sobrien (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" "")) 558790075Sobrien (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))] 558890075Sobrien "reload_completed" 558990075Sobrien [(cond_exec 559090075Sobrien (match_dup 4) 559190075Sobrien (set (match_dup 0) (neg:DI (match_dup 2)))) 559290075Sobrien (cond_exec 559390075Sobrien (match_dup 5) 559490075Sobrien (set (match_dup 0) (match_dup 3)))] 559590075Sobrien{ 559690075Sobrien operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE, 559790075Sobrien VOIDmode, operands[1], const0_rtx); 5598117395Skan}) 559990075Sobrien 560090075Sobrien;; 560190075Sobrien;; SImode if_then_else patterns. 560290075Sobrien;; 560390075Sobrien 560490075Sobrien(define_insn "*cmovsi_internal" 560590075Sobrien [(set (match_operand:SI 0 "destination_operand" "=r,m,*f,r,m,*f,r,m,*f") 560690075Sobrien (if_then_else:SI 560790075Sobrien (match_operator 4 "predicate_operator" 560890075Sobrien [(match_operand:BI 1 "register_operand" "c,c,c,c,c,c,c,c,c") 560990075Sobrien (const_int 0)]) 561090075Sobrien (match_operand:SI 2 "move_operand" 5611132718Skan "0,0,0,rim*f,rO,rO,rim*f,rO,rO") 561290075Sobrien (match_operand:SI 3 "move_operand" 5613132718Skan "rim*f,rO,rO,0,0,0,rim*f,rO,rO")))] 561490075Sobrien "ia64_move_ok (operands[0], operands[2]) 561590075Sobrien && ia64_move_ok (operands[0], operands[3])" 5616169689Skan { gcc_unreachable (); } 561790075Sobrien [(set_attr "predicable" "no")]) 561890075Sobrien 561990075Sobrien(define_insn "*abssi2_internal" 562090075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r,r") 562190075Sobrien (if_then_else:SI 562290075Sobrien (match_operator 4 "predicate_operator" 562390075Sobrien [(match_operand:BI 1 "register_operand" "c,c") 562490075Sobrien (const_int 0)]) 562590075Sobrien (neg:SI (match_operand:SI 3 "gr_reg_or_22bit_operand" "rI,rI")) 562690075Sobrien (match_operand:SI 2 "gr_reg_or_22bit_operand" "0,rI")))] 562790075Sobrien "" 562890075Sobrien "#" 562990075Sobrien [(set_attr "itanium_class" "ialu,unknown") 563090075Sobrien (set_attr "predicable" "no")]) 563190075Sobrien 563290075Sobrien(define_split 563390075Sobrien [(set (match_operand:SI 0 "register_operand" "") 563490075Sobrien (if_then_else:SI 563590075Sobrien (match_operator 4 "predicate_operator" 563690075Sobrien [(match_operand:BI 1 "register_operand" "c,c") 563790075Sobrien (const_int 0)]) 563890075Sobrien (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" "")) 563990075Sobrien (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))] 564090075Sobrien "reload_completed && rtx_equal_p (operands[0], operands[3])" 564190075Sobrien [(cond_exec 564290075Sobrien (match_dup 4) 564390075Sobrien (set (match_dup 0) 564490075Sobrien (neg:SI (match_dup 2))))] 564590075Sobrien "") 564690075Sobrien 564790075Sobrien(define_split 564890075Sobrien [(set (match_operand:SI 0 "register_operand" "") 564990075Sobrien (if_then_else:SI 565090075Sobrien (match_operator 4 "predicate_operator" 565190075Sobrien [(match_operand:BI 1 "register_operand" "c,c") 565290075Sobrien (const_int 0)]) 565390075Sobrien (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" "")) 565490075Sobrien (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))] 565590075Sobrien "reload_completed" 565690075Sobrien [(cond_exec 565790075Sobrien (match_dup 4) 565890075Sobrien (set (match_dup 0) (neg:SI (match_dup 2)))) 565990075Sobrien (cond_exec 566090075Sobrien (match_dup 5) 566190075Sobrien (set (match_dup 0) (match_dup 3)))] 566290075Sobrien{ 566390075Sobrien operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE, 566490075Sobrien VOIDmode, operands[1], const0_rtx); 5665117395Skan}) 566690075Sobrien 566790075Sobrien(define_insn_and_split "*cond_opsi2_internal" 566890075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 566990075Sobrien (match_operator:SI 5 "condop_operator" 567090075Sobrien [(if_then_else:SI 567190075Sobrien (match_operator 6 "predicate_operator" 567290075Sobrien [(match_operand:BI 1 "register_operand" "c") 567390075Sobrien (const_int 0)]) 567490075Sobrien (match_operand:SI 2 "gr_register_operand" "r") 567590075Sobrien (match_operand:SI 3 "gr_register_operand" "r")) 567690075Sobrien (match_operand:SI 4 "gr_register_operand" "r")]))] 567790075Sobrien "" 567890075Sobrien "#" 567990075Sobrien "reload_completed" 568090075Sobrien [(cond_exec 568190075Sobrien (match_dup 6) 568290075Sobrien (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 2) (match_dup 4)]))) 568390075Sobrien (cond_exec 568490075Sobrien (match_dup 7) 568590075Sobrien (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 3) (match_dup 4)])))] 568690075Sobrien{ 568790075Sobrien operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE, 568890075Sobrien VOIDmode, operands[1], const0_rtx); 5689117395Skan} 569090075Sobrien [(set_attr "itanium_class" "ialu") 569190075Sobrien (set_attr "predicable" "no")]) 569290075Sobrien 569390075Sobrien 569490075Sobrien(define_insn_and_split "*cond_opsi2_internal_b" 569590075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 569690075Sobrien (match_operator:SI 5 "condop_operator" 569790075Sobrien [(match_operand:SI 4 "gr_register_operand" "r") 569890075Sobrien (if_then_else:SI 569990075Sobrien (match_operator 6 "predicate_operator" 570090075Sobrien [(match_operand:BI 1 "register_operand" "c") 570190075Sobrien (const_int 0)]) 570290075Sobrien (match_operand:SI 2 "gr_register_operand" "r") 570390075Sobrien (match_operand:SI 3 "gr_register_operand" "r"))]))] 570490075Sobrien "" 570590075Sobrien "#" 570690075Sobrien "reload_completed" 570790075Sobrien [(cond_exec 570890075Sobrien (match_dup 6) 570990075Sobrien (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 2)]))) 571090075Sobrien (cond_exec 571190075Sobrien (match_dup 7) 571290075Sobrien (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 3)])))] 571390075Sobrien{ 571490075Sobrien operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE, 571590075Sobrien VOIDmode, operands[1], const0_rtx); 5716117395Skan} 571790075Sobrien [(set_attr "itanium_class" "ialu") 571890075Sobrien (set_attr "predicable" "no")]) 571990075Sobrien 572090075Sobrien 572190075Sobrien;; :::::::::::::::::::: 572290075Sobrien;; :: 572390075Sobrien;; :: Call and branch instructions 572490075Sobrien;; :: 572590075Sobrien;; :::::::::::::::::::: 572690075Sobrien 572790075Sobrien;; Subroutine call instruction returning no value. Operand 0 is the function 572890075Sobrien;; to call; operand 1 is the number of bytes of arguments pushed (in mode 572990075Sobrien;; `SImode', except it is normally a `const_int'); operand 2 is the number of 573090075Sobrien;; registers used as operands. 573190075Sobrien 573290075Sobrien;; On most machines, operand 2 is not actually stored into the RTL pattern. It 573390075Sobrien;; is supplied for the sake of some RISC machines which need to put this 573490075Sobrien;; information into the assembler code; they can put it in the RTL instead of 573590075Sobrien;; operand 1. 573690075Sobrien 573790075Sobrien(define_expand "call" 573890075Sobrien [(use (match_operand:DI 0 "" "")) 573990075Sobrien (use (match_operand 1 "" "")) 574090075Sobrien (use (match_operand 2 "" "")) 574190075Sobrien (use (match_operand 3 "" ""))] 574290075Sobrien "" 574390075Sobrien{ 5744117395Skan ia64_expand_call (NULL_RTX, operands[0], operands[2], false); 574590075Sobrien DONE; 5746117395Skan}) 574790075Sobrien 574890075Sobrien(define_expand "sibcall" 574990075Sobrien [(use (match_operand:DI 0 "" "")) 575090075Sobrien (use (match_operand 1 "" "")) 575190075Sobrien (use (match_operand 2 "" "")) 575290075Sobrien (use (match_operand 3 "" ""))] 575390075Sobrien "" 575490075Sobrien{ 5755117395Skan ia64_expand_call (NULL_RTX, operands[0], operands[2], true); 575690075Sobrien DONE; 5757117395Skan}) 575890075Sobrien 575990075Sobrien;; Subroutine call instruction returning a value. Operand 0 is the hard 576090075Sobrien;; register in which the value is returned. There are three more operands, 576190075Sobrien;; the same as the three operands of the `call' instruction (but with numbers 576290075Sobrien;; increased by one). 576390075Sobrien;; 576490075Sobrien;; Subroutines that return `BLKmode' objects use the `call' insn. 576590075Sobrien 576690075Sobrien(define_expand "call_value" 576790075Sobrien [(use (match_operand 0 "" "")) 576890075Sobrien (use (match_operand:DI 1 "" "")) 576990075Sobrien (use (match_operand 2 "" "")) 577090075Sobrien (use (match_operand 3 "" "")) 577190075Sobrien (use (match_operand 4 "" ""))] 577290075Sobrien "" 577390075Sobrien{ 5774117395Skan ia64_expand_call (operands[0], operands[1], operands[3], false); 577590075Sobrien DONE; 5776117395Skan}) 577790075Sobrien 577890075Sobrien(define_expand "sibcall_value" 577990075Sobrien [(use (match_operand 0 "" "")) 578090075Sobrien (use (match_operand:DI 1 "" "")) 578190075Sobrien (use (match_operand 2 "" "")) 578290075Sobrien (use (match_operand 3 "" "")) 578390075Sobrien (use (match_operand 4 "" ""))] 578490075Sobrien "" 578590075Sobrien{ 5786117395Skan ia64_expand_call (operands[0], operands[1], operands[3], true); 578790075Sobrien DONE; 5788117395Skan}) 578990075Sobrien 579090075Sobrien;; Call subroutine returning any type. 579190075Sobrien 579290075Sobrien(define_expand "untyped_call" 579390075Sobrien [(parallel [(call (match_operand 0 "" "") 579490075Sobrien (const_int 0)) 579590075Sobrien (match_operand 1 "" "") 579690075Sobrien (match_operand 2 "" "")])] 579790075Sobrien "" 579890075Sobrien{ 579990075Sobrien int i; 580090075Sobrien 580190075Sobrien emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx)); 580290075Sobrien 580390075Sobrien for (i = 0; i < XVECLEN (operands[2], 0); i++) 580490075Sobrien { 580590075Sobrien rtx set = XVECEXP (operands[2], 0, i); 580690075Sobrien emit_move_insn (SET_DEST (set), SET_SRC (set)); 580790075Sobrien } 580890075Sobrien 580990075Sobrien /* The optimizer does not know that the call sets the function value 581090075Sobrien registers we stored in the result block. We avoid problems by 581190075Sobrien claiming that all hard registers are used and clobbered at this 581290075Sobrien point. */ 581390075Sobrien emit_insn (gen_blockage ()); 581490075Sobrien 581590075Sobrien DONE; 5816117395Skan}) 581790075Sobrien 5818117395Skan(define_insn "call_nogp" 5819117395Skan [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i")) 5820117395Skan (const_int 0)) 5821117395Skan (clobber (match_operand:DI 1 "register_operand" "=b,b"))] 582290075Sobrien "" 5823117395Skan "br.call%+.many %1 = %0" 582490075Sobrien [(set_attr "itanium_class" "br,scall")]) 582590075Sobrien 5826117395Skan(define_insn "call_value_nogp" 5827132718Skan [(set (match_operand 0 "" "=X,X") 5828117395Skan (call (mem:DI (match_operand:DI 1 "call_operand" "?b,i")) 5829117395Skan (const_int 0))) 5830117395Skan (clobber (match_operand:DI 2 "register_operand" "=b,b"))] 583190075Sobrien "" 5832117395Skan "br.call%+.many %2 = %1" 583390075Sobrien [(set_attr "itanium_class" "br,scall")]) 583490075Sobrien 5835117395Skan(define_insn "sibcall_nogp" 5836117395Skan [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i")) 5837117395Skan (const_int 0))] 583890075Sobrien "" 583990075Sobrien "br%+.many %0" 584090075Sobrien [(set_attr "itanium_class" "br,scall")]) 584190075Sobrien 5842117395Skan(define_insn "call_gp" 5843132718Skan [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,i")) 5844117395Skan (const_int 1)) 5845117395Skan (clobber (match_operand:DI 1 "register_operand" "=b,b")) 5846117395Skan (clobber (match_scratch:DI 2 "=&r,X")) 5847117395Skan (clobber (match_scratch:DI 3 "=b,X"))] 584890075Sobrien "" 5849117395Skan "#" 585090075Sobrien [(set_attr "itanium_class" "br,scall")]) 585190075Sobrien 5852117395Skan;; Irritatingly, we don't have access to INSN within the split body. 5853117395Skan;; See commentary in ia64_split_call as to why these aren't peep2. 5854117395Skan(define_split 5855117395Skan [(call (mem (match_operand 0 "call_operand" "")) 5856117395Skan (const_int 1)) 5857117395Skan (clobber (match_operand:DI 1 "register_operand" "")) 5858117395Skan (clobber (match_scratch:DI 2 "")) 5859117395Skan (clobber (match_scratch:DI 3 ""))] 5860117395Skan "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)" 5861117395Skan [(const_int 0)] 5862117395Skan{ 5863117395Skan ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2], 5864117395Skan operands[3], true, false); 5865117395Skan DONE; 5866117395Skan}) 5867117395Skan 5868117395Skan(define_split 5869117395Skan [(call (mem (match_operand 0 "call_operand" "")) 5870117395Skan (const_int 1)) 5871117395Skan (clobber (match_operand:DI 1 "register_operand" "")) 5872117395Skan (clobber (match_scratch:DI 2 "")) 5873117395Skan (clobber (match_scratch:DI 3 ""))] 5874117395Skan "reload_completed" 5875117395Skan [(const_int 0)] 5876117395Skan{ 5877117395Skan ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2], 5878117395Skan operands[3], false, false); 5879117395Skan DONE; 5880117395Skan}) 5881117395Skan 5882117395Skan(define_insn "call_value_gp" 5883132718Skan [(set (match_operand 0 "" "=X,X") 5884117395Skan (call (mem:DI (match_operand:DI 1 "call_operand" "?r,i")) 5885117395Skan (const_int 1))) 5886117395Skan (clobber (match_operand:DI 2 "register_operand" "=b,b")) 5887117395Skan (clobber (match_scratch:DI 3 "=&r,X")) 5888117395Skan (clobber (match_scratch:DI 4 "=b,X"))] 588990075Sobrien "" 5890117395Skan "#" 589190075Sobrien [(set_attr "itanium_class" "br,scall")]) 589290075Sobrien 5893117395Skan(define_split 5894117395Skan [(set (match_operand 0 "" "") 5895117395Skan (call (mem:DI (match_operand:DI 1 "call_operand" "")) 5896117395Skan (const_int 1))) 5897117395Skan (clobber (match_operand:DI 2 "register_operand" "")) 5898117395Skan (clobber (match_scratch:DI 3 "")) 5899117395Skan (clobber (match_scratch:DI 4 ""))] 5900117395Skan "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)" 5901117395Skan [(const_int 0)] 5902117395Skan{ 5903117395Skan ia64_split_call (operands[0], operands[1], operands[2], operands[3], 5904117395Skan operands[4], true, false); 5905117395Skan DONE; 5906117395Skan}) 5907117395Skan 5908117395Skan(define_split 5909117395Skan [(set (match_operand 0 "" "") 5910117395Skan (call (mem:DI (match_operand:DI 1 "call_operand" "")) 5911117395Skan (const_int 1))) 5912117395Skan (clobber (match_operand:DI 2 "register_operand" "")) 5913117395Skan (clobber (match_scratch:DI 3 "")) 5914117395Skan (clobber (match_scratch:DI 4 ""))] 5915117395Skan "reload_completed" 5916117395Skan [(const_int 0)] 5917117395Skan{ 5918117395Skan ia64_split_call (operands[0], operands[1], operands[2], operands[3], 5919117395Skan operands[4], false, false); 5920117395Skan DONE; 5921117395Skan}) 5922117395Skan 5923117395Skan(define_insn_and_split "sibcall_gp" 5924117395Skan [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,i")) 5925117395Skan (const_int 1)) 5926117395Skan (clobber (match_scratch:DI 1 "=&r,X")) 5927117395Skan (clobber (match_scratch:DI 2 "=b,X"))] 592890075Sobrien "" 5929117395Skan "#" 5930117395Skan "reload_completed" 5931117395Skan [(const_int 0)] 5932117395Skan{ 5933117395Skan ia64_split_call (NULL_RTX, operands[0], NULL_RTX, operands[1], 5934117395Skan operands[2], true, true); 5935117395Skan DONE; 5936117395Skan} 593790075Sobrien [(set_attr "itanium_class" "br")]) 593890075Sobrien 593990075Sobrien(define_insn "return_internal" 594090075Sobrien [(return) 594190075Sobrien (use (match_operand:DI 0 "register_operand" "b"))] 594290075Sobrien "" 594390075Sobrien "br.ret.sptk.many %0" 594490075Sobrien [(set_attr "itanium_class" "br")]) 594590075Sobrien 594690075Sobrien(define_insn "return" 594790075Sobrien [(return)] 594890075Sobrien "ia64_direct_return ()" 594990075Sobrien "br.ret.sptk.many rp" 595090075Sobrien [(set_attr "itanium_class" "br")]) 595190075Sobrien 595290075Sobrien(define_insn "*return_true" 595390075Sobrien [(set (pc) 595490075Sobrien (if_then_else (match_operator 0 "predicate_operator" 595590075Sobrien [(match_operand:BI 1 "register_operand" "c") 595690075Sobrien (const_int 0)]) 595790075Sobrien (return) 595890075Sobrien (pc)))] 595990075Sobrien "ia64_direct_return ()" 596090075Sobrien "(%J0) br.ret%+.many rp" 596190075Sobrien [(set_attr "itanium_class" "br") 596290075Sobrien (set_attr "predicable" "no")]) 596390075Sobrien 596490075Sobrien(define_insn "*return_false" 596590075Sobrien [(set (pc) 596690075Sobrien (if_then_else (match_operator 0 "predicate_operator" 596790075Sobrien [(match_operand:BI 1 "register_operand" "c") 596890075Sobrien (const_int 0)]) 596990075Sobrien (pc) 597090075Sobrien (return)))] 597190075Sobrien "ia64_direct_return ()" 597290075Sobrien "(%j0) br.ret%+.many rp" 597390075Sobrien [(set_attr "itanium_class" "br") 597490075Sobrien (set_attr "predicable" "no")]) 597590075Sobrien 597690075Sobrien(define_insn "jump" 597790075Sobrien [(set (pc) (label_ref (match_operand 0 "" "")))] 597890075Sobrien "" 597990075Sobrien "br %l0" 598090075Sobrien [(set_attr "itanium_class" "br")]) 598190075Sobrien 598290075Sobrien(define_insn "indirect_jump" 598390075Sobrien [(set (pc) (match_operand:DI 0 "register_operand" "b"))] 598490075Sobrien "" 598590075Sobrien "br %0" 598690075Sobrien [(set_attr "itanium_class" "br")]) 598790075Sobrien 598890075Sobrien(define_expand "tablejump" 598990075Sobrien [(parallel [(set (pc) (match_operand:DI 0 "memory_operand" "")) 599090075Sobrien (use (label_ref (match_operand 1 "" "")))])] 599190075Sobrien "" 599290075Sobrien{ 599390075Sobrien rtx op0 = operands[0]; 599490075Sobrien rtx addr; 599590075Sobrien 599690075Sobrien /* ??? Bother -- do_tablejump is "helpful" and pulls the table 599790075Sobrien element into a register without bothering to see whether that 599890075Sobrien is necessary given the operand predicate. Check for MEM just 599990075Sobrien in case someone fixes this. */ 600090075Sobrien if (GET_CODE (op0) == MEM) 600190075Sobrien addr = XEXP (op0, 0); 600290075Sobrien else 600390075Sobrien { 600490075Sobrien /* Otherwise, cheat and guess that the previous insn in the 600590075Sobrien stream was the memory load. Grab the address from that. 600690075Sobrien Note we have to momentarily pop out of the sequence started 600790075Sobrien by the insn-emit wrapper in order to grab the last insn. */ 600890075Sobrien rtx last, set; 600990075Sobrien 601090075Sobrien end_sequence (); 601190075Sobrien last = get_last_insn (); 601290075Sobrien start_sequence (); 601390075Sobrien set = single_set (last); 601490075Sobrien 6015169689Skan gcc_assert (rtx_equal_p (SET_DEST (set), op0) 6016169689Skan && GET_CODE (SET_SRC (set)) == MEM); 601790075Sobrien addr = XEXP (SET_SRC (set), 0); 6018169689Skan gcc_assert (!rtx_equal_p (addr, op0)); 601990075Sobrien } 602090075Sobrien 602190075Sobrien /* Jump table elements are stored pc-relative. That is, a displacement 602290075Sobrien from the entry to the label. Thus to convert to an absolute address 602390075Sobrien we add the address of the memory from which the value is loaded. */ 602490075Sobrien operands[0] = expand_simple_binop (DImode, PLUS, op0, addr, 602590075Sobrien NULL_RTX, 1, OPTAB_DIRECT); 602690075Sobrien}) 602790075Sobrien 602890075Sobrien(define_insn "*tablejump_internal" 602990075Sobrien [(set (pc) (match_operand:DI 0 "register_operand" "b")) 603090075Sobrien (use (label_ref (match_operand 1 "" "")))] 603190075Sobrien "" 603290075Sobrien "br %0" 603390075Sobrien [(set_attr "itanium_class" "br")]) 603490075Sobrien 603590075Sobrien 603690075Sobrien;; :::::::::::::::::::: 603790075Sobrien;; :: 603890075Sobrien;; :: Prologue and Epilogue instructions 603990075Sobrien;; :: 604090075Sobrien;; :::::::::::::::::::: 604190075Sobrien 604290075Sobrien(define_expand "prologue" 604390075Sobrien [(const_int 1)] 604490075Sobrien "" 604590075Sobrien{ 604690075Sobrien ia64_expand_prologue (); 604790075Sobrien DONE; 6048117395Skan}) 604990075Sobrien 605090075Sobrien(define_expand "epilogue" 605190075Sobrien [(return)] 605290075Sobrien "" 605390075Sobrien{ 605490075Sobrien ia64_expand_epilogue (0); 605590075Sobrien DONE; 6056117395Skan}) 605790075Sobrien 605890075Sobrien(define_expand "sibcall_epilogue" 605990075Sobrien [(return)] 606090075Sobrien "" 606190075Sobrien{ 606290075Sobrien ia64_expand_epilogue (1); 606390075Sobrien DONE; 6064117395Skan}) 606590075Sobrien 606690075Sobrien;; This prevents the scheduler from moving the SP decrement past FP-relative 606790075Sobrien;; stack accesses. This is the same as adddi3 plus the extra set. 606890075Sobrien 606990075Sobrien(define_insn "prologue_allocate_stack" 607090075Sobrien [(set (match_operand:DI 0 "register_operand" "=r,r,r") 607190075Sobrien (plus:DI (match_operand:DI 1 "register_operand" "%r,r,a") 607290075Sobrien (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J"))) 607396263Sobrien (set (match_operand:DI 3 "register_operand" "+r,r,r") 607490075Sobrien (match_dup 3))] 607590075Sobrien "" 607690075Sobrien "@ 6077117395Skan add %0 = %1, %2 6078117395Skan adds %0 = %2, %1 6079117395Skan addl %0 = %2, %1" 608090075Sobrien [(set_attr "itanium_class" "ialu")]) 608190075Sobrien 608290075Sobrien;; This prevents the scheduler from moving the SP restore past FP-relative 608390075Sobrien;; stack accesses. This is similar to movdi plus the extra set. 608490075Sobrien 608590075Sobrien(define_insn "epilogue_deallocate_stack" 608690075Sobrien [(set (match_operand:DI 0 "register_operand" "=r") 608790075Sobrien (match_operand:DI 1 "register_operand" "+r")) 608890075Sobrien (set (match_dup 1) (match_dup 1))] 608990075Sobrien "" 609090075Sobrien "mov %0 = %1" 609190075Sobrien [(set_attr "itanium_class" "ialu")]) 609290075Sobrien 6093117395Skan;; As USE insns aren't meaningful after reload, this is used instead 6094117395Skan;; to prevent deleting instructions setting registers for EH handling 6095117395Skan(define_insn "prologue_use" 6096117395Skan [(unspec:DI [(match_operand:DI 0 "register_operand" "")] 6097117395Skan UNSPEC_PROLOGUE_USE)] 6098117395Skan "" 6099117395Skan "" 6100117395Skan [(set_attr "itanium_class" "ignore") 6101132718Skan (set_attr "predicable" "no") 6102132718Skan (set_attr "empty" "yes")]) 6103117395Skan 610490075Sobrien;; Allocate a new register frame. 610590075Sobrien 610690075Sobrien(define_insn "alloc" 610790075Sobrien [(set (match_operand:DI 0 "register_operand" "=r") 6108117395Skan (unspec_volatile:DI [(const_int 0)] UNSPECV_ALLOC)) 610990075Sobrien (use (match_operand:DI 1 "const_int_operand" "i")) 611090075Sobrien (use (match_operand:DI 2 "const_int_operand" "i")) 611190075Sobrien (use (match_operand:DI 3 "const_int_operand" "i")) 611290075Sobrien (use (match_operand:DI 4 "const_int_operand" "i"))] 611390075Sobrien "" 611490075Sobrien "alloc %0 = ar.pfs, %1, %2, %3, %4" 611590075Sobrien [(set_attr "itanium_class" "syst_m0") 6116169689Skan (set_attr "predicable" "no") 6117169689Skan (set_attr "first_insn" "yes")]) 611890075Sobrien 611990075Sobrien;; Modifies ar.unat 612090075Sobrien(define_expand "gr_spill" 612190075Sobrien [(parallel [(set (match_operand:DI 0 "memory_operand" "=m") 612290075Sobrien (unspec:DI [(match_operand:DI 1 "register_operand" "r") 6123117395Skan (match_operand:DI 2 "const_int_operand" "")] 6124117395Skan UNSPEC_GR_SPILL)) 612590075Sobrien (clobber (match_dup 3))])] 612690075Sobrien "" 612790075Sobrien "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);") 612890075Sobrien 612990075Sobrien(define_insn "gr_spill_internal" 6130169689Skan [(set (match_operand:DI 0 "destination_operand" "=m") 613190075Sobrien (unspec:DI [(match_operand:DI 1 "register_operand" "r") 6132117395Skan (match_operand:DI 2 "const_int_operand" "")] 6133117395Skan UNSPEC_GR_SPILL)) 613490075Sobrien (clobber (match_operand:DI 3 "register_operand" ""))] 613590075Sobrien "" 613690075Sobrien{ 6137117395Skan /* Note that we use a C output pattern here to avoid the predicate 6138117395Skan being automatically added before the .mem.offset directive. */ 6139117395Skan return ".mem.offset %2, 0\;%,st8.spill %0 = %1%P0"; 6140117395Skan} 614190075Sobrien [(set_attr "itanium_class" "st")]) 614290075Sobrien 614390075Sobrien;; Reads ar.unat 614490075Sobrien(define_expand "gr_restore" 614590075Sobrien [(parallel [(set (match_operand:DI 0 "register_operand" "=r") 614690075Sobrien (unspec:DI [(match_operand:DI 1 "memory_operand" "m") 6147117395Skan (match_operand:DI 2 "const_int_operand" "")] 6148117395Skan UNSPEC_GR_RESTORE)) 614990075Sobrien (use (match_dup 3))])] 615090075Sobrien "" 615190075Sobrien "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);") 615290075Sobrien 615390075Sobrien(define_insn "gr_restore_internal" 615490075Sobrien [(set (match_operand:DI 0 "register_operand" "=r") 615590075Sobrien (unspec:DI [(match_operand:DI 1 "memory_operand" "m") 6156117395Skan (match_operand:DI 2 "const_int_operand" "")] 6157117395Skan UNSPEC_GR_RESTORE)) 615890075Sobrien (use (match_operand:DI 3 "register_operand" ""))] 615990075Sobrien "" 6160117395Skan { return ".mem.offset %2, 0\;%,ld8.fill %0 = %1%P1"; } 616190075Sobrien [(set_attr "itanium_class" "ld")]) 616290075Sobrien 616390075Sobrien(define_insn "fr_spill" 6164169689Skan [(set (match_operand:XF 0 "destination_operand" "=m") 6165132718Skan (unspec:XF [(match_operand:XF 1 "register_operand" "f")] 6166117395Skan UNSPEC_FR_SPILL))] 616790075Sobrien "" 616890075Sobrien "stf.spill %0 = %1%P0" 616990075Sobrien [(set_attr "itanium_class" "stf")]) 617090075Sobrien 617190075Sobrien(define_insn "fr_restore" 6172132718Skan [(set (match_operand:XF 0 "register_operand" "=f") 6173132718Skan (unspec:XF [(match_operand:XF 1 "memory_operand" "m")] 6174117395Skan UNSPEC_FR_RESTORE))] 617590075Sobrien "" 617690075Sobrien "ldf.fill %0 = %1%P1" 617790075Sobrien [(set_attr "itanium_class" "fld")]) 617890075Sobrien 617990075Sobrien;; ??? The explicit stop is not ideal. It would be better if 618090075Sobrien;; rtx_needs_barrier took care of this, but this is something that can be 618190075Sobrien;; fixed later. This avoids an RSE DV. 618290075Sobrien 618390075Sobrien(define_insn "bsp_value" 618490075Sobrien [(set (match_operand:DI 0 "register_operand" "=r") 6185117395Skan (unspec:DI [(const_int 0)] UNSPEC_BSP_VALUE))] 618690075Sobrien "" 6187117395Skan "* 6188117395Skan{ 6189117395Skan return \";;\;%,mov %0 = ar.bsp\"; 6190117395Skan}" 619190075Sobrien [(set_attr "itanium_class" "frar_i")]) 619290075Sobrien 619390075Sobrien(define_insn "set_bsp" 6194117395Skan [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")] 6195117395Skan UNSPECV_SET_BSP)] 619690075Sobrien "" 6197117395Skan "flushrs 6198117395Skan mov r19=ar.rsc 6199117395Skan ;; 6200117395Skan and r19=0x1c,r19 6201117395Skan ;; 6202117395Skan mov ar.rsc=r19 6203117395Skan ;; 6204117395Skan mov ar.bspstore=%0 6205117395Skan ;; 6206117395Skan or r19=0x3,r19 6207117395Skan ;; 6208117395Skan loadrs 6209117395Skan invala 6210117395Skan ;; 6211117395Skan mov ar.rsc=r19" 621290075Sobrien [(set_attr "itanium_class" "unknown") 621390075Sobrien (set_attr "predicable" "no")]) 621490075Sobrien 621590075Sobrien;; ??? The explicit stops are not ideal. It would be better if 621690075Sobrien;; rtx_needs_barrier took care of this, but this is something that can be 621790075Sobrien;; fixed later. This avoids an RSE DV. 621890075Sobrien 621990075Sobrien(define_insn "flushrs" 6220117395Skan [(unspec [(const_int 0)] UNSPEC_FLUSHRS)] 622190075Sobrien "" 622290075Sobrien ";;\;flushrs\;;;" 6223117395Skan [(set_attr "itanium_class" "rse_m") 6224117395Skan (set_attr "predicable" "no")]) 622590075Sobrien 622690075Sobrien;; :::::::::::::::::::: 622790075Sobrien;; :: 622890075Sobrien;; :: Miscellaneous instructions 622990075Sobrien;; :: 623090075Sobrien;; :::::::::::::::::::: 623190075Sobrien 6232132718Skan;; ??? Emitting a NOP instruction isn't very useful. This should probably 623390075Sobrien;; be emitting ";;" to force a break in the instruction packing. 623490075Sobrien 623590075Sobrien;; No operation, needed in case the user uses -g but not -O. 623690075Sobrien(define_insn "nop" 623790075Sobrien [(const_int 0)] 623890075Sobrien "" 623990075Sobrien "nop 0" 6240132718Skan [(set_attr "itanium_class" "nop")]) 624190075Sobrien 624290075Sobrien(define_insn "nop_m" 624390075Sobrien [(const_int 1)] 624490075Sobrien "" 624590075Sobrien "nop.m 0" 624690075Sobrien [(set_attr "itanium_class" "nop_m")]) 624790075Sobrien 624890075Sobrien(define_insn "nop_i" 624990075Sobrien [(const_int 2)] 625090075Sobrien "" 625190075Sobrien "nop.i 0" 625290075Sobrien [(set_attr "itanium_class" "nop_i")]) 625390075Sobrien 625490075Sobrien(define_insn "nop_f" 625590075Sobrien [(const_int 3)] 625690075Sobrien "" 625790075Sobrien "nop.f 0" 625890075Sobrien [(set_attr "itanium_class" "nop_f")]) 625990075Sobrien 626090075Sobrien(define_insn "nop_b" 626190075Sobrien [(const_int 4)] 626290075Sobrien "" 626390075Sobrien "nop.b 0" 626490075Sobrien [(set_attr "itanium_class" "nop_b")]) 626590075Sobrien 626690075Sobrien(define_insn "nop_x" 626790075Sobrien [(const_int 5)] 626890075Sobrien "" 626990075Sobrien "" 6270132718Skan [(set_attr "itanium_class" "nop_x") 6271132718Skan (set_attr "empty" "yes")]) 627290075Sobrien 6273132718Skan;; The following insn will be never generated. It is used only by 6274132718Skan;; insn scheduler to change state before advancing cycle. 6275132718Skan(define_insn "pre_cycle" 6276132718Skan [(const_int 6)] 6277132718Skan "" 6278132718Skan "" 6279132718Skan [(set_attr "itanium_class" "pre_cycle")]) 6280132718Skan 628190075Sobrien(define_insn "bundle_selector" 6282117395Skan [(unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BUNDLE_SELECTOR)] 628390075Sobrien "" 6284117395Skan { return get_bundle_name (INTVAL (operands[0])); } 628590075Sobrien [(set_attr "itanium_class" "ignore") 628690075Sobrien (set_attr "predicable" "no")]) 628790075Sobrien 628890075Sobrien;; Pseudo instruction that prevents the scheduler from moving code above this 628990075Sobrien;; point. 629090075Sobrien(define_insn "blockage" 6291117395Skan [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 629290075Sobrien "" 629390075Sobrien "" 629490075Sobrien [(set_attr "itanium_class" "ignore") 629590075Sobrien (set_attr "predicable" "no")]) 629690075Sobrien 629790075Sobrien(define_insn "insn_group_barrier" 6298117395Skan [(unspec_volatile [(match_operand 0 "const_int_operand" "")] 6299117395Skan UNSPECV_INSN_GROUP_BARRIER)] 630090075Sobrien "" 630190075Sobrien ";;" 630290075Sobrien [(set_attr "itanium_class" "stop_bit") 6303132718Skan (set_attr "predicable" "no") 6304132718Skan (set_attr "empty" "yes")]) 630590075Sobrien 630696263Sobrien(define_expand "trap" 630796263Sobrien [(trap_if (const_int 1) (const_int 0))] 630896263Sobrien "" 630996263Sobrien "") 631096263Sobrien 631196263Sobrien;; ??? We don't have a match-any slot type. Setting the type to unknown 631296263Sobrien;; produces worse code that setting the slot type to A. 631396263Sobrien 631496263Sobrien(define_insn "*trap" 631596263Sobrien [(trap_if (const_int 1) (match_operand 0 "const_int_operand" ""))] 631696263Sobrien "" 631796263Sobrien "break %0" 6318169689Skan [(set_attr "itanium_class" "chk_s_i")]) 631996263Sobrien 632096263Sobrien(define_expand "conditional_trap" 632196263Sobrien [(trap_if (match_operand 0 "" "") (match_operand 1 "" ""))] 632296263Sobrien "" 632396263Sobrien{ 632496263Sobrien operands[0] = ia64_expand_compare (GET_CODE (operands[0]), VOIDmode); 632596263Sobrien}) 632696263Sobrien 632796263Sobrien(define_insn "*conditional_trap" 632896263Sobrien [(trap_if (match_operator 0 "predicate_operator" 632996263Sobrien [(match_operand:BI 1 "register_operand" "c") 633096263Sobrien (const_int 0)]) 633196263Sobrien (match_operand 2 "const_int_operand" ""))] 633296263Sobrien "" 633396263Sobrien "(%J0) break %2" 6334169689Skan [(set_attr "itanium_class" "chk_s_i") 633596263Sobrien (set_attr "predicable" "no")]) 633696263Sobrien 633790075Sobrien(define_insn "break_f" 6338117395Skan [(unspec_volatile [(const_int 0)] UNSPECV_BREAK)] 633990075Sobrien "" 634090075Sobrien "break.f 0" 634190075Sobrien [(set_attr "itanium_class" "nop_f")]) 634290075Sobrien 634390075Sobrien(define_insn "prefetch" 634490075Sobrien [(prefetch (match_operand:DI 0 "address_operand" "p") 634590075Sobrien (match_operand:DI 1 "const_int_operand" "n") 634690075Sobrien (match_operand:DI 2 "const_int_operand" "n"))] 634790075Sobrien "" 634890075Sobrien{ 634990075Sobrien static const char * const alt[2][4] = { 635090075Sobrien { 6351119256Skan "%,lfetch.nta [%0]", 6352119256Skan "%,lfetch.nt1 [%0]", 6353119256Skan "%,lfetch.nt2 [%0]", 6354119256Skan "%,lfetch [%0]" 635590075Sobrien }, 635690075Sobrien { 6357119256Skan "%,lfetch.excl.nta [%0]", 6358119256Skan "%,lfetch.excl.nt1 [%0]", 6359119256Skan "%,lfetch.excl.nt2 [%0]", 6360119256Skan "%,lfetch.excl [%0]" 636190075Sobrien } 636290075Sobrien }; 636390075Sobrien int i = (INTVAL (operands[1])); 636490075Sobrien int j = (INTVAL (operands[2])); 636590075Sobrien 6366169689Skan gcc_assert (i == 0 || i == 1); 6367169689Skan gcc_assert (j >= 0 && j <= 3); 636890075Sobrien return alt[i][j]; 636990075Sobrien} 637090075Sobrien [(set_attr "itanium_class" "lfetch")]) 637190075Sobrien 637290075Sobrien;; Non-local goto support. 637390075Sobrien 637490075Sobrien(define_expand "save_stack_nonlocal" 637590075Sobrien [(use (match_operand:OI 0 "memory_operand" "")) 637690075Sobrien (use (match_operand:DI 1 "register_operand" ""))] 637790075Sobrien "" 637890075Sobrien{ 637990075Sobrien emit_library_call (gen_rtx_SYMBOL_REF (Pmode, 638090075Sobrien \"__ia64_save_stack_nonlocal\"), 638190075Sobrien 0, VOIDmode, 2, XEXP (operands[0], 0), Pmode, 638290075Sobrien operands[1], Pmode); 638390075Sobrien DONE; 6384117395Skan}) 638590075Sobrien 638690075Sobrien(define_expand "nonlocal_goto" 638790075Sobrien [(use (match_operand 0 "general_operand" "")) 638890075Sobrien (use (match_operand 1 "general_operand" "")) 638990075Sobrien (use (match_operand 2 "general_operand" "")) 639090075Sobrien (use (match_operand 3 "general_operand" ""))] 639190075Sobrien "" 639290075Sobrien{ 639390075Sobrien emit_library_call (gen_rtx_SYMBOL_REF (Pmode, \"__ia64_nonlocal_goto\"), 639490075Sobrien LCT_NORETURN, VOIDmode, 3, 639590075Sobrien operands[1], Pmode, 639690075Sobrien copy_to_reg (XEXP (operands[2], 0)), Pmode, 639790075Sobrien operands[3], Pmode); 639890075Sobrien emit_barrier (); 639990075Sobrien DONE; 6400117395Skan}) 640190075Sobrien 6402117395Skan(define_insn_and_split "builtin_setjmp_receiver" 6403117395Skan [(unspec_volatile [(match_operand:DI 0 "" "")] UNSPECV_SETJMP_RECEIVER)] 640490075Sobrien "" 6405117395Skan "#" 6406117395Skan "reload_completed" 6407117395Skan [(const_int 0)] 640890075Sobrien{ 6409117395Skan ia64_reload_gp (); 641090075Sobrien DONE; 6411117395Skan}) 641290075Sobrien 641390075Sobrien(define_expand "eh_epilogue" 641490075Sobrien [(use (match_operand:DI 0 "register_operand" "r")) 641590075Sobrien (use (match_operand:DI 1 "register_operand" "r")) 641690075Sobrien (use (match_operand:DI 2 "register_operand" "r"))] 641790075Sobrien "" 641890075Sobrien{ 641990075Sobrien rtx bsp = gen_rtx_REG (Pmode, 10); 642090075Sobrien rtx sp = gen_rtx_REG (Pmode, 9); 642190075Sobrien 642290075Sobrien if (GET_CODE (operands[0]) != REG || REGNO (operands[0]) != 10) 642390075Sobrien { 642490075Sobrien emit_move_insn (bsp, operands[0]); 642590075Sobrien operands[0] = bsp; 642690075Sobrien } 642790075Sobrien if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 9) 642890075Sobrien { 642990075Sobrien emit_move_insn (sp, operands[2]); 643090075Sobrien operands[2] = sp; 643190075Sobrien } 643290075Sobrien emit_insn (gen_rtx_USE (VOIDmode, sp)); 643390075Sobrien emit_insn (gen_rtx_USE (VOIDmode, bsp)); 643490075Sobrien 643590075Sobrien cfun->machine->ia64_eh_epilogue_sp = sp; 643690075Sobrien cfun->machine->ia64_eh_epilogue_bsp = bsp; 6437117395Skan}) 643890075Sobrien 643990075Sobrien;; Builtin apply support. 644090075Sobrien 644190075Sobrien(define_expand "restore_stack_nonlocal" 644290075Sobrien [(use (match_operand:DI 0 "register_operand" "")) 644390075Sobrien (use (match_operand:OI 1 "memory_operand" ""))] 644490075Sobrien "" 644590075Sobrien{ 644690075Sobrien emit_library_call (gen_rtx_SYMBOL_REF (Pmode, 6447117395Skan "__ia64_restore_stack_nonlocal"), 644890075Sobrien 0, VOIDmode, 1, 644990075Sobrien copy_to_reg (XEXP (operands[1], 0)), Pmode); 645090075Sobrien DONE; 6451117395Skan}) 645290075Sobrien 645390075Sobrien 645490075Sobrien;; Predication. 645590075Sobrien 645690075Sobrien(define_cond_exec 645790075Sobrien [(match_operator 0 "predicate_operator" 645890075Sobrien [(match_operand:BI 1 "register_operand" "c") 645990075Sobrien (const_int 0)])] 646090075Sobrien "" 646190075Sobrien "(%J0)") 646290075Sobrien 646390075Sobrien(define_insn "pred_rel_mutex" 646490075Sobrien [(set (match_operand:BI 0 "register_operand" "+c") 6465117395Skan (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))] 646690075Sobrien "" 646790075Sobrien ".pred.rel.mutex %0, %I0" 646890075Sobrien [(set_attr "itanium_class" "ignore") 646990075Sobrien (set_attr "predicable" "no")]) 647090075Sobrien 647190075Sobrien(define_insn "safe_across_calls_all" 6472117395Skan [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_ALL)] 647390075Sobrien "" 647490075Sobrien ".pred.safe_across_calls p1-p63" 647590075Sobrien [(set_attr "itanium_class" "ignore") 647690075Sobrien (set_attr "predicable" "no")]) 647790075Sobrien 647890075Sobrien(define_insn "safe_across_calls_normal" 6479117395Skan [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_NORMAL)] 648090075Sobrien "" 648190075Sobrien{ 6482132718Skan emit_safe_across_calls (); 6483117395Skan return ""; 6484117395Skan} 648590075Sobrien [(set_attr "itanium_class" "ignore") 648690075Sobrien (set_attr "predicable" "no")]) 648790075Sobrien 648890075Sobrien;; UNSPEC instruction definition to "swizzle" 32 bit pointer into 64 bit 648990075Sobrien;; pointer. This is used by the HP-UX 32 bit mode. 649090075Sobrien 649190075Sobrien(define_insn "ptr_extend" 649290075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 6493117395Skan (unspec:DI [(match_operand:SI 1 "gr_register_operand" "r")] 6494117395Skan UNSPEC_ADDP4))] 649590075Sobrien "" 649690075Sobrien "addp4 %0 = 0,%1" 649790075Sobrien [(set_attr "itanium_class" "ialu")]) 649890075Sobrien 649990075Sobrien;; 6500117395Skan;; Optimizations for ptr_extend 6501117395Skan 6502132718Skan(define_insn "ptr_extend_plus_imm" 6503117395Skan [(set (match_operand:DI 0 "gr_register_operand" "=r") 6504117395Skan (unspec:DI 6505117395Skan [(plus:SI (match_operand:SI 1 "basereg_operand" "r") 6506117395Skan (match_operand:SI 2 "gr_reg_or_14bit_operand" "rI"))] 6507117395Skan UNSPEC_ADDP4))] 6508117395Skan "addp4_optimize_ok (operands[1], operands[2])" 6509117395Skan "addp4 %0 = %2, %1" 6510117395Skan [(set_attr "itanium_class" "ialu")]) 6511117395Skan 6512117395Skan(define_insn "*ptr_extend_plus_2" 6513117395Skan [(set (match_operand:DI 0 "gr_register_operand" "=r") 6514117395Skan (unspec:DI 6515117395Skan [(plus:SI (match_operand:SI 1 "gr_register_operand" "r") 6516117395Skan (match_operand:SI 2 "basereg_operand" "r"))] 6517117395Skan UNSPEC_ADDP4))] 6518117395Skan "addp4_optimize_ok (operands[1], operands[2])" 6519117395Skan "addp4 %0 = %1, %2" 6520117395Skan [(set_attr "itanium_class" "ialu")]) 6521169689Skan 6522169689Skan;; 6523169689Skan;; Get instruction pointer 6524169689Skan 6525169689Skan(define_insn "ip_value" 6526169689Skan [(set (match_operand:DI 0 "register_operand" "=r") 6527169689Skan (pc))] 6528169689Skan "" 6529169689Skan "mov %0 = ip" 6530169689Skan [(set_attr "itanium_class" "ialu")]) 6531169689Skan 6532169689Skan;; Vector operations 6533169689Skan(include "vect.md") 6534169689Skan;; Atomic operations 6535169689Skan(include "sync.md") 6536