ia64.md revision 117395
190075Sobrien;; IA-64 Machine description template 2117395Skan;; Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. 390075Sobrien;; Contributed by James E. Wilson <wilson@cygnus.com> and 490075Sobrien;; David Mosberger <davidm@hpl.hp.com>. 590075Sobrien 690075Sobrien;; This file is part of GNU CC. 790075Sobrien 890075Sobrien;; GNU CC is free software; you can redistribute it and/or modify 990075Sobrien;; it under the terms of the GNU General Public License as published by 1090075Sobrien;; the Free Software Foundation; either version 2, or (at your option) 1190075Sobrien;; any later version. 1290075Sobrien 1390075Sobrien;; GNU CC is distributed in the hope that it will be useful, 1490075Sobrien;; but WITHOUT ANY WARRANTY; without even the implied warranty of 1590075Sobrien;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1690075Sobrien;; GNU General Public License for more details. 1790075Sobrien 1890075Sobrien;; You should have received a copy of the GNU General Public License 1990075Sobrien;; along with GNU CC; see the file COPYING. If not, write to 2090075Sobrien;; the Free Software Foundation, 59 Temple Place - Suite 330, 2190075Sobrien;; Boston, MA 02111-1307, USA. 2290075Sobrien 2390075Sobrien;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. 2490075Sobrien 2590075Sobrien;; ??? register_operand accepts (subreg:DI (mem:SI X)) which forces later 2690075Sobrien;; reload. This will be fixed once scheduling support is turned on. 2790075Sobrien 2890075Sobrien;; ??? Optimize for post-increment addressing modes. 2990075Sobrien 3090075Sobrien;; ??? fselect is not supported, because there is no integer register 3190075Sobrien;; equivalent. 3290075Sobrien 3390075Sobrien;; ??? fp abs/min/max instructions may also work for integer values. 3490075Sobrien 3590075Sobrien;; ??? Would a predicate_reg_operand predicate be useful? The HP one is buggy, 3690075Sobrien;; it assumes the operand is a register and takes REGNO of it without checking. 3790075Sobrien 3890075Sobrien;; ??? Would a branch_reg_operand predicate be useful? The HP one is buggy, 3990075Sobrien;; it assumes the operand is a register and takes REGNO of it without checking. 4090075Sobrien 4190075Sobrien;; ??? Go through list of documented named patterns and look for more to 4290075Sobrien;; implement. 4390075Sobrien 4490075Sobrien;; ??? Go through instruction manual and look for more instructions that 4590075Sobrien;; can be emitted. 4690075Sobrien 4790075Sobrien;; ??? Add function unit scheduling info for Itanium (TM) processor. 4890075Sobrien 4990075Sobrien;; ??? Need a better way to describe alternate fp status registers. 5090075Sobrien 51117395Skan(define_constants 52117395Skan [; Relocations 53117395Skan (UNSPEC_LTOFF_DTPMOD 0) 54117395Skan (UNSPEC_LTOFF_DTPREL 1) 55117395Skan (UNSPEC_DTPREL 2) 56117395Skan (UNSPEC_LTOFF_TPREL 3) 57117395Skan (UNSPEC_TPREL 4) 58117395Skan 59117395Skan (UNSPEC_LD_BASE 9) 60117395Skan (UNSPEC_GR_SPILL 10) 61117395Skan (UNSPEC_GR_RESTORE 11) 62117395Skan (UNSPEC_FR_SPILL 12) 63117395Skan (UNSPEC_FR_RESTORE 13) 64117395Skan (UNSPEC_FR_RECIP_APPROX 14) 65117395Skan (UNSPEC_PRED_REL_MUTEX 15) 66117395Skan (UNSPEC_POPCNT 16) 67117395Skan (UNSPEC_PIC_CALL 17) 68117395Skan (UNSPEC_MF 18) 69117395Skan (UNSPEC_CMPXCHG_ACQ 19) 70117395Skan (UNSPEC_FETCHADD_ACQ 20) 71117395Skan (UNSPEC_BSP_VALUE 21) 72117395Skan (UNSPEC_FLUSHRS 22) 73117395Skan (UNSPEC_BUNDLE_SELECTOR 23) 74117395Skan (UNSPEC_ADDP4 24) 75117395Skan (UNSPEC_PROLOGUE_USE 25) 76117395Skan ]) 77117395Skan 78117395Skan(define_constants 79117395Skan [(UNSPECV_ALLOC 0) 80117395Skan (UNSPECV_BLOCKAGE 1) 81117395Skan (UNSPECV_INSN_GROUP_BARRIER 2) 82117395Skan (UNSPECV_BREAK 3) 83117395Skan (UNSPECV_SET_BSP 4) 84117395Skan (UNSPECV_PSAC_ALL 5) ; pred.safe_across_calls 85117395Skan (UNSPECV_PSAC_NORMAL 6) 86117395Skan (UNSPECV_SETJMP_RECEIVER 7) 87117395Skan ]) 8890075Sobrien 8990075Sobrien;; :::::::::::::::::::: 9090075Sobrien;; :: 9190075Sobrien;; :: Attributes 9290075Sobrien;; :: 9390075Sobrien;; :::::::::::::::::::: 9490075Sobrien 9590075Sobrien;; Instruction type. This primarily determines how instructions can be 9690075Sobrien;; packed in bundles, and secondarily affects scheduling to function units. 9790075Sobrien 9890075Sobrien;; A alu, can go in I or M syllable of a bundle 9990075Sobrien;; I integer 10090075Sobrien;; M memory 10190075Sobrien;; F floating-point 10290075Sobrien;; B branch 10390075Sobrien;; L long immediate, takes two syllables 10490075Sobrien;; S stop bit 10590075Sobrien 10690075Sobrien;; ??? Should not have any pattern with type unknown. Perhaps add code to 10790075Sobrien;; check this in md_reorg? Currently use unknown for patterns which emit 10890075Sobrien;; multiple instructions, patterns which emit 0 instructions, and patterns 10990075Sobrien;; which emit instruction that can go in any slot (e.g. nop). 11090075Sobrien 111117395Skan(define_attr "itanium_class" "unknown,ignore,stop_bit,br,fcmp,fcvtfx,fld, 112117395Skan fmac,fmisc,frar_i,frar_m,frbr,frfr,frpr,ialu,icmp,ilog,ishf,ld, 113117395Skan chk_s,long_i,mmmul,mmshf,mmshfi,rse_m,scall,sem,stf,st,syst_m0, 114117395Skan syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop_b,nop_f, 115117395Skan nop_i,nop_m,nop_x,lfetch" 116117395Skan (const_string "unknown")) 11790075Sobrien 11890075Sobrien;; chk_s has an I and an M form; use type A for convenience. 11990075Sobrien(define_attr "type" "unknown,A,I,M,F,B,L,X,S" 12090075Sobrien (cond [(eq_attr "itanium_class" "ld,st,fld,stf,sem,nop_m") (const_string "M") 12190075Sobrien (eq_attr "itanium_class" "rse_m,syst_m,syst_m0") (const_string "M") 12290075Sobrien (eq_attr "itanium_class" "frar_m,toar_m,frfr,tofr") (const_string "M") 12390075Sobrien (eq_attr "itanium_class" "lfetch") (const_string "M") 12490075Sobrien (eq_attr "itanium_class" "chk_s,ialu,icmp,ilog") (const_string "A") 12590075Sobrien (eq_attr "itanium_class" "fmisc,fmac,fcmp,xmpy") (const_string "F") 12690075Sobrien (eq_attr "itanium_class" "fcvtfx,nop_f") (const_string "F") 12790075Sobrien (eq_attr "itanium_class" "frar_i,toar_i,frbr,tobr") (const_string "I") 12890075Sobrien (eq_attr "itanium_class" "frpr,topr,ishf,xtd,tbit") (const_string "I") 12990075Sobrien (eq_attr "itanium_class" "mmmul,mmshf,mmshfi,nop_i") (const_string "I") 13090075Sobrien (eq_attr "itanium_class" "br,scall,nop_b") (const_string "B") 13190075Sobrien (eq_attr "itanium_class" "stop_bit") (const_string "S") 13290075Sobrien (eq_attr "itanium_class" "nop_x") (const_string "X") 13390075Sobrien (eq_attr "itanium_class" "long_i") (const_string "L")] 13490075Sobrien (const_string "unknown"))) 13590075Sobrien 13690075Sobrien(define_attr "itanium_requires_unit0" "no,yes" 13790075Sobrien (cond [(eq_attr "itanium_class" "syst_m0,sem,frfr,rse_m") (const_string "yes") 13890075Sobrien (eq_attr "itanium_class" "toar_m,frar_m") (const_string "yes") 13990075Sobrien (eq_attr "itanium_class" "frbr,tobr,mmmul") (const_string "yes") 14090075Sobrien (eq_attr "itanium_class" "tbit,ishf,topr,frpr") (const_string "yes") 14190075Sobrien (eq_attr "itanium_class" "toar_i,frar_i") (const_string "yes") 14290075Sobrien (eq_attr "itanium_class" "fmisc,fcmp") (const_string "yes")] 14390075Sobrien (const_string "no"))) 14490075Sobrien 14590075Sobrien;; Predication. True iff this instruction can be predicated. 14690075Sobrien 14790075Sobrien(define_attr "predicable" "no,yes" (const_string "yes")) 14890075Sobrien 14990075Sobrien 15090075Sobrien;; :::::::::::::::::::: 15190075Sobrien;; :: 15290075Sobrien;; :: Function Units 15390075Sobrien;; :: 15490075Sobrien;; :::::::::::::::::::: 15590075Sobrien 15690075Sobrien;; We define 6 "dummy" functional units. All the real work to decide which 15790075Sobrien;; insn uses which unit is done by our MD_SCHED_REORDER hooks. We only 15890075Sobrien;; have to ensure here that there are enough copies of the dummy unit so 15990075Sobrien;; that the scheduler doesn't get confused by MD_SCHED_REORDER. 16090075Sobrien;; Other than the 6 dummies for normal insns, we also add a single dummy unit 16190075Sobrien;; for stop bits. 16290075Sobrien 16390075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "br") 0 0) 16490075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "scall") 0 0) 16590075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fcmp") 2 0) 16690075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fcvtfx") 7 0) 16790075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fld") 9 0) 16890075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fmac") 5 0) 16990075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fmisc") 5 0) 17090075Sobrien 17190075Sobrien;; There is only one insn `mov = ar.bsp' for frar_i: 17290075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frar_i") 13 0) 17390075Sobrien;; There is only ony insn `mov = ar.unat' for frar_m: 17490075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frar_m") 6 0) 17590075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frbr") 2 0) 17690075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frfr") 2 0) 17790075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frpr") 2 0) 17890075Sobrien 17990075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ialu") 1 0) 18090075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "icmp") 1 0) 18190075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ilog") 1 0) 18290075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ishf") 1 0) 18390075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ld") 2 0) 18490075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "long_i") 1 0) 18590075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmmul") 2 0) 18690075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmshf") 2 0) 18790075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmshfi") 2 0) 18890075Sobrien 18990075Sobrien;; Now we have only one insn (flushrs) of such class. We assume that flushrs 19090075Sobrien;; is the 1st syllable of the bundle after stop bit. 19190075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "rse_m") 0 0) 19290075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "sem") 11 0) 19390075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "stf") 1 0) 19490075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "st") 1 0) 19590075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "syst_m0") 1 0) 19690075Sobrien;; Now we use only one insn `mf'. Therfore latency time is set up to 0. 19790075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "syst_m") 0 0) 19890075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tbit") 1 0) 19990075Sobrien 20090075Sobrien;; There is only one insn `mov ar.pfs =' for toar_i therefore we use 20190075Sobrien;; latency time equal to 0: 20290075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "toar_i") 0 0) 20390075Sobrien;; There are only ony 2 insns `mov ar.ccv =' and `mov ar.unat =' for toar_m: 20490075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "toar_m") 5 0) 20590075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tobr") 1 0) 20690075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tofr") 9 0) 20790075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "topr") 1 0) 20890075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "xmpy") 7 0) 20990075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "xtd") 1 0) 21090075Sobrien 21190075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_m") 0 0) 21290075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_i") 0 0) 21390075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_f") 0 0) 21490075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_b") 0 0) 21590075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_x") 0 0) 21690075Sobrien 21790075Sobrien(define_function_unit "stop_bit" 1 1 (eq_attr "itanium_class" "stop_bit") 0 0) 21890075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ignore") 0 0) 21990075Sobrien(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "unknown") 0 0) 22090075Sobrien 22190075Sobrien;; :::::::::::::::::::: 22290075Sobrien;; :: 22390075Sobrien;; :: Moves 22490075Sobrien;; :: 22590075Sobrien;; :::::::::::::::::::: 22690075Sobrien 22790075Sobrien;; Set of a single predicate register. This is only used to implement 22890075Sobrien;; pr-to-pr move and complement. 22990075Sobrien 23090075Sobrien(define_insn "*movcci" 23190075Sobrien [(set (match_operand:CCI 0 "register_operand" "=c,c,c") 23290075Sobrien (match_operand:CCI 1 "nonmemory_operand" "O,n,c"))] 23390075Sobrien "" 23490075Sobrien "@ 23590075Sobrien cmp.ne %0, p0 = r0, r0 23690075Sobrien cmp.eq %0, p0 = r0, r0 23790075Sobrien (%1) cmp.eq.unc %0, p0 = r0, r0" 23890075Sobrien [(set_attr "itanium_class" "icmp") 23990075Sobrien (set_attr "predicable" "no")]) 24090075Sobrien 24190075Sobrien(define_insn "movbi" 24290075Sobrien [(set (match_operand:BI 0 "nonimmediate_operand" "=c,c,?c,?*r, c,*r,*r,*m,*r") 24390075Sobrien (match_operand:BI 1 "move_operand" " O,n, c, c,*r, n,*m,*r,*r"))] 24490075Sobrien "" 24590075Sobrien "@ 24690075Sobrien cmp.ne %0, %I0 = r0, r0 24790075Sobrien cmp.eq %0, %I0 = r0, r0 24890075Sobrien # 24990075Sobrien # 25090075Sobrien tbit.nz %0, %I0 = %1, 0 25190075Sobrien adds %0 = %1, r0 25290075Sobrien ld1%O1 %0 = %1%P1 25390075Sobrien st1%Q0 %0 = %1%P0 25490075Sobrien mov %0 = %1" 25590075Sobrien [(set_attr "itanium_class" "icmp,icmp,unknown,unknown,tbit,ialu,ld,st,ialu")]) 25690075Sobrien 25790075Sobrien(define_split 25890075Sobrien [(set (match_operand:BI 0 "register_operand" "") 25990075Sobrien (match_operand:BI 1 "register_operand" ""))] 26090075Sobrien "reload_completed 26190075Sobrien && GET_CODE (operands[0]) == REG && GR_REGNO_P (REGNO (operands[0])) 26290075Sobrien && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))" 26390075Sobrien [(cond_exec (ne (match_dup 1) (const_int 0)) 26490075Sobrien (set (match_dup 0) (const_int 1))) 26590075Sobrien (cond_exec (eq (match_dup 1) (const_int 0)) 26690075Sobrien (set (match_dup 0) (const_int 0)))] 26790075Sobrien "") 26890075Sobrien 26990075Sobrien(define_split 27090075Sobrien [(set (match_operand:BI 0 "register_operand" "") 27190075Sobrien (match_operand:BI 1 "register_operand" ""))] 27290075Sobrien "reload_completed 27390075Sobrien && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0])) 27490075Sobrien && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))" 27590075Sobrien [(set (match_dup 2) (match_dup 4)) 27690075Sobrien (set (match_dup 3) (match_dup 5)) 277117395Skan (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))] 27890075Sobrien "operands[2] = gen_rtx_REG (CCImode, REGNO (operands[0])); 27990075Sobrien operands[3] = gen_rtx_REG (CCImode, REGNO (operands[0]) + 1); 28090075Sobrien operands[4] = gen_rtx_REG (CCImode, REGNO (operands[1])); 28190075Sobrien operands[5] = gen_rtx_REG (CCImode, REGNO (operands[1]) + 1);") 28290075Sobrien 28390075Sobrien(define_expand "movqi" 28490075Sobrien [(set (match_operand:QI 0 "general_operand" "") 28590075Sobrien (match_operand:QI 1 "general_operand" ""))] 28690075Sobrien "" 28790075Sobrien{ 288117395Skan rtx op1 = ia64_expand_move (operands[0], operands[1]); 289117395Skan if (!op1) 290117395Skan DONE; 291117395Skan operands[1] = op1; 292117395Skan}) 29390075Sobrien 29490075Sobrien(define_insn "*movqi_internal" 29590075Sobrien [(set (match_operand:QI 0 "destination_operand" "=r,r,r, m, r,*f,*f") 29690075Sobrien (match_operand:QI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))] 29790075Sobrien "ia64_move_ok (operands[0], operands[1])" 29890075Sobrien "@ 29990075Sobrien mov %0 = %r1 30090075Sobrien addl %0 = %1, r0 30190075Sobrien ld1%O1 %0 = %1%P1 30290075Sobrien st1%Q0 %0 = %r1%P0 30390075Sobrien getf.sig %0 = %1 30490075Sobrien setf.sig %0 = %r1 30590075Sobrien mov %0 = %1" 30690075Sobrien [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")]) 30790075Sobrien 30890075Sobrien(define_expand "movhi" 30990075Sobrien [(set (match_operand:HI 0 "general_operand" "") 31090075Sobrien (match_operand:HI 1 "general_operand" ""))] 31190075Sobrien "" 31290075Sobrien{ 313117395Skan rtx op1 = ia64_expand_move (operands[0], operands[1]); 314117395Skan if (!op1) 315117395Skan DONE; 316117395Skan operands[1] = op1; 317117395Skan}) 31890075Sobrien 31990075Sobrien(define_insn "*movhi_internal" 32090075Sobrien [(set (match_operand:HI 0 "destination_operand" "=r,r,r, m, r,*f,*f") 32190075Sobrien (match_operand:HI 1 "move_operand" "rO,J,m,rO,*f,rO,*f"))] 32290075Sobrien "ia64_move_ok (operands[0], operands[1])" 32390075Sobrien "@ 32490075Sobrien mov %0 = %r1 32590075Sobrien addl %0 = %1, r0 32690075Sobrien ld2%O1 %0 = %1%P1 32790075Sobrien st2%Q0 %0 = %r1%P0 32890075Sobrien getf.sig %0 = %1 32990075Sobrien setf.sig %0 = %r1 33090075Sobrien mov %0 = %1" 33190075Sobrien [(set_attr "itanium_class" "ialu,ialu,ld,st,frfr,tofr,fmisc")]) 33290075Sobrien 33390075Sobrien(define_expand "movsi" 33490075Sobrien [(set (match_operand:SI 0 "general_operand" "") 33590075Sobrien (match_operand:SI 1 "general_operand" ""))] 33690075Sobrien "" 33790075Sobrien{ 338117395Skan rtx op1 = ia64_expand_move (operands[0], operands[1]); 339117395Skan if (!op1) 340117395Skan DONE; 341117395Skan operands[1] = op1; 342117395Skan}) 34390075Sobrien 344117395Skan;; This is used during early compilation to delay the decision on 345117395Skan;; how to refer to a variable as long as possible. This is especially 346117395Skan;; important between initial rtl generation and optimization for 347117395Skan;; deferred functions, since we may acquire additional information 348117395Skan;; on the variables used in the meantime. 349117395Skan 350117395Skan(define_insn_and_split "movsi_symbolic" 351117395Skan [(set (match_operand:SI 0 "register_operand" "=r") 352117395Skan (match_operand:SI 1 "symbolic_operand" "s")) 353117395Skan (clobber (match_scratch:DI 2 "=r")) 354117395Skan (use (reg:DI 1))] 355117395Skan "" 356117395Skan "* abort ();" 357117395Skan "!no_new_pseudos || reload_completed" 358117395Skan [(const_int 0)] 359117395Skan{ 360117395Skan rtx scratch = operands[2]; 361117395Skan if (!reload_completed) 362117395Skan scratch = gen_reg_rtx (Pmode); 363117395Skan ia64_expand_load_address (operands[0], operands[1], scratch); 364117395Skan DONE; 365117395Skan}) 366117395Skan 36790075Sobrien(define_insn "*movsi_internal" 36890075Sobrien [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d") 36990075Sobrien (match_operand:SI 1 "move_operand" "rO,J,i,m,rO,*f,rO,*f,*d,rK"))] 37090075Sobrien "ia64_move_ok (operands[0], operands[1])" 37190075Sobrien "@ 37290075Sobrien mov %0 = %r1 37390075Sobrien addl %0 = %1, r0 37490075Sobrien movl %0 = %1 37590075Sobrien ld4%O1 %0 = %1%P1 37690075Sobrien st4%Q0 %0 = %r1%P0 37790075Sobrien getf.sig %0 = %1 37890075Sobrien setf.sig %0 = %r1 37990075Sobrien mov %0 = %1 38090075Sobrien mov %0 = %1 38190075Sobrien mov %0 = %r1" 382117395Skan ;; frar_m, toar_m ??? why not frar_i and toar_i 38390075Sobrien [(set_attr "itanium_class" "ialu,ialu,long_i,ld,st,frfr,tofr,fmisc,frar_m,toar_m")]) 38490075Sobrien 38590075Sobrien(define_expand "movdi" 38690075Sobrien [(set (match_operand:DI 0 "general_operand" "") 38790075Sobrien (match_operand:DI 1 "general_operand" ""))] 38890075Sobrien "" 38990075Sobrien{ 390117395Skan rtx op1 = ia64_expand_move (operands[0], operands[1]); 391117395Skan if (!op1) 392117395Skan DONE; 393117395Skan operands[1] = op1; 394117395Skan}) 39590075Sobrien 39690075Sobrien;; This is used during early compilation to delay the decision on 39790075Sobrien;; how to refer to a variable as long as possible. This is especially 39890075Sobrien;; important between initial rtl generation and optimization for 39990075Sobrien;; deferred functions, since we may acquire additional information 40090075Sobrien;; on the variables used in the meantime. 40190075Sobrien 40290075Sobrien(define_insn_and_split "movdi_symbolic" 40390075Sobrien [(set (match_operand:DI 0 "register_operand" "=r") 40490075Sobrien (match_operand:DI 1 "symbolic_operand" "s")) 405117395Skan (clobber (match_scratch:DI 2 "=r")) 40690075Sobrien (use (reg:DI 1))] 40790075Sobrien "" 40890075Sobrien "* abort ();" 409117395Skan "!no_new_pseudos || reload_completed" 41090075Sobrien [(const_int 0)] 411117395Skan{ 412117395Skan rtx scratch = operands[2]; 413117395Skan if (!reload_completed) 414117395Skan scratch = gen_reg_rtx (Pmode); 415117395Skan ia64_expand_load_address (operands[0], operands[1], scratch); 416117395Skan DONE; 417117395Skan}) 41890075Sobrien 41990075Sobrien(define_insn "*movdi_internal" 42090075Sobrien [(set (match_operand:DI 0 "destination_operand" 42190075Sobrien "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b, r,*e, r,*d, r,*c") 42290075Sobrien (match_operand:DI 1 "move_operand" 42390075Sobrien "rO,J,i,m,rO,*f,rO,*f, Q,*f,*b,rO,*e,rK,*d,rK,*c,rO"))] 42490075Sobrien "ia64_move_ok (operands[0], operands[1])" 42590075Sobrien{ 42690075Sobrien static const char * const alt[] = { 427117395Skan "%,mov %0 = %r1", 428117395Skan "%,addl %0 = %1, r0", 429117395Skan "%,movl %0 = %1", 430117395Skan "%,ld8%O1 %0 = %1%P1", 431117395Skan "%,st8%Q0 %0 = %r1%P0", 432117395Skan "%,getf.sig %0 = %1", 433117395Skan "%,setf.sig %0 = %r1", 434117395Skan "%,mov %0 = %1", 435117395Skan "%,ldf8 %0 = %1%P1", 436117395Skan "%,stf8 %0 = %1%P0", 437117395Skan "%,mov %0 = %1", 438117395Skan "%,mov %0 = %r1", 439117395Skan "%,mov %0 = %1", 440117395Skan "%,mov %0 = %1", 441117395Skan "%,mov %0 = %1", 442117395Skan "%,mov %0 = %1", 443117395Skan "mov %0 = pr", 444117395Skan "mov pr = %1, -1" 44590075Sobrien }; 44690075Sobrien 44790075Sobrien if (which_alternative == 2 && ! TARGET_NO_PIC 44890075Sobrien && symbolic_operand (operands[1], VOIDmode)) 44990075Sobrien abort (); 45090075Sobrien 45190075Sobrien return alt[which_alternative]; 452117395Skan} 45390075Sobrien [(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")]) 45490075Sobrien 45590075Sobrien(define_split 45690075Sobrien [(set (match_operand:DI 0 "register_operand" "") 45790075Sobrien (match_operand:DI 1 "symbolic_operand" ""))] 45890075Sobrien "reload_completed && ! TARGET_NO_PIC" 45990075Sobrien [(const_int 0)] 46090075Sobrien{ 46190075Sobrien ia64_expand_load_address (operands[0], operands[1], NULL_RTX); 46290075Sobrien DONE; 463117395Skan}) 46490075Sobrien 46590075Sobrien(define_expand "load_fptr" 46690075Sobrien [(set (match_dup 2) 467117395Skan (plus:DI (reg:DI 1) (match_operand 1 "function_operand" ""))) 46890075Sobrien (set (match_operand:DI 0 "register_operand" "") (match_dup 3))] 46990075Sobrien "" 47090075Sobrien{ 47190075Sobrien operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode); 47290075Sobrien operands[3] = gen_rtx_MEM (DImode, operands[2]); 47390075Sobrien RTX_UNCHANGING_P (operands[3]) = 1; 474117395Skan}) 47590075Sobrien 47690075Sobrien(define_insn "*load_fptr_internal1" 47790075Sobrien [(set (match_operand:DI 0 "register_operand" "=r") 478117395Skan (plus:DI (reg:DI 1) (match_operand 1 "function_operand" "s")))] 47990075Sobrien "" 48090075Sobrien "addl %0 = @ltoff(@fptr(%1)), gp" 48190075Sobrien [(set_attr "itanium_class" "ialu")]) 48290075Sobrien 48390075Sobrien(define_insn "load_gprel" 48490075Sobrien [(set (match_operand:DI 0 "register_operand" "=r") 485117395Skan (plus:DI (reg:DI 1) (match_operand 1 "sdata_symbolic_operand" "s")))] 48690075Sobrien "" 48790075Sobrien "addl %0 = @gprel(%1), gp" 48890075Sobrien [(set_attr "itanium_class" "ialu")]) 48990075Sobrien 49090075Sobrien(define_insn "gprel64_offset" 49190075Sobrien [(set (match_operand:DI 0 "register_operand" "=r") 49290075Sobrien (minus:DI (match_operand:DI 1 "symbolic_operand" "") (reg:DI 1)))] 49390075Sobrien "" 49490075Sobrien "movl %0 = @gprel(%1)" 49590075Sobrien [(set_attr "itanium_class" "long_i")]) 49690075Sobrien 49790075Sobrien(define_expand "load_gprel64" 49890075Sobrien [(set (match_dup 2) 49990075Sobrien (minus:DI (match_operand:DI 1 "symbolic_operand" "") (match_dup 3))) 50090075Sobrien (set (match_operand:DI 0 "register_operand" "") 50190075Sobrien (plus:DI (match_dup 3) (match_dup 2)))] 50290075Sobrien "" 50390075Sobrien{ 50490075Sobrien operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode); 50590075Sobrien operands[3] = pic_offset_table_rtx; 506117395Skan}) 50790075Sobrien 50890075Sobrien(define_expand "load_symptr" 50990075Sobrien [(set (match_operand:DI 2 "register_operand" "") 510117395Skan (plus:DI (high:DI (match_operand:DI 1 "got_symbolic_operand" "")) 511117395Skan (match_dup 3))) 512117395Skan (set (match_operand:DI 0 "register_operand" "") 513117395Skan (lo_sum:DI (match_dup 2) (match_dup 1)))] 51490075Sobrien "" 51590075Sobrien{ 516117395Skan operands[3] = pic_offset_table_rtx; 517117395Skan}) 51890075Sobrien 519117395Skan(define_insn "*load_symptr_high" 52090075Sobrien [(set (match_operand:DI 0 "register_operand" "=r") 521117395Skan (plus:DI (high:DI (match_operand 1 "got_symbolic_operand" "s")) 522117395Skan (match_operand:DI 2 "register_operand" "a")))] 52390075Sobrien "" 524117395Skan{ 525117395Skan if (HAVE_AS_LTOFFX_LDXMOV_RELOCS) 526117395Skan return "%,addl %0 = @ltoffx(%1), %2"; 527117395Skan else 528117395Skan return "%,addl %0 = @ltoff(%1), %2"; 529117395Skan} 53090075Sobrien [(set_attr "itanium_class" "ialu")]) 53190075Sobrien 532117395Skan(define_insn "*load_symptr_low" 533117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 534117395Skan (lo_sum:DI (match_operand:DI 1 "register_operand" "r") 535117395Skan (match_operand 2 "got_symbolic_operand" "s")))] 536117395Skan "" 537117395Skan{ 538117395Skan if (HAVE_AS_LTOFFX_LDXMOV_RELOCS) 539117395Skan return "%,ld8.mov %0 = [%1], %2"; 540117395Skan else 541117395Skan return "%,ld8 %0 = [%1]"; 542117395Skan} 543117395Skan [(set_attr "itanium_class" "ld")]) 544117395Skan 545117395Skan(define_insn "load_ltoff_dtpmod" 546117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 547117395Skan (plus:DI (reg:DI 1) 548117395Skan (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 549117395Skan UNSPEC_LTOFF_DTPMOD)))] 550117395Skan "" 551117395Skan "addl %0 = @ltoff(@dtpmod(%1)), gp" 552117395Skan [(set_attr "itanium_class" "ialu")]) 553117395Skan 554117395Skan(define_insn "load_ltoff_dtprel" 555117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 556117395Skan (plus:DI (reg:DI 1) 557117395Skan (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 558117395Skan UNSPEC_LTOFF_DTPREL)))] 559117395Skan "" 560117395Skan "addl %0 = @ltoff(@dtprel(%1)), gp" 561117395Skan [(set_attr "itanium_class" "ialu")]) 562117395Skan 563117395Skan(define_expand "load_dtprel" 564117395Skan [(set (match_operand:DI 0 "register_operand" "") 565117395Skan (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 566117395Skan UNSPEC_DTPREL))] 567117395Skan "" 568117395Skan "") 569117395Skan 570117395Skan(define_insn "*load_dtprel64" 571117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 572117395Skan (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 573117395Skan UNSPEC_DTPREL))] 574117395Skan "TARGET_TLS64" 575117395Skan "movl %0 = @dtprel(%1)" 576117395Skan [(set_attr "itanium_class" "long_i")]) 577117395Skan 578117395Skan(define_insn "*load_dtprel22" 579117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 580117395Skan (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 581117395Skan UNSPEC_DTPREL))] 582117395Skan "" 583117395Skan "addl %0 = @dtprel(%1), r0" 584117395Skan [(set_attr "itanium_class" "ialu")]) 585117395Skan 586117395Skan(define_expand "add_dtprel" 587117395Skan [(set (match_operand:DI 0 "register_operand" "") 588117395Skan (plus:DI (match_operand:DI 1 "register_operand" "") 589117395Skan (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 590117395Skan UNSPEC_DTPREL)))] 591117395Skan "!TARGET_TLS64" 592117395Skan "") 593117395Skan 594117395Skan(define_insn "*add_dtprel14" 595117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 596117395Skan (plus:DI (match_operand:DI 1 "register_operand" "r") 597117395Skan (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 598117395Skan UNSPEC_DTPREL)))] 599117395Skan "TARGET_TLS14" 600117395Skan "adds %0 = @dtprel(%2), %1" 601117395Skan [(set_attr "itanium_class" "ialu")]) 602117395Skan 603117395Skan(define_insn "*add_dtprel22" 604117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 605117395Skan (plus:DI (match_operand:DI 1 "register_operand" "a") 606117395Skan (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 607117395Skan UNSPEC_DTPREL)))] 608117395Skan "TARGET_TLS22" 609117395Skan "addl %0 = @dtprel(%2), %1" 610117395Skan [(set_attr "itanium_class" "ialu")]) 611117395Skan 612117395Skan(define_insn "load_ltoff_tprel" 613117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 614117395Skan (plus:DI (reg:DI 1) 615117395Skan (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 616117395Skan UNSPEC_LTOFF_TPREL)))] 617117395Skan "" 618117395Skan "addl %0 = @ltoff(@tprel(%1)), gp" 619117395Skan [(set_attr "itanium_class" "ialu")]) 620117395Skan 621117395Skan(define_expand "load_tprel" 622117395Skan [(set (match_operand:DI 0 "register_operand" "") 623117395Skan (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 624117395Skan UNSPEC_TPREL))] 625117395Skan "" 626117395Skan "") 627117395Skan 628117395Skan(define_insn "*load_tprel64" 629117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 630117395Skan (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 631117395Skan UNSPEC_TPREL))] 632117395Skan "TARGET_TLS64" 633117395Skan "movl %0 = @tprel(%1)" 634117395Skan [(set_attr "itanium_class" "long_i")]) 635117395Skan 636117395Skan(define_insn "*load_tprel22" 637117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 638117395Skan (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 639117395Skan UNSPEC_TPREL))] 640117395Skan "" 641117395Skan "addl %0 = @tprel(%1), r0" 642117395Skan [(set_attr "itanium_class" "ialu")]) 643117395Skan 644117395Skan(define_expand "add_tprel" 645117395Skan [(set (match_operand:DI 0 "register_operand" "") 646117395Skan (plus:DI (match_operand:DI 1 "register_operand" "") 647117395Skan (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 648117395Skan UNSPEC_TPREL)))] 649117395Skan "!TARGET_TLS64" 650117395Skan "") 651117395Skan 652117395Skan(define_insn "*add_tprel14" 653117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 654117395Skan (plus:DI (match_operand:DI 1 "register_operand" "r") 655117395Skan (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 656117395Skan UNSPEC_TPREL)))] 657117395Skan "TARGET_TLS14" 658117395Skan "adds %0 = @tprel(%2), %1" 659117395Skan [(set_attr "itanium_class" "ialu")]) 660117395Skan 661117395Skan(define_insn "*add_tprel22" 662117395Skan [(set (match_operand:DI 0 "register_operand" "=r") 663117395Skan (plus:DI (match_operand:DI 1 "register_operand" "a") 664117395Skan (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 665117395Skan UNSPEC_TPREL)))] 666117395Skan "TARGET_TLS22" 667117395Skan "addl %0 = @tprel(%2), %1" 668117395Skan [(set_attr "itanium_class" "ialu")]) 669117395Skan 67090075Sobrien;; With no offsettable memory references, we've got to have a scratch 67190075Sobrien;; around to play with the second word. 67290075Sobrien(define_expand "movti" 67390075Sobrien [(parallel [(set (match_operand:TI 0 "general_operand" "") 67490075Sobrien (match_operand:TI 1 "general_operand" "")) 67590075Sobrien (clobber (match_scratch:DI 2 ""))])] 67690075Sobrien "" 67790075Sobrien{ 678117395Skan rtx op1 = ia64_expand_move (operands[0], operands[1]); 679117395Skan if (!op1) 680117395Skan DONE; 681117395Skan operands[1] = op1; 682117395Skan}) 68390075Sobrien 68490075Sobrien(define_insn_and_split "*movti_internal" 68590075Sobrien [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m") 68690075Sobrien (match_operand:TI 1 "general_operand" "ri,m,r")) 68790075Sobrien (clobber (match_scratch:DI 2 "=X,&r,&r"))] 68890075Sobrien "ia64_move_ok (operands[0], operands[1])" 68990075Sobrien "#" 69090075Sobrien "reload_completed" 69190075Sobrien [(const_int 0)] 69290075Sobrien{ 69390075Sobrien rtx adj1, adj2, in[2], out[2], insn; 69490075Sobrien int first; 69590075Sobrien 69690075Sobrien adj1 = ia64_split_timode (in, operands[1], operands[2]); 69790075Sobrien adj2 = ia64_split_timode (out, operands[0], operands[2]); 69890075Sobrien 69990075Sobrien first = 0; 70090075Sobrien if (reg_overlap_mentioned_p (out[0], in[1])) 70190075Sobrien { 70290075Sobrien if (reg_overlap_mentioned_p (out[1], in[0])) 70390075Sobrien abort (); 70490075Sobrien first = 1; 70590075Sobrien } 70690075Sobrien 70790075Sobrien if (adj1 && adj2) 70890075Sobrien abort (); 70990075Sobrien if (adj1) 71090075Sobrien emit_insn (adj1); 71190075Sobrien if (adj2) 71290075Sobrien emit_insn (adj2); 71390075Sobrien insn = emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first])); 71490075Sobrien if (GET_CODE (out[first]) == MEM 71590075Sobrien && GET_CODE (XEXP (out[first], 0)) == POST_MODIFY) 71690075Sobrien REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, 71790075Sobrien XEXP (XEXP (out[first], 0), 0), 71890075Sobrien REG_NOTES (insn)); 71990075Sobrien insn = emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first])); 72090075Sobrien if (GET_CODE (out[!first]) == MEM 72190075Sobrien && GET_CODE (XEXP (out[!first], 0)) == POST_MODIFY) 72290075Sobrien REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, 72390075Sobrien XEXP (XEXP (out[!first], 0), 0), 72490075Sobrien REG_NOTES (insn)); 72590075Sobrien DONE; 726117395Skan} 72790075Sobrien [(set_attr "itanium_class" "unknown") 72890075Sobrien (set_attr "predicable" "no")]) 72990075Sobrien 73090075Sobrien;; ??? SSA creates these. Can't allow memories since we don't have 73190075Sobrien;; the scratch register. Fortunately combine will know how to add 73290075Sobrien;; the clobber and scratch. 73390075Sobrien(define_insn_and_split "*movti_internal_reg" 73490075Sobrien [(set (match_operand:TI 0 "register_operand" "=r") 73590075Sobrien (match_operand:TI 1 "nonmemory_operand" "ri"))] 73690075Sobrien "" 73790075Sobrien "#" 73890075Sobrien "reload_completed" 73990075Sobrien [(const_int 0)] 74090075Sobrien{ 74190075Sobrien rtx in[2], out[2]; 74290075Sobrien int first; 74390075Sobrien 74490075Sobrien ia64_split_timode (in, operands[1], NULL_RTX); 74590075Sobrien ia64_split_timode (out, operands[0], NULL_RTX); 74690075Sobrien 74790075Sobrien first = 0; 74890075Sobrien if (reg_overlap_mentioned_p (out[0], in[1])) 74990075Sobrien { 75090075Sobrien if (reg_overlap_mentioned_p (out[1], in[0])) 75190075Sobrien abort (); 75290075Sobrien first = 1; 75390075Sobrien } 75490075Sobrien 75590075Sobrien emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first])); 75690075Sobrien emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first])); 75790075Sobrien DONE; 758117395Skan} 75990075Sobrien [(set_attr "itanium_class" "unknown") 76090075Sobrien (set_attr "predicable" "no")]) 76190075Sobrien 76290075Sobrien(define_expand "reload_inti" 76390075Sobrien [(parallel [(set (match_operand:TI 0 "register_operand" "=r") 76490075Sobrien (match_operand:TI 1 "" "m")) 76590075Sobrien (clobber (match_operand:TI 2 "register_operand" "=&r"))])] 76690075Sobrien "" 76790075Sobrien{ 76890075Sobrien unsigned int s_regno = REGNO (operands[2]); 76990075Sobrien if (s_regno == REGNO (operands[0])) 77090075Sobrien s_regno += 1; 77190075Sobrien operands[2] = gen_rtx_REG (DImode, s_regno); 772117395Skan}) 77390075Sobrien 77490075Sobrien(define_expand "reload_outti" 77590075Sobrien [(parallel [(set (match_operand:TI 0 "" "=m") 77690075Sobrien (match_operand:TI 1 "register_operand" "r")) 77790075Sobrien (clobber (match_operand:TI 2 "register_operand" "=&r"))])] 77890075Sobrien "" 77990075Sobrien{ 78090075Sobrien unsigned int s_regno = REGNO (operands[2]); 78190075Sobrien if (s_regno == REGNO (operands[1])) 78290075Sobrien s_regno += 1; 78390075Sobrien operands[2] = gen_rtx_REG (DImode, s_regno); 784117395Skan}) 78590075Sobrien 78690075Sobrien;; Floating Point Moves 78790075Sobrien;; 78890075Sobrien;; Note - Patterns for SF mode moves are compulsory, but 789117395Skan;; patterns for DF are optional, as GCC can synthesize them. 79090075Sobrien 79190075Sobrien(define_expand "movsf" 79290075Sobrien [(set (match_operand:SF 0 "general_operand" "") 79390075Sobrien (match_operand:SF 1 "general_operand" ""))] 79490075Sobrien "" 79590075Sobrien{ 796117395Skan rtx op1 = ia64_expand_move (operands[0], operands[1]); 797117395Skan if (!op1) 798117395Skan DONE; 799117395Skan operands[1] = op1; 800117395Skan}) 80190075Sobrien 80290075Sobrien(define_insn "*movsf_internal" 80390075Sobrien [(set (match_operand:SF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m") 80490075Sobrien (match_operand:SF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))] 80590075Sobrien "ia64_move_ok (operands[0], operands[1])" 80690075Sobrien "@ 807117395Skan mov %0 = %F1 808117395Skan ldfs %0 = %1%P1 809117395Skan stfs %0 = %F1%P0 810117395Skan getf.s %0 = %F1 811117395Skan setf.s %0 = %1 812117395Skan mov %0 = %1 813117395Skan ld4%O1 %0 = %1%P1 814117395Skan st4%Q0 %0 = %1%P0" 81590075Sobrien [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")]) 81690075Sobrien 81790075Sobrien(define_expand "movdf" 81890075Sobrien [(set (match_operand:DF 0 "general_operand" "") 81990075Sobrien (match_operand:DF 1 "general_operand" ""))] 82090075Sobrien "" 82190075Sobrien{ 822117395Skan rtx op1 = ia64_expand_move (operands[0], operands[1]); 823117395Skan if (!op1) 824117395Skan DONE; 825117395Skan operands[1] = op1; 826117395Skan}) 82790075Sobrien 82890075Sobrien(define_insn "*movdf_internal" 82990075Sobrien [(set (match_operand:DF 0 "destination_operand" "=f,f, Q,*r, f,*r,*r, m") 83090075Sobrien (match_operand:DF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))] 83190075Sobrien "ia64_move_ok (operands[0], operands[1])" 83290075Sobrien "@ 833117395Skan mov %0 = %F1 834117395Skan ldfd %0 = %1%P1 835117395Skan stfd %0 = %F1%P0 836117395Skan getf.d %0 = %F1 837117395Skan setf.d %0 = %1 838117395Skan mov %0 = %1 839117395Skan ld8%O1 %0 = %1%P1 840117395Skan st8%Q0 %0 = %1%P0" 84190075Sobrien [(set_attr "itanium_class" "fmisc,fld,stf,frfr,tofr,ialu,ld,st")]) 84290075Sobrien 84390075Sobrien;; With no offsettable memory references, we've got to have a scratch 84490075Sobrien;; around to play with the second word if the variable winds up in GRs. 84590075Sobrien(define_expand "movtf" 84690075Sobrien [(set (match_operand:TF 0 "general_operand" "") 84790075Sobrien (match_operand:TF 1 "general_operand" ""))] 84890075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 84990075Sobrien{ 85090075Sobrien /* We must support TFmode loads into general registers for stdarg/vararg 85190075Sobrien and unprototyped calls. We split them into DImode loads for convenience. 85290075Sobrien We don't need TFmode stores from general regs, because a stdarg/vararg 85390075Sobrien routine does a block store to memory of unnamed arguments. */ 85490075Sobrien if (GET_CODE (operands[0]) == REG 85590075Sobrien && GR_REGNO_P (REGNO (operands[0]))) 85690075Sobrien { 85790075Sobrien /* We're hoping to transform everything that deals with TFmode 85890075Sobrien quantities and GR registers early in the compiler. */ 85990075Sobrien if (no_new_pseudos) 86090075Sobrien abort (); 86190075Sobrien 86290075Sobrien /* Struct to register can just use TImode instead. */ 86390075Sobrien if ((GET_CODE (operands[1]) == SUBREG 86490075Sobrien && GET_MODE (SUBREG_REG (operands[1])) == TImode) 86590075Sobrien || (GET_CODE (operands[1]) == REG 86690075Sobrien && GR_REGNO_P (REGNO (operands[1])))) 86790075Sobrien { 86890075Sobrien emit_move_insn (gen_rtx_REG (TImode, REGNO (operands[0])), 86990075Sobrien SUBREG_REG (operands[1])); 87090075Sobrien DONE; 87190075Sobrien } 87290075Sobrien 87390075Sobrien if (GET_CODE (operands[1]) == CONST_DOUBLE) 87490075Sobrien { 87590075Sobrien emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0])), 87690075Sobrien operand_subword (operands[1], 0, 0, TFmode)); 87790075Sobrien emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0]) + 1), 87890075Sobrien operand_subword (operands[1], 1, 0, TFmode)); 87990075Sobrien DONE; 88090075Sobrien } 88190075Sobrien 88290075Sobrien /* If the quantity is in a register not known to be GR, spill it. */ 88390075Sobrien if (register_operand (operands[1], TFmode)) 88490075Sobrien operands[1] = spill_tfmode_operand (operands[1], 1); 88590075Sobrien 88690075Sobrien if (GET_CODE (operands[1]) == MEM) 88790075Sobrien { 88890075Sobrien rtx out[2]; 88990075Sobrien 89090075Sobrien out[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0])); 89190075Sobrien out[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[0])+1); 89290075Sobrien 89390075Sobrien emit_move_insn (out[0], adjust_address (operands[1], DImode, 0)); 89490075Sobrien emit_move_insn (out[1], adjust_address (operands[1], DImode, 8)); 89590075Sobrien DONE; 89690075Sobrien } 89790075Sobrien 89890075Sobrien abort (); 89990075Sobrien } 90090075Sobrien 90190075Sobrien if (! reload_in_progress && ! reload_completed) 90290075Sobrien { 90390075Sobrien operands[0] = spill_tfmode_operand (operands[0], 0); 90490075Sobrien operands[1] = spill_tfmode_operand (operands[1], 0); 90590075Sobrien 90690075Sobrien if (! ia64_move_ok (operands[0], operands[1])) 90790075Sobrien operands[1] = force_reg (TFmode, operands[1]); 90890075Sobrien } 909117395Skan}) 91090075Sobrien 91190075Sobrien;; ??? There's no easy way to mind volatile acquire/release semantics. 91290075Sobrien 91390075Sobrien(define_insn "*movtf_internal" 91490075Sobrien [(set (match_operand:TF 0 "destination_tfmode_operand" "=f,f, m") 91590075Sobrien (match_operand:TF 1 "general_tfmode_operand" "fG,m,fG"))] 91690075Sobrien "INTEL_EXTENDED_IEEE_FORMAT && ia64_move_ok (operands[0], operands[1])" 91790075Sobrien "@ 918117395Skan mov %0 = %F1 919117395Skan ldfe %0 = %1%P1 920117395Skan stfe %0 = %F1%P0" 92190075Sobrien [(set_attr "itanium_class" "fmisc,fld,stf")]) 92290075Sobrien 92390075Sobrien;; :::::::::::::::::::: 92490075Sobrien;; :: 92590075Sobrien;; :: Conversions 92690075Sobrien;; :: 92790075Sobrien;; :::::::::::::::::::: 92890075Sobrien 92990075Sobrien;; Signed conversions from a smaller integer to a larger integer 93090075Sobrien 93190075Sobrien(define_insn "extendqidi2" 93290075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 93390075Sobrien (sign_extend:DI (match_operand:QI 1 "gr_register_operand" "r")))] 93490075Sobrien "" 93590075Sobrien "sxt1 %0 = %1" 93690075Sobrien [(set_attr "itanium_class" "xtd")]) 93790075Sobrien 93890075Sobrien(define_insn "extendhidi2" 93990075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 94090075Sobrien (sign_extend:DI (match_operand:HI 1 "gr_register_operand" "r")))] 94190075Sobrien "" 94290075Sobrien "sxt2 %0 = %1" 94390075Sobrien [(set_attr "itanium_class" "xtd")]) 94490075Sobrien 94590075Sobrien(define_insn "extendsidi2" 94690075Sobrien [(set (match_operand:DI 0 "grfr_register_operand" "=r,?f") 94790075Sobrien (sign_extend:DI (match_operand:SI 1 "grfr_register_operand" "r,f")))] 94890075Sobrien "" 94990075Sobrien "@ 95090075Sobrien sxt4 %0 = %1 95190075Sobrien fsxt.r %0 = %1, %1" 95290075Sobrien [(set_attr "itanium_class" "xtd,fmisc")]) 95390075Sobrien 95490075Sobrien;; Unsigned conversions from a smaller integer to a larger integer 95590075Sobrien 95690075Sobrien(define_insn "zero_extendqidi2" 95790075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r,r") 95890075Sobrien (zero_extend:DI (match_operand:QI 1 "gr_nonimmediate_operand" "r,m")))] 95990075Sobrien "" 96090075Sobrien "@ 96190075Sobrien zxt1 %0 = %1 96290075Sobrien ld1%O1 %0 = %1%P1" 96390075Sobrien [(set_attr "itanium_class" "xtd,ld")]) 96490075Sobrien 96590075Sobrien(define_insn "zero_extendhidi2" 96690075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r,r") 96790075Sobrien (zero_extend:DI (match_operand:HI 1 "gr_nonimmediate_operand" "r,m")))] 96890075Sobrien "" 96990075Sobrien "@ 97090075Sobrien zxt2 %0 = %1 97190075Sobrien ld2%O1 %0 = %1%P1" 97290075Sobrien [(set_attr "itanium_class" "xtd,ld")]) 97390075Sobrien 97490075Sobrien(define_insn "zero_extendsidi2" 97590075Sobrien [(set (match_operand:DI 0 "grfr_register_operand" "=r,r,?f") 97690075Sobrien (zero_extend:DI 97790075Sobrien (match_operand:SI 1 "grfr_nonimmediate_operand" "r,m,f")))] 97890075Sobrien "" 97990075Sobrien "@ 98090075Sobrien zxt4 %0 = %1 98190075Sobrien ld4%O1 %0 = %1%P1 98290075Sobrien fmix.r %0 = f0, %1" 98390075Sobrien [(set_attr "itanium_class" "xtd,ld,fmisc")]) 98490075Sobrien 98590075Sobrien;; Convert between floating point types of different sizes. 98690075Sobrien 98790075Sobrien;; At first glance, it would appear that emitting fnorm for an extending 98890075Sobrien;; conversion is unnecessary. However, the stf and getf instructions work 98990075Sobrien;; correctly only if the input is properly rounded for its type. In 99090075Sobrien;; particular, we get the wrong result for getf.d/stfd if the input is a 99190075Sobrien;; denorm single. Since we don't know what the next instruction will be, we 99290075Sobrien;; have to emit an fnorm. 99390075Sobrien 99490075Sobrien;; ??? Optimization opportunity here. Get rid of the insn altogether 99590075Sobrien;; when we can. Should probably use a scheme like has been proposed 99690075Sobrien;; for ia32 in dealing with operands that match unary operators. This 99790075Sobrien;; would let combine merge the thing into adjacent insns. See also how the 99890075Sobrien;; mips port handles SIGN_EXTEND as operands to integer arithmetic insns via 99990075Sobrien;; se_register_operand. 100090075Sobrien 100190075Sobrien(define_insn "extendsfdf2" 100290075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 100390075Sobrien (float_extend:DF (match_operand:SF 1 "fr_register_operand" "f")))] 100490075Sobrien "" 100590075Sobrien "fnorm.d %0 = %1" 100690075Sobrien [(set_attr "itanium_class" "fmac")]) 100790075Sobrien 100890075Sobrien(define_insn "extendsftf2" 100990075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "=f") 101090075Sobrien (float_extend:TF (match_operand:SF 1 "fr_register_operand" "f")))] 101190075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 101290075Sobrien "fnorm %0 = %1" 101390075Sobrien [(set_attr "itanium_class" "fmac")]) 101490075Sobrien 101590075Sobrien(define_insn "extenddftf2" 101690075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "=f") 101790075Sobrien (float_extend:TF (match_operand:DF 1 "fr_register_operand" "f")))] 101890075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 101990075Sobrien "fnorm %0 = %1" 102090075Sobrien [(set_attr "itanium_class" "fmac")]) 102190075Sobrien 102290075Sobrien(define_insn "truncdfsf2" 102390075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 102490075Sobrien (float_truncate:SF (match_operand:DF 1 "fr_register_operand" "f")))] 102590075Sobrien "" 102690075Sobrien "fnorm.s %0 = %1" 102790075Sobrien [(set_attr "itanium_class" "fmac")]) 102890075Sobrien 102990075Sobrien(define_insn "trunctfsf2" 103090075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 103190075Sobrien (float_truncate:SF (match_operand:TF 1 "fr_register_operand" "f")))] 103290075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 103390075Sobrien "fnorm.s %0 = %1" 103490075Sobrien [(set_attr "itanium_class" "fmac")]) 103590075Sobrien 103690075Sobrien(define_insn "trunctfdf2" 103790075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 103890075Sobrien (float_truncate:DF (match_operand:TF 1 "fr_register_operand" "f")))] 103990075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 104090075Sobrien "fnorm.d %0 = %1" 104190075Sobrien [(set_attr "itanium_class" "fmac")]) 104290075Sobrien 104390075Sobrien;; Convert between signed integer types and floating point. 104490075Sobrien 104590075Sobrien(define_insn "floatditf2" 104690075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "=f") 104790075Sobrien (float:TF (match_operand:DI 1 "fr_register_operand" "f")))] 104890075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 104990075Sobrien "fcvt.xf %0 = %1" 105090075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 105190075Sobrien 105290075Sobrien;; ??? Suboptimal. This should be split somehow. 105390075Sobrien(define_insn "floatdidf2" 105490075Sobrien [(set (match_operand:DF 0 "register_operand" "=f") 105590075Sobrien (float:DF (match_operand:DI 1 "register_operand" "f")))] 105690075Sobrien "!INTEL_EXTENDED_IEEE_FORMAT" 1057117395Skan "fcvt.xf %0 = %1\;;;\;%,fnorm.d %0 = %0" 105890075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 105990075Sobrien 106090075Sobrien;; ??? Suboptimal. This should be split somehow. 106190075Sobrien(define_insn "floatdisf2" 106290075Sobrien [(set (match_operand:SF 0 "register_operand" "=f") 106390075Sobrien (float:SF (match_operand:DI 1 "register_operand" "f")))] 106490075Sobrien "!INTEL_EXTENDED_IEEE_FORMAT" 1065117395Skan "fcvt.xf %0 = %1\;;;\;%,fnorm.s %0 = %0" 106690075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 106790075Sobrien 106890075Sobrien(define_insn "fix_truncsfdi2" 106990075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 107090075Sobrien (fix:DI (match_operand:SF 1 "fr_register_operand" "f")))] 107190075Sobrien "" 107290075Sobrien "fcvt.fx.trunc %0 = %1" 107390075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 107490075Sobrien 107590075Sobrien(define_insn "fix_truncdfdi2" 107690075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 107790075Sobrien (fix:DI (match_operand:DF 1 "fr_register_operand" "f")))] 107890075Sobrien "" 107990075Sobrien "fcvt.fx.trunc %0 = %1" 108090075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 108190075Sobrien 108290075Sobrien(define_insn "fix_trunctfdi2" 108390075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 108490075Sobrien (fix:DI (match_operand:TF 1 "fr_register_operand" "f")))] 108590075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 108690075Sobrien "fcvt.fx.trunc %0 = %1" 108790075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 108890075Sobrien 108990075Sobrien(define_insn "fix_trunctfdi2_alts" 109090075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 109190075Sobrien (fix:DI (match_operand:TF 1 "fr_register_operand" "f"))) 109290075Sobrien (use (match_operand:SI 2 "const_int_operand" ""))] 109390075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 109490075Sobrien "fcvt.fx.trunc.s%2 %0 = %1" 109590075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 109690075Sobrien 109790075Sobrien;; Convert between unsigned integer types and floating point. 109890075Sobrien 109990075Sobrien(define_insn "floatunsdisf2" 110090075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 110190075Sobrien (unsigned_float:SF (match_operand:DI 1 "fr_register_operand" "f")))] 110290075Sobrien "" 110390075Sobrien "fcvt.xuf.s %0 = %1" 110490075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 110590075Sobrien 110690075Sobrien(define_insn "floatunsdidf2" 110790075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 110890075Sobrien (unsigned_float:DF (match_operand:DI 1 "fr_register_operand" "f")))] 110990075Sobrien "" 111090075Sobrien "fcvt.xuf.d %0 = %1" 111190075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 111290075Sobrien 111390075Sobrien(define_insn "floatunsditf2" 111490075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "=f") 111590075Sobrien (unsigned_float:TF (match_operand:DI 1 "fr_register_operand" "f")))] 111690075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 111790075Sobrien "fcvt.xuf %0 = %1" 111890075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 111990075Sobrien 112090075Sobrien(define_insn "fixuns_truncsfdi2" 112190075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 112290075Sobrien (unsigned_fix:DI (match_operand:SF 1 "fr_register_operand" "f")))] 112390075Sobrien "" 112490075Sobrien "fcvt.fxu.trunc %0 = %1" 112590075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 112690075Sobrien 112790075Sobrien(define_insn "fixuns_truncdfdi2" 112890075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 112990075Sobrien (unsigned_fix:DI (match_operand:DF 1 "fr_register_operand" "f")))] 113090075Sobrien "" 113190075Sobrien "fcvt.fxu.trunc %0 = %1" 113290075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 113390075Sobrien 113490075Sobrien(define_insn "fixuns_trunctfdi2" 113590075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 113690075Sobrien (unsigned_fix:DI (match_operand:TF 1 "fr_register_operand" "f")))] 113790075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 113890075Sobrien "fcvt.fxu.trunc %0 = %1" 113990075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 114090075Sobrien 114190075Sobrien(define_insn "fixuns_trunctfdi2_alts" 114290075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 114390075Sobrien (unsigned_fix:DI (match_operand:TF 1 "fr_register_operand" "f"))) 114490075Sobrien (use (match_operand:SI 2 "const_int_operand" ""))] 114590075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 114690075Sobrien "fcvt.fxu.trunc.s%2 %0 = %1" 114790075Sobrien [(set_attr "itanium_class" "fcvtfx")]) 114890075Sobrien 114990075Sobrien;; :::::::::::::::::::: 115090075Sobrien;; :: 115190075Sobrien;; :: Bit field extraction 115290075Sobrien;; :: 115390075Sobrien;; :::::::::::::::::::: 115490075Sobrien 115590075Sobrien(define_insn "extv" 115690075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 115790075Sobrien (sign_extract:DI (match_operand:DI 1 "gr_register_operand" "r") 115890075Sobrien (match_operand:DI 2 "const_int_operand" "n") 115990075Sobrien (match_operand:DI 3 "const_int_operand" "n")))] 116090075Sobrien "" 116190075Sobrien "extr %0 = %1, %3, %2" 116290075Sobrien [(set_attr "itanium_class" "ishf")]) 116390075Sobrien 116490075Sobrien(define_insn "extzv" 116590075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 116690075Sobrien (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r") 116790075Sobrien (match_operand:DI 2 "const_int_operand" "n") 116890075Sobrien (match_operand:DI 3 "const_int_operand" "n")))] 116990075Sobrien "" 117090075Sobrien "extr.u %0 = %1, %3, %2" 117190075Sobrien [(set_attr "itanium_class" "ishf")]) 117290075Sobrien 117390075Sobrien;; Insert a bit field. 117490075Sobrien;; Can have 3 operands, source1 (inserter), source2 (insertee), dest. 117590075Sobrien;; Source1 can be 0 or -1. 117690075Sobrien;; Source2 can be 0. 117790075Sobrien 117890075Sobrien;; ??? Actual dep instruction is more powerful than what these insv 117990075Sobrien;; patterns support. Unfortunately, combine is unable to create patterns 118090075Sobrien;; where source2 != dest. 118190075Sobrien 118290075Sobrien(define_expand "insv" 118390075Sobrien [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "") 118490075Sobrien (match_operand:DI 1 "const_int_operand" "") 118590075Sobrien (match_operand:DI 2 "const_int_operand" "")) 118690075Sobrien (match_operand:DI 3 "nonmemory_operand" ""))] 118790075Sobrien "" 118890075Sobrien{ 118990075Sobrien int width = INTVAL (operands[1]); 119090075Sobrien int shift = INTVAL (operands[2]); 119190075Sobrien 119290075Sobrien /* If operand[3] is a constant, and isn't 0 or -1, then load it into a 119390075Sobrien pseudo. */ 119490075Sobrien if (! register_operand (operands[3], DImode) 119590075Sobrien && operands[3] != const0_rtx && operands[3] != constm1_rtx) 119690075Sobrien operands[3] = force_reg (DImode, operands[3]); 119790075Sobrien 119890075Sobrien /* If this is a single dep instruction, we have nothing to do. */ 119990075Sobrien if (! ((register_operand (operands[3], DImode) && width <= 16) 120090075Sobrien || operands[3] == const0_rtx || operands[3] == constm1_rtx)) 120190075Sobrien { 120290075Sobrien /* Check for cases that can be implemented with a mix instruction. */ 120390075Sobrien if (width == 32 && shift == 0) 120490075Sobrien { 120590075Sobrien /* Directly generating the mix4left instruction confuses 120690075Sobrien optimize_bit_field in function.c. Since this is performing 120790075Sobrien a useful optimization, we defer generation of the complicated 120890075Sobrien mix4left RTL to the first splitting phase. */ 120990075Sobrien rtx tmp = gen_reg_rtx (DImode); 121090075Sobrien emit_insn (gen_shift_mix4left (operands[0], operands[3], tmp)); 121190075Sobrien DONE; 121290075Sobrien } 121390075Sobrien else if (width == 32 && shift == 32) 121490075Sobrien { 121590075Sobrien emit_insn (gen_mix4right (operands[0], operands[3])); 121690075Sobrien DONE; 121790075Sobrien } 121890075Sobrien 121990075Sobrien /* We could handle remaining cases by emitting multiple dep 122090075Sobrien instructions. 122190075Sobrien 122290075Sobrien If we need more than two dep instructions then we lose. A 6 122390075Sobrien insn sequence mov mask1,mov mask2,shl;;and,and;;or is better than 122490075Sobrien mov;;dep,shr;;dep,shr;;dep. The former can be executed in 3 cycles, 122590075Sobrien the latter is 6 cycles on an Itanium (TM) processor, because there is 122690075Sobrien only one function unit that can execute dep and shr immed. 122790075Sobrien 122890075Sobrien If we only need two dep instruction, then we still lose. 122990075Sobrien mov;;dep,shr;;dep is still 4 cycles. Even if we optimize away 123090075Sobrien the unnecessary mov, this is still undesirable because it will be 123190075Sobrien hard to optimize, and it creates unnecessary pressure on the I0 123290075Sobrien function unit. */ 123390075Sobrien 123490075Sobrien FAIL; 123590075Sobrien 123690075Sobrien#if 0 123790075Sobrien /* This code may be useful for other IA-64 processors, so we leave it in 123890075Sobrien for now. */ 123990075Sobrien while (width > 16) 124090075Sobrien { 124190075Sobrien rtx tmp; 124290075Sobrien 124390075Sobrien emit_insn (gen_insv (operands[0], GEN_INT (16), GEN_INT (shift), 124490075Sobrien operands[3])); 124590075Sobrien shift += 16; 124690075Sobrien width -= 16; 124790075Sobrien tmp = gen_reg_rtx (DImode); 124890075Sobrien emit_insn (gen_lshrdi3 (tmp, operands[3], GEN_INT (16))); 124990075Sobrien operands[3] = tmp; 125090075Sobrien } 125190075Sobrien operands[1] = GEN_INT (width); 125290075Sobrien operands[2] = GEN_INT (shift); 125390075Sobrien#endif 125490075Sobrien } 1255117395Skan}) 125690075Sobrien 125790075Sobrien(define_insn "*insv_internal" 125890075Sobrien [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r") 125990075Sobrien (match_operand:DI 1 "const_int_operand" "n") 126090075Sobrien (match_operand:DI 2 "const_int_operand" "n")) 126190075Sobrien (match_operand:DI 3 "nonmemory_operand" "rP"))] 126290075Sobrien "(gr_register_operand (operands[3], DImode) && INTVAL (operands[1]) <= 16) 126390075Sobrien || operands[3] == const0_rtx || operands[3] == constm1_rtx" 126490075Sobrien "dep %0 = %3, %0, %2, %1" 126590075Sobrien [(set_attr "itanium_class" "ishf")]) 126690075Sobrien 1267117395Skan;; Combine doesn't like to create bit-field insertions into zero. 126890075Sobrien(define_insn "*depz_internal" 126990075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 127090075Sobrien (and:DI (ashift:DI (match_operand:DI 1 "gr_register_operand" "r") 127190075Sobrien (match_operand:DI 2 "const_int_operand" "n")) 127290075Sobrien (match_operand:DI 3 "const_int_operand" "n")))] 127390075Sobrien "CONST_OK_FOR_M (INTVAL (operands[2])) 127490075Sobrien && ia64_depz_field_mask (operands[3], operands[2]) > 0" 127590075Sobrien{ 127690075Sobrien operands[3] = GEN_INT (ia64_depz_field_mask (operands[3], operands[2])); 1277117395Skan return "%,dep.z %0 = %1, %2, %3"; 1278117395Skan} 127990075Sobrien [(set_attr "itanium_class" "ishf")]) 128090075Sobrien 128190075Sobrien(define_insn "shift_mix4left" 128290075Sobrien [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r") 128390075Sobrien (const_int 32) (const_int 0)) 128490075Sobrien (match_operand:DI 1 "gr_register_operand" "r")) 128590075Sobrien (clobber (match_operand:DI 2 "gr_register_operand" "=r"))] 128690075Sobrien "" 128790075Sobrien "#" 128890075Sobrien [(set_attr "itanium_class" "unknown")]) 128990075Sobrien 129090075Sobrien(define_split 129190075Sobrien [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "") 129290075Sobrien (const_int 32) (const_int 0)) 129390075Sobrien (match_operand:DI 1 "register_operand" "")) 129490075Sobrien (clobber (match_operand:DI 2 "register_operand" ""))] 129590075Sobrien "reload_completed" 129690075Sobrien [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32))) 129790075Sobrien (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0)) 129890075Sobrien (lshiftrt:DI (match_dup 3) (const_int 32)))] 129990075Sobrien "operands[3] = operands[2];") 130090075Sobrien 130190075Sobrien(define_split 130290075Sobrien [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "") 130390075Sobrien (const_int 32) (const_int 0)) 130490075Sobrien (match_operand:DI 1 "register_operand" "")) 130590075Sobrien (clobber (match_operand:DI 2 "register_operand" ""))] 130690075Sobrien "! reload_completed" 130790075Sobrien [(set (match_dup 3) (ashift:DI (match_dup 1) (const_int 32))) 130890075Sobrien (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 0)) 130990075Sobrien (lshiftrt:DI (match_dup 3) (const_int 32)))] 131090075Sobrien "operands[3] = operands[2];") 131190075Sobrien 131290075Sobrien(define_insn "*mix4left" 131390075Sobrien [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r") 131490075Sobrien (const_int 32) (const_int 0)) 131590075Sobrien (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r") 131690075Sobrien (const_int 32)))] 131790075Sobrien "" 131890075Sobrien "mix4.l %0 = %0, %r1" 131990075Sobrien [(set_attr "itanium_class" "mmshf")]) 132090075Sobrien 132190075Sobrien(define_insn "mix4right" 132290075Sobrien [(set (zero_extract:DI (match_operand:DI 0 "gr_register_operand" "+r") 132390075Sobrien (const_int 32) (const_int 32)) 132490075Sobrien (match_operand:DI 1 "gr_reg_or_0_operand" "rO"))] 132590075Sobrien "" 132690075Sobrien "mix4.r %0 = %r1, %0" 132790075Sobrien [(set_attr "itanium_class" "mmshf")]) 132890075Sobrien 132990075Sobrien;; This is used by the rotrsi3 pattern. 133090075Sobrien 133190075Sobrien(define_insn "*mix4right_3op" 133290075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 133390075Sobrien (ior:DI (zero_extend:DI (match_operand:SI 1 "gr_register_operand" "r")) 133490075Sobrien (ashift:DI (zero_extend:DI 133590075Sobrien (match_operand:SI 2 "gr_register_operand" "r")) 133690075Sobrien (const_int 32))))] 133790075Sobrien "" 133890075Sobrien "mix4.r %0 = %2, %1" 133990075Sobrien [(set_attr "itanium_class" "mmshf")]) 134090075Sobrien 134190075Sobrien 134290075Sobrien;; :::::::::::::::::::: 134390075Sobrien;; :: 134490075Sobrien;; :: 1 bit Integer arithmetic 134590075Sobrien;; :: 134690075Sobrien;; :::::::::::::::::::: 134790075Sobrien 134890075Sobrien(define_insn_and_split "andbi3" 134990075Sobrien [(set (match_operand:BI 0 "register_operand" "=c,c,r") 135090075Sobrien (and:BI (match_operand:BI 1 "register_operand" "%0,0,r") 135190075Sobrien (match_operand:BI 2 "register_operand" "c,r,r")))] 135290075Sobrien "" 135390075Sobrien "@ 135490075Sobrien # 135590075Sobrien tbit.nz.and.orcm %0, %I0 = %2, 0 135690075Sobrien and %0 = %2, %1" 135790075Sobrien "reload_completed 135890075Sobrien && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0])) 135990075Sobrien && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))" 136090075Sobrien [(cond_exec (eq (match_dup 2) (const_int 0)) 136190075Sobrien (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0)) 136290075Sobrien (match_dup 0))))] 136390075Sobrien "" 136490075Sobrien [(set_attr "itanium_class" "unknown,tbit,ilog")]) 136590075Sobrien 136690075Sobrien(define_insn_and_split "*andcmbi3" 136790075Sobrien [(set (match_operand:BI 0 "register_operand" "=c,c,r") 136890075Sobrien (and:BI (not:BI (match_operand:BI 1 "register_operand" "c,r,r")) 136990075Sobrien (match_operand:BI 2 "register_operand" "0,0,r")))] 137090075Sobrien "" 137190075Sobrien "@ 137290075Sobrien # 137390075Sobrien tbit.z.and.orcm %0, %I0 = %1, 0 137490075Sobrien andcm %0 = %2, %1" 137590075Sobrien "reload_completed 137690075Sobrien && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0])) 137790075Sobrien && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))" 137890075Sobrien [(cond_exec (ne (match_dup 1) (const_int 0)) 137990075Sobrien (set (match_dup 0) (and:BI (ne:BI (const_int 0) (const_int 0)) 138090075Sobrien (match_dup 0))))] 138190075Sobrien "" 138290075Sobrien [(set_attr "itanium_class" "unknown,tbit,ilog")]) 138390075Sobrien 138490075Sobrien(define_insn_and_split "iorbi3" 138590075Sobrien [(set (match_operand:BI 0 "register_operand" "=c,c,r") 138690075Sobrien (ior:BI (match_operand:BI 1 "register_operand" "%0,0,r") 138790075Sobrien (match_operand:BI 2 "register_operand" "c,r,r")))] 138890075Sobrien "" 138990075Sobrien "@ 139090075Sobrien # 139190075Sobrien tbit.nz.or.andcm %0, %I0 = %2, 0 139290075Sobrien or %0 = %2, %1" 139390075Sobrien "reload_completed 139490075Sobrien && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0])) 139590075Sobrien && GET_CODE (operands[2]) == REG && PR_REGNO_P (REGNO (operands[2]))" 139690075Sobrien [(cond_exec (ne (match_dup 2) (const_int 0)) 139790075Sobrien (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0)) 139890075Sobrien (match_dup 0))))] 139990075Sobrien "" 140090075Sobrien [(set_attr "itanium_class" "unknown,tbit,ilog")]) 140190075Sobrien 140290075Sobrien(define_insn_and_split "*iorcmbi3" 140390075Sobrien [(set (match_operand:BI 0 "register_operand" "=c,c") 140490075Sobrien (ior:BI (not:BI (match_operand:BI 1 "register_operand" "c,r")) 140590075Sobrien (match_operand:BI 2 "register_operand" "0,0")))] 140690075Sobrien "" 140790075Sobrien "@ 140890075Sobrien # 140990075Sobrien tbit.z.or.andcm %0, %I0 = %1, 0" 141090075Sobrien "reload_completed 141190075Sobrien && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0])) 141290075Sobrien && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1]))" 141390075Sobrien [(cond_exec (eq (match_dup 1) (const_int 0)) 141490075Sobrien (set (match_dup 0) (ior:BI (eq:BI (const_int 0) (const_int 0)) 141590075Sobrien (match_dup 0))))] 141690075Sobrien "" 141790075Sobrien [(set_attr "itanium_class" "unknown,tbit")]) 141890075Sobrien 141990075Sobrien(define_insn "one_cmplbi2" 142090075Sobrien [(set (match_operand:BI 0 "register_operand" "=c,r,c,&c") 142190075Sobrien (not:BI (match_operand:BI 1 "register_operand" "r,r,0,c"))) 142290075Sobrien (clobber (match_scratch:BI 2 "=X,X,c,X"))] 142390075Sobrien "" 142490075Sobrien "@ 142590075Sobrien tbit.z %0, %I0 = %1, 0 142690075Sobrien xor %0 = 1, %1 142790075Sobrien # 142890075Sobrien #" 142990075Sobrien [(set_attr "itanium_class" "tbit,ilog,unknown,unknown")]) 143090075Sobrien 143190075Sobrien(define_split 143290075Sobrien [(set (match_operand:BI 0 "register_operand" "") 143390075Sobrien (not:BI (match_operand:BI 1 "register_operand" ""))) 143490075Sobrien (clobber (match_scratch:BI 2 ""))] 143590075Sobrien "reload_completed 143690075Sobrien && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0])) 143790075Sobrien && rtx_equal_p (operands[0], operands[1])" 143890075Sobrien [(set (match_dup 4) (match_dup 3)) 143990075Sobrien (set (match_dup 0) (const_int 1)) 144090075Sobrien (cond_exec (ne (match_dup 2) (const_int 0)) 144190075Sobrien (set (match_dup 0) (const_int 0))) 1442117395Skan (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))] 144390075Sobrien "operands[3] = gen_rtx_REG (CCImode, REGNO (operands[1])); 144490075Sobrien operands[4] = gen_rtx_REG (CCImode, REGNO (operands[2]));") 144590075Sobrien 144690075Sobrien(define_split 144790075Sobrien [(set (match_operand:BI 0 "register_operand" "") 144890075Sobrien (not:BI (match_operand:BI 1 "register_operand" ""))) 144990075Sobrien (clobber (match_scratch:BI 2 ""))] 145090075Sobrien "reload_completed 145190075Sobrien && GET_CODE (operands[0]) == REG && PR_REGNO_P (REGNO (operands[0])) 145290075Sobrien && GET_CODE (operands[1]) == REG && PR_REGNO_P (REGNO (operands[1])) 145390075Sobrien && ! rtx_equal_p (operands[0], operands[1])" 145490075Sobrien [(cond_exec (ne (match_dup 1) (const_int 0)) 145590075Sobrien (set (match_dup 0) (const_int 0))) 145690075Sobrien (cond_exec (eq (match_dup 1) (const_int 0)) 145790075Sobrien (set (match_dup 0) (const_int 1))) 1458117395Skan (set (match_dup 0) (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))] 145990075Sobrien "") 146090075Sobrien 146190075Sobrien(define_insn "*cmpsi_and_0" 146290075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 146390075Sobrien (and:BI (match_operator:BI 4 "predicate_operator" 146490075Sobrien [(match_operand:SI 2 "gr_reg_or_0_operand" "rO") 146590075Sobrien (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]) 146690075Sobrien (match_operand:BI 1 "register_operand" "0")))] 146790075Sobrien "" 146890075Sobrien "cmp4.%C4.and.orcm %0, %I0 = %3, %r2" 146990075Sobrien [(set_attr "itanium_class" "icmp")]) 147090075Sobrien 147190075Sobrien(define_insn "*cmpsi_and_1" 147290075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 147390075Sobrien (and:BI (match_operator:BI 3 "signed_inequality_operator" 147490075Sobrien [(match_operand:SI 2 "gr_register_operand" "r") 147590075Sobrien (const_int 0)]) 147690075Sobrien (match_operand:BI 1 "register_operand" "0")))] 147790075Sobrien "" 147890075Sobrien "cmp4.%C3.and.orcm %0, %I0 = r0, %2" 147990075Sobrien [(set_attr "itanium_class" "icmp")]) 148090075Sobrien 148190075Sobrien(define_insn "*cmpsi_andnot_0" 148290075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 148390075Sobrien (and:BI (not:BI (match_operator:BI 4 "predicate_operator" 148490075Sobrien [(match_operand:SI 2 "gr_reg_or_0_operand" "rO") 148590075Sobrien (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])) 148690075Sobrien (match_operand:BI 1 "register_operand" "0")))] 148790075Sobrien "" 148890075Sobrien "cmp4.%C4.or.andcm %I0, %0 = %3, %r2" 148990075Sobrien [(set_attr "itanium_class" "icmp")]) 149090075Sobrien 149190075Sobrien(define_insn "*cmpsi_andnot_1" 149290075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 149390075Sobrien (and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator" 149490075Sobrien [(match_operand:SI 2 "gr_register_operand" "r") 149590075Sobrien (const_int 0)])) 149690075Sobrien (match_operand:BI 1 "register_operand" "0")))] 149790075Sobrien "" 149890075Sobrien "cmp4.%C3.or.andcm %I0, %0 = r0, %2" 149990075Sobrien [(set_attr "itanium_class" "icmp")]) 150090075Sobrien 150190075Sobrien(define_insn "*cmpdi_and_0" 150290075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 150390075Sobrien (and:BI (match_operator:BI 4 "predicate_operator" 150490075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 150590075Sobrien (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]) 150690075Sobrien (match_operand:BI 1 "register_operand" "0")))] 150790075Sobrien "" 150890075Sobrien "cmp.%C4.and.orcm %0, %I0 = %3, %2" 150990075Sobrien [(set_attr "itanium_class" "icmp")]) 151090075Sobrien 151190075Sobrien(define_insn "*cmpdi_and_1" 151290075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 151390075Sobrien (and:BI (match_operator:BI 3 "signed_inequality_operator" 151490075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 151590075Sobrien (const_int 0)]) 151690075Sobrien (match_operand:BI 1 "register_operand" "0")))] 151790075Sobrien "" 151890075Sobrien "cmp.%C3.and.orcm %0, %I0 = r0, %2" 151990075Sobrien [(set_attr "itanium_class" "icmp")]) 152090075Sobrien 152190075Sobrien(define_insn "*cmpdi_andnot_0" 152290075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 152390075Sobrien (and:BI (not:BI (match_operator:BI 4 "predicate_operator" 152490075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 152590075Sobrien (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])) 152690075Sobrien (match_operand:BI 1 "register_operand" "0")))] 152790075Sobrien "" 152890075Sobrien "cmp.%C4.or.andcm %I0, %0 = %3, %2" 152990075Sobrien [(set_attr "itanium_class" "icmp")]) 153090075Sobrien 153190075Sobrien(define_insn "*cmpdi_andnot_1" 153290075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 153390075Sobrien (and:BI (not:BI (match_operator:BI 3 "signed_inequality_operator" 153490075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 153590075Sobrien (const_int 0)])) 153690075Sobrien (match_operand:BI 1 "register_operand" "0")))] 153790075Sobrien "" 153890075Sobrien "cmp.%C3.or.andcm %I0, %0 = r0, %2" 153990075Sobrien [(set_attr "itanium_class" "icmp")]) 154090075Sobrien 154190075Sobrien(define_insn "*tbit_and_0" 154290075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 154390075Sobrien (and:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r") 154490075Sobrien (const_int 1)) 154590075Sobrien (const_int 0)) 154690075Sobrien (match_operand:BI 2 "register_operand" "0")))] 154790075Sobrien "" 154890075Sobrien "tbit.nz.and.orcm %0, %I0 = %1, 0" 154990075Sobrien [(set_attr "itanium_class" "tbit")]) 155090075Sobrien 155190075Sobrien(define_insn "*tbit_and_1" 155290075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 155390075Sobrien (and:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r") 155490075Sobrien (const_int 1)) 155590075Sobrien (const_int 0)) 155690075Sobrien (match_operand:BI 2 "register_operand" "0")))] 155790075Sobrien "" 155890075Sobrien "tbit.z.and.orcm %0, %I0 = %1, 0" 155990075Sobrien [(set_attr "itanium_class" "tbit")]) 156090075Sobrien 156190075Sobrien(define_insn "*tbit_and_2" 156290075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 156390075Sobrien (and:BI (ne:BI (zero_extract:DI 156490075Sobrien (match_operand:DI 1 "gr_register_operand" "r") 156590075Sobrien (const_int 1) 156690075Sobrien (match_operand:DI 2 "const_int_operand" "n")) 156790075Sobrien (const_int 0)) 156890075Sobrien (match_operand:BI 3 "register_operand" "0")))] 156990075Sobrien "" 157090075Sobrien "tbit.nz.and.orcm %0, %I0 = %1, %2" 157190075Sobrien [(set_attr "itanium_class" "tbit")]) 157290075Sobrien 157390075Sobrien(define_insn "*tbit_and_3" 157490075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 157590075Sobrien (and:BI (eq:BI (zero_extract:DI 157690075Sobrien (match_operand:DI 1 "gr_register_operand" "r") 157790075Sobrien (const_int 1) 157890075Sobrien (match_operand:DI 2 "const_int_operand" "n")) 157990075Sobrien (const_int 0)) 158090075Sobrien (match_operand:BI 3 "register_operand" "0")))] 158190075Sobrien "" 158290075Sobrien "tbit.z.and.orcm %0, %I0 = %1, %2" 158390075Sobrien [(set_attr "itanium_class" "tbit")]) 158490075Sobrien 158590075Sobrien(define_insn "*cmpsi_or_0" 158690075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 158790075Sobrien (ior:BI (match_operator:BI 4 "predicate_operator" 158890075Sobrien [(match_operand:SI 2 "gr_reg_or_0_operand" "rO") 158990075Sobrien (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]) 159090075Sobrien (match_operand:BI 1 "register_operand" "0")))] 159190075Sobrien "" 159290075Sobrien "cmp4.%C4.or.andcm %0, %I0 = %3, %r2" 159390075Sobrien [(set_attr "itanium_class" "icmp")]) 159490075Sobrien 159590075Sobrien(define_insn "*cmpsi_or_1" 159690075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 159790075Sobrien (ior:BI (match_operator:BI 3 "signed_inequality_operator" 159890075Sobrien [(match_operand:SI 2 "gr_register_operand" "r") 159990075Sobrien (const_int 0)]) 160090075Sobrien (match_operand:BI 1 "register_operand" "0")))] 160190075Sobrien "" 160290075Sobrien "cmp4.%C3.or.andcm %0, %I0 = r0, %2" 160390075Sobrien [(set_attr "itanium_class" "icmp")]) 160490075Sobrien 160590075Sobrien(define_insn "*cmpsi_orcm_0" 160690075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 160790075Sobrien (ior:BI (not:BI (match_operator:BI 4 "predicate_operator" 160890075Sobrien [(match_operand:SI 2 "gr_reg_or_0_operand" "rO") 160990075Sobrien (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")])) 161090075Sobrien (match_operand:BI 1 "register_operand" "0")))] 161190075Sobrien "" 161290075Sobrien "cmp4.%C4.and.orcm %I0, %0 = %3, %r2" 161390075Sobrien [(set_attr "itanium_class" "icmp")]) 161490075Sobrien 161590075Sobrien(define_insn "*cmpsi_orcm_1" 161690075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 161790075Sobrien (ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator" 161890075Sobrien [(match_operand:SI 2 "gr_register_operand" "r") 161990075Sobrien (const_int 0)])) 162090075Sobrien (match_operand:BI 1 "register_operand" "0")))] 162190075Sobrien "" 162290075Sobrien "cmp4.%C3.and.orcm %I0, %0 = r0, %2" 162390075Sobrien [(set_attr "itanium_class" "icmp")]) 162490075Sobrien 162590075Sobrien(define_insn "*cmpdi_or_0" 162690075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 162790075Sobrien (ior:BI (match_operator:BI 4 "predicate_operator" 162890075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 162990075Sobrien (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]) 163090075Sobrien (match_operand:BI 1 "register_operand" "0")))] 163190075Sobrien "" 163290075Sobrien "cmp.%C4.or.andcm %0, %I0 = %3, %2" 163390075Sobrien [(set_attr "itanium_class" "icmp")]) 163490075Sobrien 163590075Sobrien(define_insn "*cmpdi_or_1" 163690075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 163790075Sobrien (ior:BI (match_operator:BI 3 "signed_inequality_operator" 163890075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 163990075Sobrien (const_int 0)]) 164090075Sobrien (match_operand:BI 1 "register_operand" "0")))] 164190075Sobrien "" 164290075Sobrien "cmp.%C3.or.andcm %0, %I0 = r0, %2" 164390075Sobrien [(set_attr "itanium_class" "icmp")]) 164490075Sobrien 164590075Sobrien(define_insn "*cmpdi_orcm_0" 164690075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 164790075Sobrien (ior:BI (not:BI (match_operator:BI 4 "predicate_operator" 164890075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 164990075Sobrien (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")])) 165090075Sobrien (match_operand:BI 1 "register_operand" "0")))] 165190075Sobrien "" 165290075Sobrien "cmp.%C4.and.orcm %I0, %0 = %3, %2" 165390075Sobrien [(set_attr "itanium_class" "icmp")]) 165490075Sobrien 165590075Sobrien(define_insn "*cmpdi_orcm_1" 165690075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 165790075Sobrien (ior:BI (not:BI (match_operator:BI 3 "signed_inequality_operator" 165890075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 165990075Sobrien (const_int 0)])) 166090075Sobrien (match_operand:BI 1 "register_operand" "0")))] 166190075Sobrien "" 166290075Sobrien "cmp.%C3.and.orcm %I0, %0 = r0, %2" 166390075Sobrien [(set_attr "itanium_class" "icmp")]) 166490075Sobrien 166590075Sobrien(define_insn "*tbit_or_0" 166690075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 166790075Sobrien (ior:BI (ne:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r") 166890075Sobrien (const_int 1)) 166990075Sobrien (const_int 0)) 167090075Sobrien (match_operand:BI 2 "register_operand" "0")))] 167190075Sobrien "" 167290075Sobrien "tbit.nz.or.andcm %0, %I0 = %1, 0" 167390075Sobrien [(set_attr "itanium_class" "tbit")]) 167490075Sobrien 167590075Sobrien(define_insn "*tbit_or_1" 167690075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 167790075Sobrien (ior:BI (eq:BI (and:DI (match_operand:DI 1 "gr_register_operand" "r") 167890075Sobrien (const_int 1)) 167990075Sobrien (const_int 0)) 168090075Sobrien (match_operand:BI 2 "register_operand" "0")))] 168190075Sobrien "" 168290075Sobrien "tbit.z.or.andcm %0, %I0 = %1, 0" 168390075Sobrien [(set_attr "itanium_class" "tbit")]) 168490075Sobrien 168590075Sobrien(define_insn "*tbit_or_2" 168690075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 168790075Sobrien (ior:BI (ne:BI (zero_extract:DI 168890075Sobrien (match_operand:DI 1 "gr_register_operand" "r") 168990075Sobrien (const_int 1) 169090075Sobrien (match_operand:DI 2 "const_int_operand" "n")) 169190075Sobrien (const_int 0)) 169290075Sobrien (match_operand:BI 3 "register_operand" "0")))] 169390075Sobrien "" 169490075Sobrien "tbit.nz.or.andcm %0, %I0 = %1, %2" 169590075Sobrien [(set_attr "itanium_class" "tbit")]) 169690075Sobrien 169790075Sobrien(define_insn "*tbit_or_3" 169890075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 169990075Sobrien (ior:BI (eq:BI (zero_extract:DI 170090075Sobrien (match_operand:DI 1 "gr_register_operand" "r") 170190075Sobrien (const_int 1) 170290075Sobrien (match_operand:DI 2 "const_int_operand" "n")) 170390075Sobrien (const_int 0)) 170490075Sobrien (match_operand:BI 3 "register_operand" "0")))] 170590075Sobrien "" 170690075Sobrien "tbit.z.or.andcm %0, %I0 = %1, %2" 170790075Sobrien [(set_attr "itanium_class" "tbit")]) 170890075Sobrien 170990075Sobrien;; Transform test of and/or of setcc into parallel comparisons. 171090075Sobrien 171190075Sobrien(define_split 171290075Sobrien [(set (match_operand:BI 0 "register_operand" "") 171390075Sobrien (ne:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "") 171490075Sobrien (const_int 0)) 171590075Sobrien (match_operand:DI 3 "register_operand" "")) 171690075Sobrien (const_int 0)))] 171790075Sobrien "" 171890075Sobrien [(set (match_dup 0) 171990075Sobrien (and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0)) 172090075Sobrien (match_dup 2)))] 172190075Sobrien "") 172290075Sobrien 172390075Sobrien(define_split 172490075Sobrien [(set (match_operand:BI 0 "register_operand" "") 172590075Sobrien (eq:BI (and:DI (ne:DI (match_operand:BI 2 "register_operand" "") 172690075Sobrien (const_int 0)) 172790075Sobrien (match_operand:DI 3 "register_operand" "")) 172890075Sobrien (const_int 0)))] 172990075Sobrien "" 173090075Sobrien [(set (match_dup 0) 173190075Sobrien (and:BI (ne:BI (and:DI (match_dup 3) (const_int 1)) (const_int 0)) 173290075Sobrien (match_dup 2))) 173390075Sobrien (parallel [(set (match_dup 0) (not:BI (match_dup 0))) 173490075Sobrien (clobber (scratch))])] 173590075Sobrien "") 173690075Sobrien 173790075Sobrien(define_split 173890075Sobrien [(set (match_operand:BI 0 "register_operand" "") 173990075Sobrien (ne:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "") 174090075Sobrien (const_int 0)) 174190075Sobrien (match_operand:DI 3 "register_operand" "")) 174290075Sobrien (const_int 0)))] 174390075Sobrien "" 174490075Sobrien [(set (match_dup 0) 174590075Sobrien (ior:BI (ne:BI (match_dup 3) (const_int 0)) 174690075Sobrien (match_dup 2)))] 174790075Sobrien "") 174890075Sobrien 174990075Sobrien(define_split 175090075Sobrien [(set (match_operand:BI 0 "register_operand" "") 175190075Sobrien (eq:BI (ior:DI (ne:DI (match_operand:BI 2 "register_operand" "") 175290075Sobrien (const_int 0)) 175390075Sobrien (match_operand:DI 3 "register_operand" "")) 175490075Sobrien (const_int 0)))] 175590075Sobrien "" 175690075Sobrien [(set (match_dup 0) 175790075Sobrien (ior:BI (ne:BI (match_dup 3) (const_int 0)) 175890075Sobrien (match_dup 2))) 175990075Sobrien (parallel [(set (match_dup 0) (not:BI (match_dup 0))) 176090075Sobrien (clobber (scratch))])] 176190075Sobrien "") 176290075Sobrien 176390075Sobrien;; ??? Incredibly hackish. Either need four proper patterns with all 176490075Sobrien;; the alternatives, or rely on sched1 to split the insn and hope that 176590075Sobrien;; nothing bad happens to the comparisons in the meantime. 176690075Sobrien;; 176790075Sobrien;; Alternately, adjust combine to allow 2->2 and 3->3 splits, assuming 176890075Sobrien;; that we're doing height reduction. 176990075Sobrien; 177090075Sobrien;(define_insn_and_split "" 177190075Sobrien; [(set (match_operand:BI 0 "register_operand" "=c") 177290075Sobrien; (and:BI (and:BI (match_operator:BI 1 "comparison_operator" 177390075Sobrien; [(match_operand 2 "" "") 177490075Sobrien; (match_operand 3 "" "")]) 177590075Sobrien; (match_operator:BI 4 "comparison_operator" 177690075Sobrien; [(match_operand 5 "" "") 177790075Sobrien; (match_operand 6 "" "")])) 177890075Sobrien; (match_dup 0)))] 177990075Sobrien; "flag_schedule_insns" 178090075Sobrien; "#" 178190075Sobrien; "" 178290075Sobrien; [(set (match_dup 0) (and:BI (match_dup 1) (match_dup 0))) 178390075Sobrien; (set (match_dup 0) (and:BI (match_dup 4) (match_dup 0)))] 178490075Sobrien; "") 178590075Sobrien; 178690075Sobrien;(define_insn_and_split "" 178790075Sobrien; [(set (match_operand:BI 0 "register_operand" "=c") 178890075Sobrien; (ior:BI (ior:BI (match_operator:BI 1 "comparison_operator" 178990075Sobrien; [(match_operand 2 "" "") 179090075Sobrien; (match_operand 3 "" "")]) 179190075Sobrien; (match_operator:BI 4 "comparison_operator" 179290075Sobrien; [(match_operand 5 "" "") 179390075Sobrien; (match_operand 6 "" "")])) 179490075Sobrien; (match_dup 0)))] 179590075Sobrien; "flag_schedule_insns" 179690075Sobrien; "#" 179790075Sobrien; "" 179890075Sobrien; [(set (match_dup 0) (ior:BI (match_dup 1) (match_dup 0))) 179990075Sobrien; (set (match_dup 0) (ior:BI (match_dup 4) (match_dup 0)))] 180090075Sobrien; "") 180190075Sobrien; 180290075Sobrien;(define_split 180390075Sobrien; [(set (match_operand:BI 0 "register_operand" "") 180490075Sobrien; (and:BI (and:BI (match_operator:BI 1 "comparison_operator" 180590075Sobrien; [(match_operand 2 "" "") 180690075Sobrien; (match_operand 3 "" "")]) 180790075Sobrien; (match_operand:BI 7 "register_operand" "")) 180890075Sobrien; (and:BI (match_operator:BI 4 "comparison_operator" 180990075Sobrien; [(match_operand 5 "" "") 181090075Sobrien; (match_operand 6 "" "")]) 181190075Sobrien; (match_operand:BI 8 "register_operand" ""))))] 181290075Sobrien; "" 181390075Sobrien; [(set (match_dup 0) (and:BI (match_dup 7) (match_dup 8))) 181490075Sobrien; (set (match_dup 0) (and:BI (and:BI (match_dup 1) (match_dup 4)) 181590075Sobrien; (match_dup 0)))] 181690075Sobrien; "") 181790075Sobrien; 181890075Sobrien;(define_split 181990075Sobrien; [(set (match_operand:BI 0 "register_operand" "") 182090075Sobrien; (ior:BI (ior:BI (match_operator:BI 1 "comparison_operator" 182190075Sobrien; [(match_operand 2 "" "") 182290075Sobrien; (match_operand 3 "" "")]) 182390075Sobrien; (match_operand:BI 7 "register_operand" "")) 182490075Sobrien; (ior:BI (match_operator:BI 4 "comparison_operator" 182590075Sobrien; [(match_operand 5 "" "") 182690075Sobrien; (match_operand 6 "" "")]) 182790075Sobrien; (match_operand:BI 8 "register_operand" ""))))] 182890075Sobrien; "" 182990075Sobrien; [(set (match_dup 0) (ior:BI (match_dup 7) (match_dup 8))) 183090075Sobrien; (set (match_dup 0) (ior:BI (ior:BI (match_dup 1) (match_dup 4)) 183190075Sobrien; (match_dup 0)))] 183290075Sobrien; "") 183390075Sobrien 183490075Sobrien;; Try harder to avoid predicate copies by duplicating compares. 183590075Sobrien;; Note that we'll have already split the predicate copy, which 183690075Sobrien;; is kind of a pain, but oh well. 183790075Sobrien 183890075Sobrien(define_peephole2 183990075Sobrien [(set (match_operand:BI 0 "register_operand" "") 184090075Sobrien (match_operand:BI 1 "comparison_operator" "")) 184190075Sobrien (set (match_operand:CCI 2 "register_operand" "") 184290075Sobrien (match_operand:CCI 3 "register_operand" "")) 184390075Sobrien (set (match_operand:CCI 4 "register_operand" "") 184490075Sobrien (match_operand:CCI 5 "register_operand" "")) 184590075Sobrien (set (match_operand:BI 6 "register_operand" "") 1846117395Skan (unspec:BI [(match_dup 6)] UNSPEC_PRED_REL_MUTEX))] 184790075Sobrien "REGNO (operands[3]) == REGNO (operands[0]) 184890075Sobrien && REGNO (operands[4]) == REGNO (operands[0]) + 1 184990075Sobrien && REGNO (operands[4]) == REGNO (operands[2]) + 1 185090075Sobrien && REGNO (operands[6]) == REGNO (operands[2])" 185190075Sobrien [(set (match_dup 0) (match_dup 1)) 185290075Sobrien (set (match_dup 6) (match_dup 7))] 185390075Sobrien "operands[7] = copy_rtx (operands[1]);") 185490075Sobrien 185590075Sobrien;; :::::::::::::::::::: 185690075Sobrien;; :: 185790075Sobrien;; :: 16 bit Integer arithmetic 185890075Sobrien;; :: 185990075Sobrien;; :::::::::::::::::::: 186090075Sobrien 186190075Sobrien(define_insn "mulhi3" 186290075Sobrien [(set (match_operand:HI 0 "gr_register_operand" "=r") 186390075Sobrien (mult:HI (match_operand:HI 1 "gr_register_operand" "r") 186490075Sobrien (match_operand:HI 2 "gr_register_operand" "r")))] 186590075Sobrien "" 186690075Sobrien "pmpy2.r %0 = %1, %2" 186790075Sobrien [(set_attr "itanium_class" "mmmul")]) 186890075Sobrien 186990075Sobrien 187090075Sobrien;; :::::::::::::::::::: 187190075Sobrien;; :: 187290075Sobrien;; :: 32 bit Integer arithmetic 187390075Sobrien;; :: 187490075Sobrien;; :::::::::::::::::::: 187590075Sobrien 187690075Sobrien(define_insn "addsi3" 187790075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r") 187890075Sobrien (plus:SI (match_operand:SI 1 "gr_register_operand" "%r,r,a") 187990075Sobrien (match_operand:SI 2 "gr_reg_or_22bit_operand" "r,I,J")))] 188090075Sobrien "" 188190075Sobrien "@ 1882117395Skan add %0 = %1, %2 1883117395Skan adds %0 = %2, %1 1884117395Skan addl %0 = %2, %1" 188590075Sobrien [(set_attr "itanium_class" "ialu")]) 188690075Sobrien 188790075Sobrien(define_insn "*addsi3_plus1" 188890075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 188990075Sobrien (plus:SI (plus:SI (match_operand:SI 1 "gr_register_operand" "r") 189090075Sobrien (match_operand:SI 2 "gr_register_operand" "r")) 189190075Sobrien (const_int 1)))] 189290075Sobrien "" 189390075Sobrien "add %0 = %1, %2, 1" 189490075Sobrien [(set_attr "itanium_class" "ialu")]) 189590075Sobrien 189690075Sobrien(define_insn "*addsi3_plus1_alt" 189790075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 189890075Sobrien (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r") 189990075Sobrien (const_int 2)) 190090075Sobrien (const_int 1)))] 190190075Sobrien "" 190290075Sobrien "add %0 = %1, %1, 1" 190390075Sobrien [(set_attr "itanium_class" "ialu")]) 190490075Sobrien 190590075Sobrien(define_insn "*addsi3_shladd" 190690075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 190790075Sobrien (plus:SI (mult:SI (match_operand:SI 1 "gr_register_operand" "r") 190890075Sobrien (match_operand:SI 2 "shladd_operand" "n")) 190990075Sobrien (match_operand:SI 3 "gr_register_operand" "r")))] 191090075Sobrien "" 191190075Sobrien "shladd %0 = %1, %S2, %3" 191290075Sobrien [(set_attr "itanium_class" "ialu")]) 191390075Sobrien 191490075Sobrien(define_insn "subsi3" 191590075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 191690075Sobrien (minus:SI (match_operand:SI 1 "gr_reg_or_8bit_operand" "rK") 191790075Sobrien (match_operand:SI 2 "gr_register_operand" "r")))] 191890075Sobrien "" 191990075Sobrien "sub %0 = %1, %2" 192090075Sobrien [(set_attr "itanium_class" "ialu")]) 192190075Sobrien 192290075Sobrien(define_insn "*subsi3_minus1" 192390075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 192490075Sobrien (plus:SI (not:SI (match_operand:SI 1 "gr_register_operand" "r")) 192590075Sobrien (match_operand:SI 2 "gr_register_operand" "r")))] 192690075Sobrien "" 192790075Sobrien "sub %0 = %2, %1, 1" 192890075Sobrien [(set_attr "itanium_class" "ialu")]) 192990075Sobrien 193090075Sobrien;; ??? Could add maddsi3 patterns patterned after the madddi3 patterns. 193190075Sobrien 193290075Sobrien(define_insn "mulsi3" 193390075Sobrien [(set (match_operand:SI 0 "fr_register_operand" "=f") 193490075Sobrien (mult:SI (match_operand:SI 1 "grfr_register_operand" "f") 193590075Sobrien (match_operand:SI 2 "grfr_register_operand" "f")))] 193690075Sobrien "" 193790075Sobrien "xmpy.l %0 = %1, %2" 193890075Sobrien [(set_attr "itanium_class" "xmpy")]) 193990075Sobrien 194090075Sobrien(define_insn "maddsi4" 194190075Sobrien [(set (match_operand:SI 0 "fr_register_operand" "=f") 194290075Sobrien (plus:SI (mult:SI (match_operand:SI 1 "grfr_register_operand" "f") 194390075Sobrien (match_operand:SI 2 "grfr_register_operand" "f")) 194490075Sobrien (match_operand:SI 3 "grfr_register_operand" "f")))] 194590075Sobrien "" 194690075Sobrien "xma.l %0 = %1, %2, %3" 194790075Sobrien [(set_attr "itanium_class" "xmpy")]) 194890075Sobrien 194990075Sobrien(define_insn "negsi2" 195090075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 195190075Sobrien (neg:SI (match_operand:SI 1 "gr_register_operand" "r")))] 195290075Sobrien "" 195390075Sobrien "sub %0 = r0, %1" 195490075Sobrien [(set_attr "itanium_class" "ialu")]) 195590075Sobrien 195690075Sobrien(define_expand "abssi2" 195790075Sobrien [(set (match_dup 2) 195890075Sobrien (ge:BI (match_operand:SI 1 "gr_register_operand" "") (const_int 0))) 195990075Sobrien (set (match_operand:SI 0 "gr_register_operand" "") 196090075Sobrien (if_then_else:SI (eq (match_dup 2) (const_int 0)) 196190075Sobrien (neg:SI (match_dup 1)) 196290075Sobrien (match_dup 1)))] 196390075Sobrien "" 1964117395Skan { operands[2] = gen_reg_rtx (BImode); }) 196590075Sobrien 196690075Sobrien(define_expand "sminsi3" 196790075Sobrien [(set (match_dup 3) 196890075Sobrien (ge:BI (match_operand:SI 1 "gr_register_operand" "") 196990075Sobrien (match_operand:SI 2 "gr_register_operand" ""))) 197090075Sobrien (set (match_operand:SI 0 "gr_register_operand" "") 197190075Sobrien (if_then_else:SI (ne (match_dup 3) (const_int 0)) 197290075Sobrien (match_dup 2) (match_dup 1)))] 197390075Sobrien "" 1974117395Skan { operands[3] = gen_reg_rtx (BImode); }) 197590075Sobrien 197690075Sobrien(define_expand "smaxsi3" 197790075Sobrien [(set (match_dup 3) 197890075Sobrien (ge:BI (match_operand:SI 1 "gr_register_operand" "") 197990075Sobrien (match_operand:SI 2 "gr_register_operand" ""))) 198090075Sobrien (set (match_operand:SI 0 "gr_register_operand" "") 198190075Sobrien (if_then_else:SI (ne (match_dup 3) (const_int 0)) 198290075Sobrien (match_dup 1) (match_dup 2)))] 198390075Sobrien "" 1984117395Skan { operands[3] = gen_reg_rtx (BImode); }) 198590075Sobrien 198690075Sobrien(define_expand "uminsi3" 198790075Sobrien [(set (match_dup 3) 198890075Sobrien (geu:BI (match_operand:SI 1 "gr_register_operand" "") 198990075Sobrien (match_operand:SI 2 "gr_register_operand" ""))) 199090075Sobrien (set (match_operand:SI 0 "gr_register_operand" "") 199190075Sobrien (if_then_else:SI (ne (match_dup 3) (const_int 0)) 199290075Sobrien (match_dup 2) (match_dup 1)))] 199390075Sobrien "" 1994117395Skan { operands[3] = gen_reg_rtx (BImode); }) 199590075Sobrien 199690075Sobrien(define_expand "umaxsi3" 199790075Sobrien [(set (match_dup 3) 199890075Sobrien (geu:BI (match_operand:SI 1 "gr_register_operand" "") 199990075Sobrien (match_operand:SI 2 "gr_register_operand" ""))) 200090075Sobrien (set (match_operand:SI 0 "gr_register_operand" "") 200190075Sobrien (if_then_else:SI (ne (match_dup 3) (const_int 0)) 200290075Sobrien (match_dup 1) (match_dup 2)))] 200390075Sobrien "" 2004117395Skan { operands[3] = gen_reg_rtx (BImode); }) 200590075Sobrien 200690075Sobrien(define_expand "divsi3" 200790075Sobrien [(set (match_operand:SI 0 "register_operand" "") 200890075Sobrien (div:SI (match_operand:SI 1 "general_operand" "") 200990075Sobrien (match_operand:SI 2 "general_operand" "")))] 2010117395Skan "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV" 201190075Sobrien{ 201290075Sobrien rtx op1_tf, op2_tf, op0_tf, op0_di, twon34; 2013117395Skan REAL_VALUE_TYPE twon34_r; 201490075Sobrien 201590075Sobrien op0_tf = gen_reg_rtx (TFmode); 201690075Sobrien op0_di = gen_reg_rtx (DImode); 201790075Sobrien 201890075Sobrien if (CONSTANT_P (operands[1])) 201990075Sobrien operands[1] = force_reg (SImode, operands[1]); 202090075Sobrien op1_tf = gen_reg_rtx (TFmode); 202190075Sobrien expand_float (op1_tf, operands[1], 0); 202290075Sobrien 202390075Sobrien if (CONSTANT_P (operands[2])) 202490075Sobrien operands[2] = force_reg (SImode, operands[2]); 202590075Sobrien op2_tf = gen_reg_rtx (TFmode); 202690075Sobrien expand_float (op2_tf, operands[2], 0); 202790075Sobrien 202890075Sobrien /* 2^-34 */ 2029117395Skan real_2expN (&twon34_r, -34); 2030117395Skan twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, TFmode); 203190075Sobrien twon34 = force_reg (TFmode, twon34); 203290075Sobrien 203390075Sobrien emit_insn (gen_divsi3_internal (op0_tf, op1_tf, op2_tf, twon34)); 203490075Sobrien 203590075Sobrien emit_insn (gen_fix_trunctfdi2_alts (op0_di, op0_tf, const1_rtx)); 203690075Sobrien emit_move_insn (operands[0], gen_lowpart (SImode, op0_di)); 203790075Sobrien DONE; 2038117395Skan}) 203990075Sobrien 204090075Sobrien(define_expand "modsi3" 204190075Sobrien [(set (match_operand:SI 0 "register_operand" "") 204290075Sobrien (mod:SI (match_operand:SI 1 "general_operand" "") 204390075Sobrien (match_operand:SI 2 "general_operand" "")))] 2044117395Skan "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV" 204590075Sobrien{ 204690075Sobrien rtx op2_neg, op1_di, div; 204790075Sobrien 204890075Sobrien div = gen_reg_rtx (SImode); 204990075Sobrien emit_insn (gen_divsi3 (div, operands[1], operands[2])); 205090075Sobrien 205190075Sobrien op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0); 205290075Sobrien 205390075Sobrien /* This is a trick to get us to reuse the value that we're sure to 205490075Sobrien have already copied to the FP regs. */ 205590075Sobrien op1_di = gen_reg_rtx (DImode); 205690075Sobrien convert_move (op1_di, operands[1], 0); 205790075Sobrien 205890075Sobrien emit_insn (gen_maddsi4 (operands[0], div, op2_neg, 205990075Sobrien gen_lowpart (SImode, op1_di))); 206090075Sobrien DONE; 2061117395Skan}) 206290075Sobrien 206390075Sobrien(define_expand "udivsi3" 206490075Sobrien [(set (match_operand:SI 0 "register_operand" "") 206590075Sobrien (udiv:SI (match_operand:SI 1 "general_operand" "") 206690075Sobrien (match_operand:SI 2 "general_operand" "")))] 2067117395Skan "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV" 206890075Sobrien{ 206990075Sobrien rtx op1_tf, op2_tf, op0_tf, op0_di, twon34; 2070117395Skan REAL_VALUE_TYPE twon34_r; 207190075Sobrien 207290075Sobrien op0_tf = gen_reg_rtx (TFmode); 207390075Sobrien op0_di = gen_reg_rtx (DImode); 207490075Sobrien 207590075Sobrien if (CONSTANT_P (operands[1])) 207690075Sobrien operands[1] = force_reg (SImode, operands[1]); 207790075Sobrien op1_tf = gen_reg_rtx (TFmode); 207890075Sobrien expand_float (op1_tf, operands[1], 1); 207990075Sobrien 208090075Sobrien if (CONSTANT_P (operands[2])) 208190075Sobrien operands[2] = force_reg (SImode, operands[2]); 208290075Sobrien op2_tf = gen_reg_rtx (TFmode); 208390075Sobrien expand_float (op2_tf, operands[2], 1); 208490075Sobrien 208590075Sobrien /* 2^-34 */ 2086117395Skan real_2expN (&twon34_r, -34); 2087117395Skan twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, TFmode); 208890075Sobrien twon34 = force_reg (TFmode, twon34); 208990075Sobrien 209090075Sobrien emit_insn (gen_divsi3_internal (op0_tf, op1_tf, op2_tf, twon34)); 209190075Sobrien 209290075Sobrien emit_insn (gen_fixuns_trunctfdi2_alts (op0_di, op0_tf, const1_rtx)); 209390075Sobrien emit_move_insn (operands[0], gen_lowpart (SImode, op0_di)); 209490075Sobrien DONE; 2095117395Skan}) 209690075Sobrien 209790075Sobrien(define_expand "umodsi3" 209890075Sobrien [(set (match_operand:SI 0 "register_operand" "") 209990075Sobrien (umod:SI (match_operand:SI 1 "general_operand" "") 210090075Sobrien (match_operand:SI 2 "general_operand" "")))] 2101117395Skan "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV" 210290075Sobrien{ 210390075Sobrien rtx op2_neg, op1_di, div; 210490075Sobrien 210590075Sobrien div = gen_reg_rtx (SImode); 210690075Sobrien emit_insn (gen_udivsi3 (div, operands[1], operands[2])); 210790075Sobrien 210890075Sobrien op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0); 210990075Sobrien 211090075Sobrien /* This is a trick to get us to reuse the value that we're sure to 211190075Sobrien have already copied to the FP regs. */ 211290075Sobrien op1_di = gen_reg_rtx (DImode); 211390075Sobrien convert_move (op1_di, operands[1], 1); 211490075Sobrien 211590075Sobrien emit_insn (gen_maddsi4 (operands[0], div, op2_neg, 211690075Sobrien gen_lowpart (SImode, op1_di))); 211790075Sobrien DONE; 2118117395Skan}) 211990075Sobrien 212090075Sobrien(define_insn_and_split "divsi3_internal" 212190075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "=&f") 212290075Sobrien (float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f") 212390075Sobrien (match_operand:TF 2 "fr_register_operand" "f")))) 212490075Sobrien (clobber (match_scratch:TF 4 "=&f")) 212590075Sobrien (clobber (match_scratch:TF 5 "=&f")) 212690075Sobrien (clobber (match_scratch:BI 6 "=c")) 212790075Sobrien (use (match_operand:TF 3 "fr_register_operand" "f"))] 2128117395Skan "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV" 212990075Sobrien "#" 213090075Sobrien "&& reload_completed" 213190075Sobrien [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2))) 2132117395Skan (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)] 2133117395Skan UNSPEC_FR_RECIP_APPROX)) 213490075Sobrien (use (const_int 1))]) 213590075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 213690075Sobrien (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0))) 213790075Sobrien (use (const_int 1))])) 213890075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 213990075Sobrien (parallel [(set (match_dup 5) 214090075Sobrien (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0))) 214190075Sobrien (match_dup 7))) 214290075Sobrien (use (const_int 1))])) 214390075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 214490075Sobrien (parallel [(set (match_dup 4) 214590075Sobrien (plus:TF (mult:TF (match_dup 5) (match_dup 4)) 214690075Sobrien (match_dup 4))) 214790075Sobrien (use (const_int 1))])) 214890075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 214990075Sobrien (parallel [(set (match_dup 5) 215090075Sobrien (plus:TF (mult:TF (match_dup 5) (match_dup 5)) 215190075Sobrien (match_dup 3))) 215290075Sobrien (use (const_int 1))])) 215390075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 215490075Sobrien (parallel [(set (match_dup 0) 215590075Sobrien (plus:TF (mult:TF (match_dup 5) (match_dup 4)) 215690075Sobrien (match_dup 4))) 215790075Sobrien (use (const_int 1))])) 215890075Sobrien ] 215990075Sobrien "operands[7] = CONST1_RTX (TFmode);" 216090075Sobrien [(set_attr "predicable" "no")]) 216190075Sobrien 216290075Sobrien;; :::::::::::::::::::: 216390075Sobrien;; :: 216490075Sobrien;; :: 64 bit Integer arithmetic 216590075Sobrien;; :: 216690075Sobrien;; :::::::::::::::::::: 216790075Sobrien 216890075Sobrien(define_insn "adddi3" 216990075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r") 217090075Sobrien (plus:DI (match_operand:DI 1 "gr_register_operand" "%r,r,a") 217190075Sobrien (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J")))] 217290075Sobrien "" 217390075Sobrien "@ 2174117395Skan add %0 = %1, %2 2175117395Skan adds %0 = %2, %1 2176117395Skan addl %0 = %2, %1" 217790075Sobrien [(set_attr "itanium_class" "ialu")]) 217890075Sobrien 217990075Sobrien(define_insn "*adddi3_plus1" 218090075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 218190075Sobrien (plus:DI (plus:DI (match_operand:DI 1 "gr_register_operand" "r") 218290075Sobrien (match_operand:DI 2 "gr_register_operand" "r")) 218390075Sobrien (const_int 1)))] 218490075Sobrien "" 218590075Sobrien "add %0 = %1, %2, 1" 218690075Sobrien [(set_attr "itanium_class" "ialu")]) 218790075Sobrien 218890075Sobrien;; This has some of the same problems as shladd. We let the shladd 218990075Sobrien;; eliminator hack handle it, which results in the 1 being forced into 219090075Sobrien;; a register, but not more ugliness here. 219190075Sobrien(define_insn "*adddi3_plus1_alt" 219290075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 219390075Sobrien (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r") 219490075Sobrien (const_int 2)) 219590075Sobrien (const_int 1)))] 219690075Sobrien "" 219790075Sobrien "add %0 = %1, %1, 1" 219890075Sobrien [(set_attr "itanium_class" "ialu")]) 219990075Sobrien 220090075Sobrien(define_insn "subdi3" 220190075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 220290075Sobrien (minus:DI (match_operand:DI 1 "gr_reg_or_8bit_operand" "rK") 220390075Sobrien (match_operand:DI 2 "gr_register_operand" "r")))] 220490075Sobrien "" 220590075Sobrien "sub %0 = %1, %2" 220690075Sobrien [(set_attr "itanium_class" "ialu")]) 220790075Sobrien 220890075Sobrien(define_insn "*subdi3_minus1" 220990075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 221090075Sobrien (plus:DI (not:DI (match_operand:DI 1 "gr_register_operand" "r")) 221190075Sobrien (match_operand:DI 2 "gr_register_operand" "r")))] 221290075Sobrien "" 221390075Sobrien "sub %0 = %2, %1, 1" 221490075Sobrien [(set_attr "itanium_class" "ialu")]) 221590075Sobrien 221690075Sobrien;; ??? Use grfr instead of fr because of virtual register elimination 221790075Sobrien;; and silly test cases multiplying by the frame pointer. 221890075Sobrien(define_insn "muldi3" 221990075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 222090075Sobrien (mult:DI (match_operand:DI 1 "grfr_register_operand" "f") 222190075Sobrien (match_operand:DI 2 "grfr_register_operand" "f")))] 222290075Sobrien "" 222390075Sobrien "xmpy.l %0 = %1, %2" 222490075Sobrien [(set_attr "itanium_class" "xmpy")]) 222590075Sobrien 222690075Sobrien;; ??? If operand 3 is an eliminable reg, then register elimination causes the 222790075Sobrien;; same problem that we have with shladd below. Unfortunately, this case is 222890075Sobrien;; much harder to fix because the multiply puts the result in an FP register, 222990075Sobrien;; but the add needs inputs from a general register. We add a spurious clobber 223090075Sobrien;; here so that it will be present just in case register elimination gives us 223190075Sobrien;; the funny result. 223290075Sobrien 223390075Sobrien;; ??? Maybe validate_changes should try adding match_scratch clobbers? 223490075Sobrien 223590075Sobrien;; ??? Maybe we should change how adds are canonicalized. 223690075Sobrien 223790075Sobrien(define_insn "madddi4" 223890075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 223990075Sobrien (plus:DI (mult:DI (match_operand:DI 1 "grfr_register_operand" "f") 224090075Sobrien (match_operand:DI 2 "grfr_register_operand" "f")) 224190075Sobrien (match_operand:DI 3 "grfr_register_operand" "f"))) 224290075Sobrien (clobber (match_scratch:DI 4 "=X"))] 224390075Sobrien "" 224490075Sobrien "xma.l %0 = %1, %2, %3" 224590075Sobrien [(set_attr "itanium_class" "xmpy")]) 224690075Sobrien 224790075Sobrien;; This can be created by register elimination if operand3 of shladd is an 224890075Sobrien;; eliminable register or has reg_equiv_constant set. 224990075Sobrien 225090075Sobrien;; We have to use nonmemory_operand for operand 4, to ensure that the 225190075Sobrien;; validate_changes call inside eliminate_regs will always succeed. If it 225290075Sobrien;; doesn't succeed, then this remain a madddi4 pattern, and will be reloaded 225390075Sobrien;; incorrectly. 225490075Sobrien 225590075Sobrien(define_insn "*madddi4_elim" 225690075Sobrien [(set (match_operand:DI 0 "register_operand" "=&r") 225790075Sobrien (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "f") 225890075Sobrien (match_operand:DI 2 "register_operand" "f")) 225990075Sobrien (match_operand:DI 3 "register_operand" "f")) 226090075Sobrien (match_operand:DI 4 "nonmemory_operand" "rI"))) 226190075Sobrien (clobber (match_scratch:DI 5 "=f"))] 226290075Sobrien "reload_in_progress" 226390075Sobrien "#" 226490075Sobrien [(set_attr "itanium_class" "unknown")]) 226590075Sobrien 226690075Sobrien(define_split 226790075Sobrien [(set (match_operand:DI 0 "register_operand" "") 226890075Sobrien (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "") 226990075Sobrien (match_operand:DI 2 "register_operand" "")) 227090075Sobrien (match_operand:DI 3 "register_operand" "")) 227190075Sobrien (match_operand:DI 4 "gr_reg_or_14bit_operand" ""))) 227290075Sobrien (clobber (match_scratch:DI 5 ""))] 227390075Sobrien "reload_completed" 227490075Sobrien [(parallel [(set (match_dup 5) (plus:DI (mult:DI (match_dup 1) (match_dup 2)) 227590075Sobrien (match_dup 3))) 227690075Sobrien (clobber (match_dup 0))]) 227790075Sobrien (set (match_dup 0) (match_dup 5)) 227890075Sobrien (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))] 227990075Sobrien "") 228090075Sobrien 228190075Sobrien;; ??? There are highpart multiply and add instructions, but we have no way 228290075Sobrien;; to generate them. 228390075Sobrien 228490075Sobrien(define_insn "smuldi3_highpart" 228590075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 228690075Sobrien (truncate:DI 228790075Sobrien (lshiftrt:TI 228890075Sobrien (mult:TI (sign_extend:TI 228990075Sobrien (match_operand:DI 1 "fr_register_operand" "f")) 229090075Sobrien (sign_extend:TI 229190075Sobrien (match_operand:DI 2 "fr_register_operand" "f"))) 229290075Sobrien (const_int 64))))] 229390075Sobrien "" 229490075Sobrien "xmpy.h %0 = %1, %2" 229590075Sobrien [(set_attr "itanium_class" "xmpy")]) 229690075Sobrien 229790075Sobrien(define_insn "umuldi3_highpart" 229890075Sobrien [(set (match_operand:DI 0 "fr_register_operand" "=f") 229990075Sobrien (truncate:DI 230090075Sobrien (lshiftrt:TI 230190075Sobrien (mult:TI (zero_extend:TI 230290075Sobrien (match_operand:DI 1 "fr_register_operand" "f")) 230390075Sobrien (zero_extend:TI 230490075Sobrien (match_operand:DI 2 "fr_register_operand" "f"))) 230590075Sobrien (const_int 64))))] 230690075Sobrien "" 230790075Sobrien "xmpy.hu %0 = %1, %2" 230890075Sobrien [(set_attr "itanium_class" "xmpy")]) 230990075Sobrien 231090075Sobrien(define_insn "negdi2" 231190075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 231290075Sobrien (neg:DI (match_operand:DI 1 "gr_register_operand" "r")))] 231390075Sobrien "" 231490075Sobrien "sub %0 = r0, %1" 231590075Sobrien [(set_attr "itanium_class" "ialu")]) 231690075Sobrien 231790075Sobrien(define_expand "absdi2" 231890075Sobrien [(set (match_dup 2) 231990075Sobrien (ge:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0))) 232090075Sobrien (set (match_operand:DI 0 "gr_register_operand" "") 232190075Sobrien (if_then_else:DI (eq (match_dup 2) (const_int 0)) 232290075Sobrien (neg:DI (match_dup 1)) 232390075Sobrien (match_dup 1)))] 232490075Sobrien "" 2325117395Skan { operands[2] = gen_reg_rtx (BImode); }) 232690075Sobrien 232790075Sobrien(define_expand "smindi3" 232890075Sobrien [(set (match_dup 3) 232990075Sobrien (ge:BI (match_operand:DI 1 "gr_register_operand" "") 233090075Sobrien (match_operand:DI 2 "gr_register_operand" ""))) 233190075Sobrien (set (match_operand:DI 0 "gr_register_operand" "") 233290075Sobrien (if_then_else:DI (ne (match_dup 3) (const_int 0)) 233390075Sobrien (match_dup 2) (match_dup 1)))] 233490075Sobrien "" 2335117395Skan { operands[3] = gen_reg_rtx (BImode); }) 233690075Sobrien 233790075Sobrien(define_expand "smaxdi3" 233890075Sobrien [(set (match_dup 3) 233990075Sobrien (ge:BI (match_operand:DI 1 "gr_register_operand" "") 234090075Sobrien (match_operand:DI 2 "gr_register_operand" ""))) 234190075Sobrien (set (match_operand:DI 0 "gr_register_operand" "") 234290075Sobrien (if_then_else:DI (ne (match_dup 3) (const_int 0)) 234390075Sobrien (match_dup 1) (match_dup 2)))] 234490075Sobrien "" 2345117395Skan { operands[3] = gen_reg_rtx (BImode); }) 234690075Sobrien 234790075Sobrien(define_expand "umindi3" 234890075Sobrien [(set (match_dup 3) 234990075Sobrien (geu:BI (match_operand:DI 1 "gr_register_operand" "") 235090075Sobrien (match_operand:DI 2 "gr_register_operand" ""))) 235190075Sobrien (set (match_operand:DI 0 "gr_register_operand" "") 235290075Sobrien (if_then_else:DI (ne (match_dup 3) (const_int 0)) 235390075Sobrien (match_dup 2) (match_dup 1)))] 235490075Sobrien "" 2355117395Skan { operands[3] = gen_reg_rtx (BImode); }) 235690075Sobrien 235790075Sobrien(define_expand "umaxdi3" 235890075Sobrien [(set (match_dup 3) 235990075Sobrien (geu:BI (match_operand:DI 1 "gr_register_operand" "") 236090075Sobrien (match_operand:DI 2 "gr_register_operand" ""))) 236190075Sobrien (set (match_operand:DI 0 "gr_register_operand" "") 236290075Sobrien (if_then_else:DI (ne (match_dup 3) (const_int 0)) 236390075Sobrien (match_dup 1) (match_dup 2)))] 236490075Sobrien "" 2365117395Skan { operands[3] = gen_reg_rtx (BImode); }) 236690075Sobrien 236790075Sobrien(define_expand "ffsdi2" 236890075Sobrien [(set (match_dup 6) 236990075Sobrien (eq:BI (match_operand:DI 1 "gr_register_operand" "") (const_int 0))) 237090075Sobrien (set (match_dup 2) (plus:DI (match_dup 1) (const_int -1))) 237190075Sobrien (set (match_dup 5) (const_int 0)) 237290075Sobrien (set (match_dup 3) (xor:DI (match_dup 1) (match_dup 2))) 2373117395Skan (set (match_dup 4) (unspec:DI [(match_dup 3)] UNSPEC_POPCNT)) 237490075Sobrien (set (match_operand:DI 0 "gr_register_operand" "") 237590075Sobrien (if_then_else:DI (ne (match_dup 6) (const_int 0)) 237690075Sobrien (match_dup 5) (match_dup 4)))] 237790075Sobrien "" 237890075Sobrien{ 237990075Sobrien operands[2] = gen_reg_rtx (DImode); 238090075Sobrien operands[3] = gen_reg_rtx (DImode); 238190075Sobrien operands[4] = gen_reg_rtx (DImode); 238290075Sobrien operands[5] = gen_reg_rtx (DImode); 238390075Sobrien operands[6] = gen_reg_rtx (BImode); 2384117395Skan}) 238590075Sobrien 238690075Sobrien(define_insn "*popcnt" 238790075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 2388117395Skan (unspec:DI [(match_operand:DI 1 "gr_register_operand" "r")] 2389117395Skan UNSPEC_POPCNT))] 239090075Sobrien "" 239190075Sobrien "popcnt %0 = %1" 239290075Sobrien [(set_attr "itanium_class" "mmmul")]) 239390075Sobrien 239490075Sobrien(define_expand "divdi3" 239590075Sobrien [(set (match_operand:DI 0 "register_operand" "") 239690075Sobrien (div:DI (match_operand:DI 1 "general_operand" "") 239790075Sobrien (match_operand:DI 2 "general_operand" "")))] 2398117395Skan "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV" 239990075Sobrien{ 240090075Sobrien rtx op1_tf, op2_tf, op0_tf; 240190075Sobrien 240290075Sobrien op0_tf = gen_reg_rtx (TFmode); 240390075Sobrien 240490075Sobrien if (CONSTANT_P (operands[1])) 240590075Sobrien operands[1] = force_reg (DImode, operands[1]); 240690075Sobrien op1_tf = gen_reg_rtx (TFmode); 240790075Sobrien expand_float (op1_tf, operands[1], 0); 240890075Sobrien 240990075Sobrien if (CONSTANT_P (operands[2])) 241090075Sobrien operands[2] = force_reg (DImode, operands[2]); 241190075Sobrien op2_tf = gen_reg_rtx (TFmode); 241290075Sobrien expand_float (op2_tf, operands[2], 0); 241390075Sobrien 2414117395Skan if (TARGET_INLINE_INT_DIV_LAT) 241590075Sobrien emit_insn (gen_divdi3_internal_lat (op0_tf, op1_tf, op2_tf)); 241690075Sobrien else 241790075Sobrien emit_insn (gen_divdi3_internal_thr (op0_tf, op1_tf, op2_tf)); 241890075Sobrien 241990075Sobrien emit_insn (gen_fix_trunctfdi2_alts (operands[0], op0_tf, const1_rtx)); 242090075Sobrien DONE; 2421117395Skan}) 242290075Sobrien 242390075Sobrien(define_expand "moddi3" 242490075Sobrien [(set (match_operand:DI 0 "register_operand" "") 242590075Sobrien (mod:SI (match_operand:DI 1 "general_operand" "") 242690075Sobrien (match_operand:DI 2 "general_operand" "")))] 2427117395Skan "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV" 242890075Sobrien{ 242990075Sobrien rtx op2_neg, div; 243090075Sobrien 243190075Sobrien div = gen_reg_rtx (DImode); 243290075Sobrien emit_insn (gen_divdi3 (div, operands[1], operands[2])); 243390075Sobrien 243490075Sobrien op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0); 243590075Sobrien 243690075Sobrien emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1])); 243790075Sobrien DONE; 2438117395Skan}) 243990075Sobrien 244090075Sobrien(define_expand "udivdi3" 244190075Sobrien [(set (match_operand:DI 0 "register_operand" "") 244290075Sobrien (udiv:DI (match_operand:DI 1 "general_operand" "") 244390075Sobrien (match_operand:DI 2 "general_operand" "")))] 2444117395Skan "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV" 244590075Sobrien{ 244690075Sobrien rtx op1_tf, op2_tf, op0_tf; 244790075Sobrien 244890075Sobrien op0_tf = gen_reg_rtx (TFmode); 244990075Sobrien 245090075Sobrien if (CONSTANT_P (operands[1])) 245190075Sobrien operands[1] = force_reg (DImode, operands[1]); 245290075Sobrien op1_tf = gen_reg_rtx (TFmode); 245390075Sobrien expand_float (op1_tf, operands[1], 1); 245490075Sobrien 245590075Sobrien if (CONSTANT_P (operands[2])) 245690075Sobrien operands[2] = force_reg (DImode, operands[2]); 245790075Sobrien op2_tf = gen_reg_rtx (TFmode); 245890075Sobrien expand_float (op2_tf, operands[2], 1); 245990075Sobrien 2460117395Skan if (TARGET_INLINE_INT_DIV_LAT) 246190075Sobrien emit_insn (gen_divdi3_internal_lat (op0_tf, op1_tf, op2_tf)); 246290075Sobrien else 246390075Sobrien emit_insn (gen_divdi3_internal_thr (op0_tf, op1_tf, op2_tf)); 246490075Sobrien 246590075Sobrien emit_insn (gen_fixuns_trunctfdi2_alts (operands[0], op0_tf, const1_rtx)); 246690075Sobrien DONE; 2467117395Skan}) 246890075Sobrien 246990075Sobrien(define_expand "umoddi3" 247090075Sobrien [(set (match_operand:DI 0 "register_operand" "") 247190075Sobrien (umod:DI (match_operand:DI 1 "general_operand" "") 247290075Sobrien (match_operand:DI 2 "general_operand" "")))] 2473117395Skan "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV" 247490075Sobrien{ 247590075Sobrien rtx op2_neg, div; 247690075Sobrien 247790075Sobrien div = gen_reg_rtx (DImode); 247890075Sobrien emit_insn (gen_udivdi3 (div, operands[1], operands[2])); 247990075Sobrien 248090075Sobrien op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0); 248190075Sobrien 248290075Sobrien emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1])); 248390075Sobrien DONE; 2484117395Skan}) 248590075Sobrien 248690075Sobrien(define_insn_and_split "divdi3_internal_lat" 248790075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "=&f") 248890075Sobrien (float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f") 248990075Sobrien (match_operand:TF 2 "fr_register_operand" "f")))) 249090075Sobrien (clobber (match_scratch:TF 3 "=&f")) 249190075Sobrien (clobber (match_scratch:TF 4 "=&f")) 249290075Sobrien (clobber (match_scratch:TF 5 "=&f")) 249390075Sobrien (clobber (match_scratch:BI 6 "=c"))] 2494117395Skan "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV_LAT" 249590075Sobrien "#" 249690075Sobrien "&& reload_completed" 249790075Sobrien [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2))) 2498117395Skan (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)] 2499117395Skan UNSPEC_FR_RECIP_APPROX)) 250090075Sobrien (use (const_int 1))]) 250190075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 250290075Sobrien (parallel [(set (match_dup 3) 250390075Sobrien (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0))) 250490075Sobrien (match_dup 7))) 250590075Sobrien (use (const_int 1))])) 250690075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 250790075Sobrien (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0))) 250890075Sobrien (use (const_int 1))])) 250990075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 251090075Sobrien (parallel [(set (match_dup 5) (mult:TF (match_dup 3) (match_dup 3))) 251190075Sobrien (use (const_int 1))])) 251290075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 251390075Sobrien (parallel [(set (match_dup 4) 251490075Sobrien (plus:TF (mult:TF (match_dup 3) (match_dup 4)) 251590075Sobrien (match_dup 4))) 251690075Sobrien (use (const_int 1))])) 251790075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 251890075Sobrien (parallel [(set (match_dup 0) 251990075Sobrien (plus:TF (mult:TF (match_dup 3) (match_dup 0)) 252090075Sobrien (match_dup 0))) 252190075Sobrien (use (const_int 1))])) 252290075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 252390075Sobrien (parallel [(set (match_dup 3) 252490075Sobrien (plus:TF (mult:TF (match_dup 5) (match_dup 4)) 252590075Sobrien (match_dup 4))) 252690075Sobrien (use (const_int 1))])) 252790075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 252890075Sobrien (parallel [(set (match_dup 0) 252990075Sobrien (plus:TF (mult:TF (match_dup 5) (match_dup 0)) 253090075Sobrien (match_dup 0))) 253190075Sobrien (use (const_int 1))])) 253290075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 253390075Sobrien (parallel [(set (match_dup 4) 253490075Sobrien (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3))) 253590075Sobrien (match_dup 1))) 253690075Sobrien (use (const_int 1))])) 253790075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 253890075Sobrien (parallel [(set (match_dup 0) 253990075Sobrien (plus:TF (mult:TF (match_dup 4) (match_dup 0)) 254090075Sobrien (match_dup 3))) 254190075Sobrien (use (const_int 1))])) 254290075Sobrien ] 254390075Sobrien "operands[7] = CONST1_RTX (TFmode);" 254490075Sobrien [(set_attr "predicable" "no")]) 254590075Sobrien 254690075Sobrien(define_insn_and_split "divdi3_internal_thr" 254790075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "=&f") 254890075Sobrien (float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f") 254990075Sobrien (match_operand:TF 2 "fr_register_operand" "f")))) 255090075Sobrien (clobber (match_scratch:TF 3 "=&f")) 255190075Sobrien (clobber (match_scratch:TF 4 "=f")) 255290075Sobrien (clobber (match_scratch:BI 5 "=c"))] 2553117395Skan "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV_THR" 255490075Sobrien "#" 255590075Sobrien "&& reload_completed" 255690075Sobrien [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2))) 2557117395Skan (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)] 2558117395Skan UNSPEC_FR_RECIP_APPROX)) 255990075Sobrien (use (const_int 1))]) 256090075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 256190075Sobrien (parallel [(set (match_dup 3) 256290075Sobrien (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0))) 256390075Sobrien (match_dup 6))) 256490075Sobrien (use (const_int 1))])) 256590075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 256690075Sobrien (parallel [(set (match_dup 0) 256790075Sobrien (plus:TF (mult:TF (match_dup 3) (match_dup 0)) 256890075Sobrien (match_dup 0))) 256990075Sobrien (use (const_int 1))])) 257090075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 257190075Sobrien (parallel [(set (match_dup 3) (mult:TF (match_dup 3) (match_dup 3))) 257290075Sobrien (use (const_int 1))])) 257390075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 257490075Sobrien (parallel [(set (match_dup 0) 257590075Sobrien (plus:TF (mult:TF (match_dup 3) (match_dup 0)) 257690075Sobrien (match_dup 0))) 257790075Sobrien (use (const_int 1))])) 257890075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 257990075Sobrien (parallel [(set (match_dup 3) (mult:TF (match_dup 0) (match_dup 1))) 258090075Sobrien (use (const_int 1))])) 258190075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 258290075Sobrien (parallel [(set (match_dup 4) 258390075Sobrien (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3))) 258490075Sobrien (match_dup 1))) 258590075Sobrien (use (const_int 1))])) 258690075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 258790075Sobrien (parallel [(set (match_dup 0) 258890075Sobrien (plus:TF (mult:TF (match_dup 4) (match_dup 0)) 258990075Sobrien (match_dup 3))) 259090075Sobrien (use (const_int 1))])) 259190075Sobrien ] 259290075Sobrien "operands[6] = CONST1_RTX (TFmode);" 259390075Sobrien [(set_attr "predicable" "no")]) 259490075Sobrien 259590075Sobrien;; :::::::::::::::::::: 259690075Sobrien;; :: 259790075Sobrien;; :: 32 bit floating point arithmetic 259890075Sobrien;; :: 259990075Sobrien;; :::::::::::::::::::: 260090075Sobrien 260190075Sobrien(define_insn "addsf3" 260290075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 260390075Sobrien (plus:SF (match_operand:SF 1 "fr_register_operand" "%f") 260490075Sobrien (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))] 260590075Sobrien "" 260690075Sobrien "fadd.s %0 = %1, %F2" 260790075Sobrien [(set_attr "itanium_class" "fmac")]) 260890075Sobrien 260990075Sobrien(define_insn "subsf3" 261090075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 261190075Sobrien (minus:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG") 261290075Sobrien (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))] 261390075Sobrien "" 261490075Sobrien "fsub.s %0 = %F1, %F2" 261590075Sobrien [(set_attr "itanium_class" "fmac")]) 261690075Sobrien 261790075Sobrien(define_insn "mulsf3" 261890075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 261990075Sobrien (mult:SF (match_operand:SF 1 "fr_register_operand" "%f") 262090075Sobrien (match_operand:SF 2 "fr_register_operand" "f")))] 262190075Sobrien "" 262290075Sobrien "fmpy.s %0 = %1, %2" 262390075Sobrien [(set_attr "itanium_class" "fmac")]) 262490075Sobrien 262590075Sobrien(define_insn "abssf2" 262690075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 262790075Sobrien (abs:SF (match_operand:SF 1 "fr_register_operand" "f")))] 262890075Sobrien "" 262990075Sobrien "fabs %0 = %1" 263090075Sobrien [(set_attr "itanium_class" "fmisc")]) 263190075Sobrien 263290075Sobrien(define_insn "negsf2" 263390075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 263490075Sobrien (neg:SF (match_operand:SF 1 "fr_register_operand" "f")))] 263590075Sobrien "" 263690075Sobrien "fneg %0 = %1" 263790075Sobrien [(set_attr "itanium_class" "fmisc")]) 263890075Sobrien 263990075Sobrien(define_insn "*nabssf2" 264090075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 264190075Sobrien (neg:SF (abs:SF (match_operand:SF 1 "fr_register_operand" "f"))))] 264290075Sobrien "" 264390075Sobrien "fnegabs %0 = %1" 264490075Sobrien [(set_attr "itanium_class" "fmisc")]) 264590075Sobrien 264690075Sobrien(define_insn "minsf3" 264790075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 264890075Sobrien (smin:SF (match_operand:SF 1 "fr_register_operand" "f") 264990075Sobrien (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))] 265090075Sobrien "" 265190075Sobrien "fmin %0 = %1, %F2" 265290075Sobrien [(set_attr "itanium_class" "fmisc")]) 265390075Sobrien 265490075Sobrien(define_insn "maxsf3" 265590075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 265690075Sobrien (smax:SF (match_operand:SF 1 "fr_register_operand" "f") 265790075Sobrien (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")))] 265890075Sobrien "" 265990075Sobrien "fmax %0 = %1, %F2" 266090075Sobrien [(set_attr "itanium_class" "fmisc")]) 266190075Sobrien 266290075Sobrien(define_insn "*maddsf4" 266390075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 266490075Sobrien (plus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f") 266590075Sobrien (match_operand:SF 2 "fr_register_operand" "f")) 266690075Sobrien (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))] 266790075Sobrien "" 266890075Sobrien "fma.s %0 = %1, %2, %F3" 266990075Sobrien [(set_attr "itanium_class" "fmac")]) 267090075Sobrien 267190075Sobrien(define_insn "*msubsf4" 267290075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 267390075Sobrien (minus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f") 267490075Sobrien (match_operand:SF 2 "fr_register_operand" "f")) 267590075Sobrien (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))] 267690075Sobrien "" 267790075Sobrien "fms.s %0 = %1, %2, %F3" 267890075Sobrien [(set_attr "itanium_class" "fmac")]) 267990075Sobrien 268090075Sobrien(define_insn "*nmulsf3" 268190075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 268290075Sobrien (neg:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f") 268390075Sobrien (match_operand:SF 2 "fr_register_operand" "f"))))] 268490075Sobrien "" 268590075Sobrien "fnmpy.s %0 = %1, %2" 268690075Sobrien [(set_attr "itanium_class" "fmac")]) 268790075Sobrien 268890075Sobrien;; ??? Is it possible to canonicalize this as (minus (reg) (mult))? 268990075Sobrien 269090075Sobrien(define_insn "*nmaddsf4" 269190075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 269290075Sobrien (plus:SF (neg:SF (mult:SF 269390075Sobrien (match_operand:SF 1 "fr_register_operand" "f") 269490075Sobrien (match_operand:SF 2 "fr_register_operand" "f"))) 269590075Sobrien (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")))] 269690075Sobrien "" 269790075Sobrien "fnma.s %0 = %1, %2, %F3" 269890075Sobrien [(set_attr "itanium_class" "fmac")]) 269990075Sobrien 270090075Sobrien(define_expand "divsf3" 270190075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "") 270290075Sobrien (div:SF (match_operand:SF 1 "fr_register_operand" "") 270390075Sobrien (match_operand:SF 2 "fr_register_operand" "")))] 2704117395Skan "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV" 270590075Sobrien{ 270690075Sobrien rtx insn; 2707117395Skan if (TARGET_INLINE_FLOAT_DIV_LAT) 270890075Sobrien insn = gen_divsf3_internal_lat (operands[0], operands[1], operands[2]); 270990075Sobrien else 271090075Sobrien insn = gen_divsf3_internal_thr (operands[0], operands[1], operands[2]); 271190075Sobrien emit_insn (insn); 271290075Sobrien DONE; 2713117395Skan}) 271490075Sobrien 271590075Sobrien(define_insn_and_split "divsf3_internal_lat" 271690075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=&f") 271790075Sobrien (div:SF (match_operand:SF 1 "fr_register_operand" "f") 271890075Sobrien (match_operand:SF 2 "fr_register_operand" "f"))) 271990075Sobrien (clobber (match_scratch:TF 3 "=&f")) 272090075Sobrien (clobber (match_scratch:TF 4 "=f")) 272190075Sobrien (clobber (match_scratch:BI 5 "=c"))] 2722117395Skan "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_LAT" 272390075Sobrien "#" 272490075Sobrien "&& reload_completed" 272590075Sobrien [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8))) 2726117395Skan (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)] 2727117395Skan UNSPEC_FR_RECIP_APPROX)) 272890075Sobrien (use (const_int 1))]) 272990075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 273090075Sobrien (parallel [(set (match_dup 3) (mult:TF (match_dup 7) (match_dup 6))) 273190075Sobrien (use (const_int 1))])) 273290075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 273390075Sobrien (parallel [(set (match_dup 4) 273490075Sobrien (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6))) 273590075Sobrien (match_dup 10))) 273690075Sobrien (use (const_int 1))])) 273790075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 273890075Sobrien (parallel [(set (match_dup 3) 273990075Sobrien (plus:TF (mult:TF (match_dup 4) (match_dup 3)) 274090075Sobrien (match_dup 3))) 274190075Sobrien (use (const_int 1))])) 274290075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 274390075Sobrien (parallel [(set (match_dup 4) (mult:TF (match_dup 4) (match_dup 4))) 274490075Sobrien (use (const_int 1))])) 274590075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 274690075Sobrien (parallel [(set (match_dup 3) 274790075Sobrien (plus:TF (mult:TF (match_dup 4) (match_dup 3)) 274890075Sobrien (match_dup 3))) 274990075Sobrien (use (const_int 1))])) 275090075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 275190075Sobrien (parallel [(set (match_dup 4) (mult:TF (match_dup 4) (match_dup 4))) 275290075Sobrien (use (const_int 1))])) 275390075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 275490075Sobrien (parallel [(set (match_dup 9) 275590075Sobrien (float_truncate:DF 275690075Sobrien (plus:TF (mult:TF (match_dup 4) (match_dup 3)) 275790075Sobrien (match_dup 3)))) 275890075Sobrien (use (const_int 1))])) 275990075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 276090075Sobrien (set (match_dup 0) 276190075Sobrien (float_truncate:SF (match_dup 6)))) 276290075Sobrien ] 2763117395Skan{ 2764117395Skan operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0])); 2765117395Skan operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1])); 2766117395Skan operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2])); 2767117395Skan operands[9] = gen_rtx_REG (DFmode, REGNO (operands[0])); 2768117395Skan operands[10] = CONST1_RTX (TFmode); 2769117395Skan} 277090075Sobrien [(set_attr "predicable" "no")]) 277190075Sobrien 277290075Sobrien(define_insn_and_split "divsf3_internal_thr" 277390075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=&f") 277490075Sobrien (div:SF (match_operand:SF 1 "fr_register_operand" "f") 277590075Sobrien (match_operand:SF 2 "fr_register_operand" "f"))) 277690075Sobrien (clobber (match_scratch:TF 3 "=&f")) 277790075Sobrien (clobber (match_scratch:TF 4 "=f")) 277890075Sobrien (clobber (match_scratch:BI 5 "=c"))] 2779117395Skan "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_THR" 278090075Sobrien "#" 278190075Sobrien "&& reload_completed" 278290075Sobrien [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8))) 2783117395Skan (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)] 2784117395Skan UNSPEC_FR_RECIP_APPROX)) 278590075Sobrien (use (const_int 1))]) 278690075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 278790075Sobrien (parallel [(set (match_dup 3) 278890075Sobrien (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6))) 278990075Sobrien (match_dup 10))) 279090075Sobrien (use (const_int 1))])) 279190075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 279290075Sobrien (parallel [(set (match_dup 3) 279390075Sobrien (plus:TF (mult:TF (match_dup 3) (match_dup 3)) 279490075Sobrien (match_dup 3))) 279590075Sobrien (use (const_int 1))])) 279690075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 279790075Sobrien (parallel [(set (match_dup 6) 279890075Sobrien (plus:TF (mult:TF (match_dup 3) (match_dup 6)) 279990075Sobrien (match_dup 6))) 280090075Sobrien (use (const_int 1))])) 280190075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 280290075Sobrien (parallel [(set (match_dup 9) 280390075Sobrien (float_truncate:SF 280490075Sobrien (mult:TF (match_dup 7) (match_dup 6)))) 280590075Sobrien (use (const_int 1))])) 280690075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 280790075Sobrien (parallel [(set (match_dup 4) 280890075Sobrien (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 3))) 280990075Sobrien (match_dup 7))) 281090075Sobrien (use (const_int 1))])) 281190075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 281290075Sobrien (set (match_dup 0) 281390075Sobrien (float_truncate:SF 281490075Sobrien (plus:TF (mult:TF (match_dup 4) (match_dup 6)) 281590075Sobrien (match_dup 3))))) 281690075Sobrien ] 2817117395Skan{ 2818117395Skan operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0])); 2819117395Skan operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1])); 2820117395Skan operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2])); 2821117395Skan operands[9] = gen_rtx_REG (SFmode, REGNO (operands[3])); 2822117395Skan operands[10] = CONST1_RTX (TFmode); 2823117395Skan} 282490075Sobrien [(set_attr "predicable" "no")]) 282590075Sobrien 282690075Sobrien;; :::::::::::::::::::: 282790075Sobrien;; :: 282890075Sobrien;; :: 64 bit floating point arithmetic 282990075Sobrien;; :: 283090075Sobrien;; :::::::::::::::::::: 283190075Sobrien 283290075Sobrien(define_insn "adddf3" 283390075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 283490075Sobrien (plus:DF (match_operand:DF 1 "fr_register_operand" "%f") 283590075Sobrien (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))] 283690075Sobrien "" 283790075Sobrien "fadd.d %0 = %1, %F2" 283890075Sobrien [(set_attr "itanium_class" "fmac")]) 283990075Sobrien 284090075Sobrien(define_insn "*adddf3_trunc" 284190075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 284290075Sobrien (float_truncate:SF 284390075Sobrien (plus:DF (match_operand:DF 1 "fr_register_operand" "%f") 284490075Sobrien (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))] 284590075Sobrien "" 284690075Sobrien "fadd.s %0 = %1, %F2" 284790075Sobrien [(set_attr "itanium_class" "fmac")]) 284890075Sobrien 284990075Sobrien(define_insn "subdf3" 285090075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 285190075Sobrien (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG") 285290075Sobrien (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))] 285390075Sobrien "" 285490075Sobrien "fsub.d %0 = %F1, %F2" 285590075Sobrien [(set_attr "itanium_class" "fmac")]) 285690075Sobrien 285790075Sobrien(define_insn "*subdf3_trunc" 285890075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 285990075Sobrien (float_truncate:SF 286090075Sobrien (minus:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG") 286190075Sobrien (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))] 286290075Sobrien "" 286390075Sobrien "fsub.s %0 = %F1, %F2" 286490075Sobrien [(set_attr "itanium_class" "fmac")]) 286590075Sobrien 286690075Sobrien(define_insn "muldf3" 286790075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 286890075Sobrien (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 286990075Sobrien (match_operand:DF 2 "fr_register_operand" "f")))] 287090075Sobrien "" 287190075Sobrien "fmpy.d %0 = %1, %2" 287290075Sobrien [(set_attr "itanium_class" "fmac")]) 287390075Sobrien 287490075Sobrien(define_insn "*muldf3_trunc" 287590075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 287690075Sobrien (float_truncate:SF 287790075Sobrien (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 287890075Sobrien (match_operand:DF 2 "fr_register_operand" "f"))))] 287990075Sobrien "" 288090075Sobrien "fmpy.s %0 = %1, %2" 288190075Sobrien [(set_attr "itanium_class" "fmac")]) 288290075Sobrien 288390075Sobrien(define_insn "absdf2" 288490075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 288590075Sobrien (abs:DF (match_operand:DF 1 "fr_register_operand" "f")))] 288690075Sobrien "" 288790075Sobrien "fabs %0 = %1" 288890075Sobrien [(set_attr "itanium_class" "fmisc")]) 288990075Sobrien 289090075Sobrien(define_insn "negdf2" 289190075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 289290075Sobrien (neg:DF (match_operand:DF 1 "fr_register_operand" "f")))] 289390075Sobrien "" 289490075Sobrien "fneg %0 = %1" 289590075Sobrien [(set_attr "itanium_class" "fmisc")]) 289690075Sobrien 289790075Sobrien(define_insn "*nabsdf2" 289890075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 289990075Sobrien (neg:DF (abs:DF (match_operand:DF 1 "fr_register_operand" "f"))))] 290090075Sobrien "" 290190075Sobrien "fnegabs %0 = %1" 290290075Sobrien [(set_attr "itanium_class" "fmisc")]) 290390075Sobrien 290490075Sobrien(define_insn "mindf3" 290590075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 290690075Sobrien (smin:DF (match_operand:DF 1 "fr_register_operand" "f") 290790075Sobrien (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))] 290890075Sobrien "" 290990075Sobrien "fmin %0 = %1, %F2" 291090075Sobrien [(set_attr "itanium_class" "fmisc")]) 291190075Sobrien 291290075Sobrien(define_insn "maxdf3" 291390075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 291490075Sobrien (smax:DF (match_operand:DF 1 "fr_register_operand" "f") 291590075Sobrien (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))] 291690075Sobrien "" 291790075Sobrien "fmax %0 = %1, %F2" 291890075Sobrien [(set_attr "itanium_class" "fmisc")]) 291990075Sobrien 292090075Sobrien(define_insn "*madddf4" 292190075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 292290075Sobrien (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 292390075Sobrien (match_operand:DF 2 "fr_register_operand" "f")) 292490075Sobrien (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))] 292590075Sobrien "" 292690075Sobrien "fma.d %0 = %1, %2, %F3" 292790075Sobrien [(set_attr "itanium_class" "fmac")]) 292890075Sobrien 292990075Sobrien(define_insn "*madddf4_trunc" 293090075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 293190075Sobrien (float_truncate:SF 293290075Sobrien (plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 293390075Sobrien (match_operand:DF 2 "fr_register_operand" "f")) 293490075Sobrien (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))] 293590075Sobrien "" 293690075Sobrien "fma.s %0 = %1, %2, %F3" 293790075Sobrien [(set_attr "itanium_class" "fmac")]) 293890075Sobrien 293990075Sobrien(define_insn "*msubdf4" 294090075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 294190075Sobrien (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 294290075Sobrien (match_operand:DF 2 "fr_register_operand" "f")) 294390075Sobrien (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))] 294490075Sobrien "" 294590075Sobrien "fms.d %0 = %1, %2, %F3" 294690075Sobrien [(set_attr "itanium_class" "fmac")]) 294790075Sobrien 294890075Sobrien(define_insn "*msubdf4_trunc" 294990075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 295090075Sobrien (float_truncate:SF 295190075Sobrien (minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 295290075Sobrien (match_operand:DF 2 "fr_register_operand" "f")) 295390075Sobrien (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))] 295490075Sobrien "" 295590075Sobrien "fms.s %0 = %1, %2, %F3" 295690075Sobrien [(set_attr "itanium_class" "fmac")]) 295790075Sobrien 295890075Sobrien(define_insn "*nmuldf3" 295990075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 296090075Sobrien (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 296190075Sobrien (match_operand:DF 2 "fr_register_operand" "f"))))] 296290075Sobrien "" 296390075Sobrien "fnmpy.d %0 = %1, %2" 296490075Sobrien [(set_attr "itanium_class" "fmac")]) 296590075Sobrien 296690075Sobrien(define_insn "*nmuldf3_trunc" 296790075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 296890075Sobrien (float_truncate:SF 296990075Sobrien (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f") 297090075Sobrien (match_operand:DF 2 "fr_register_operand" "f")))))] 297190075Sobrien "" 297290075Sobrien "fnmpy.s %0 = %1, %2" 297390075Sobrien [(set_attr "itanium_class" "fmac")]) 297490075Sobrien 297590075Sobrien;; ??? Is it possible to canonicalize this as (minus (reg) (mult))? 297690075Sobrien 297790075Sobrien(define_insn "*nmadddf4" 297890075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 297990075Sobrien (plus:DF (neg:DF (mult:DF 298090075Sobrien (match_operand:DF 1 "fr_register_operand" "f") 298190075Sobrien (match_operand:DF 2 "fr_register_operand" "f"))) 298290075Sobrien (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")))] 298390075Sobrien "" 298490075Sobrien "fnma.d %0 = %1, %2, %F3" 298590075Sobrien [(set_attr "itanium_class" "fmac")]) 298690075Sobrien 298790075Sobrien(define_insn "*nmadddf4_alts" 298890075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 298990075Sobrien (plus:DF (neg:DF (mult:DF 299090075Sobrien (match_operand:DF 1 "fr_register_operand" "f") 299190075Sobrien (match_operand:DF 2 "fr_register_operand" "f"))) 299290075Sobrien (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))) 299390075Sobrien (use (match_operand:SI 4 "const_int_operand" ""))] 299490075Sobrien "" 299590075Sobrien "fnma.d.s%4 %0 = %1, %2, %F3" 299690075Sobrien [(set_attr "itanium_class" "fmac")]) 299790075Sobrien 299890075Sobrien(define_insn "*nmadddf4_trunc" 299990075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 300090075Sobrien (float_truncate:SF 300190075Sobrien (plus:DF (neg:DF (mult:DF 300290075Sobrien (match_operand:DF 1 "fr_register_operand" "f") 300390075Sobrien (match_operand:DF 2 "fr_register_operand" "f"))) 300490075Sobrien (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG"))))] 300590075Sobrien "" 300690075Sobrien "fnma.s %0 = %1, %2, %F3" 300790075Sobrien [(set_attr "itanium_class" "fmac")]) 300890075Sobrien 300990075Sobrien(define_expand "divdf3" 301090075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "") 301190075Sobrien (div:DF (match_operand:DF 1 "fr_register_operand" "") 301290075Sobrien (match_operand:DF 2 "fr_register_operand" "")))] 3013117395Skan "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV" 301490075Sobrien{ 301590075Sobrien rtx insn; 3016117395Skan if (TARGET_INLINE_FLOAT_DIV_LAT) 301790075Sobrien insn = gen_divdf3_internal_lat (operands[0], operands[1], operands[2]); 301890075Sobrien else 301990075Sobrien insn = gen_divdf3_internal_thr (operands[0], operands[1], operands[2]); 302090075Sobrien emit_insn (insn); 302190075Sobrien DONE; 3022117395Skan}) 302390075Sobrien 302490075Sobrien(define_insn_and_split "divdf3_internal_lat" 302590075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=&f") 302690075Sobrien (div:DF (match_operand:DF 1 "fr_register_operand" "f") 302790075Sobrien (match_operand:DF 2 "fr_register_operand" "f"))) 302890075Sobrien (clobber (match_scratch:TF 3 "=&f")) 302990075Sobrien (clobber (match_scratch:TF 4 "=&f")) 303090075Sobrien (clobber (match_scratch:TF 5 "=&f")) 303190075Sobrien (clobber (match_scratch:BI 6 "=c"))] 3032117395Skan "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_LAT" 303390075Sobrien "#" 303490075Sobrien "&& reload_completed" 303590075Sobrien [(parallel [(set (match_dup 7) (div:TF (const_int 1) (match_dup 9))) 3036117395Skan (set (match_dup 6) (unspec:BI [(match_dup 8) (match_dup 9)] 3037117395Skan UNSPEC_FR_RECIP_APPROX)) 303890075Sobrien (use (const_int 1))]) 303990075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 304090075Sobrien (parallel [(set (match_dup 3) (mult:TF (match_dup 8) (match_dup 7))) 304190075Sobrien (use (const_int 1))])) 304290075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 304390075Sobrien (parallel [(set (match_dup 4) 304490075Sobrien (plus:TF (neg:TF (mult:TF (match_dup 9) (match_dup 7))) 304590075Sobrien (match_dup 12))) 304690075Sobrien (use (const_int 1))])) 304790075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 304890075Sobrien (parallel [(set (match_dup 3) 304990075Sobrien (plus:TF (mult:TF (match_dup 4) (match_dup 3)) 305090075Sobrien (match_dup 3))) 305190075Sobrien (use (const_int 1))])) 305290075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 305390075Sobrien (parallel [(set (match_dup 5) (mult:TF (match_dup 4) (match_dup 4))) 305490075Sobrien (use (const_int 1))])) 305590075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 305690075Sobrien (parallel [(set (match_dup 7) 305790075Sobrien (plus:TF (mult:TF (match_dup 4) (match_dup 7)) 305890075Sobrien (match_dup 7))) 305990075Sobrien (use (const_int 1))])) 306090075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 306190075Sobrien (parallel [(set (match_dup 3) 306290075Sobrien (plus:TF (mult:TF (match_dup 5) (match_dup 3)) 306390075Sobrien (match_dup 3))) 306490075Sobrien (use (const_int 1))])) 306590075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 306690075Sobrien (parallel [(set (match_dup 4) (mult:TF (match_dup 5) (match_dup 5))) 306790075Sobrien (use (const_int 1))])) 306890075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 306990075Sobrien (parallel [(set (match_dup 7) 307090075Sobrien (plus:TF (mult:TF (match_dup 5) (match_dup 7)) 307190075Sobrien (match_dup 7))) 307290075Sobrien (use (const_int 1))])) 307390075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 307490075Sobrien (parallel [(set (match_dup 10) 307590075Sobrien (float_truncate:DF 307690075Sobrien (plus:TF (mult:TF (match_dup 4) (match_dup 3)) 307790075Sobrien (match_dup 3)))) 307890075Sobrien (use (const_int 1))])) 307990075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 308090075Sobrien (parallel [(set (match_dup 7) 308190075Sobrien (plus:TF (mult:TF (match_dup 4) (match_dup 7)) 308290075Sobrien (match_dup 7))) 308390075Sobrien (use (const_int 1))])) 308490075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 308590075Sobrien (parallel [(set (match_dup 11) 308690075Sobrien (float_truncate:DF 308790075Sobrien (plus:TF (neg:TF (mult:TF (match_dup 9) (match_dup 3))) 308890075Sobrien (match_dup 8)))) 308990075Sobrien (use (const_int 1))])) 309090075Sobrien (cond_exec (ne (match_dup 6) (const_int 0)) 309190075Sobrien (set (match_dup 0) 309290075Sobrien (float_truncate:DF (plus:TF (mult:TF (match_dup 5) (match_dup 7)) 309390075Sobrien (match_dup 3))))) 309490075Sobrien ] 3095117395Skan{ 3096117395Skan operands[7] = gen_rtx_REG (TFmode, REGNO (operands[0])); 3097117395Skan operands[8] = gen_rtx_REG (TFmode, REGNO (operands[1])); 3098117395Skan operands[9] = gen_rtx_REG (TFmode, REGNO (operands[2])); 3099117395Skan operands[10] = gen_rtx_REG (DFmode, REGNO (operands[3])); 3100117395Skan operands[11] = gen_rtx_REG (DFmode, REGNO (operands[5])); 3101117395Skan operands[12] = CONST1_RTX (TFmode); 3102117395Skan} 310390075Sobrien [(set_attr "predicable" "no")]) 310490075Sobrien 310590075Sobrien(define_insn_and_split "divdf3_internal_thr" 310690075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=&f") 310790075Sobrien (div:DF (match_operand:DF 1 "fr_register_operand" "f") 310890075Sobrien (match_operand:DF 2 "fr_register_operand" "f"))) 310990075Sobrien (clobber (match_scratch:TF 3 "=&f")) 311090075Sobrien (clobber (match_scratch:DF 4 "=f")) 311190075Sobrien (clobber (match_scratch:BI 5 "=c"))] 3112117395Skan "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_THR" 311390075Sobrien "#" 311490075Sobrien "&& reload_completed" 311590075Sobrien [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8))) 3116117395Skan (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)] 3117117395Skan UNSPEC_FR_RECIP_APPROX)) 311890075Sobrien (use (const_int 1))]) 311990075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 312090075Sobrien (parallel [(set (match_dup 3) 312190075Sobrien (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6))) 312290075Sobrien (match_dup 10))) 312390075Sobrien (use (const_int 1))])) 312490075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 312590075Sobrien (parallel [(set (match_dup 6) 312690075Sobrien (plus:TF (mult:TF (match_dup 3) (match_dup 6)) 312790075Sobrien (match_dup 6))) 312890075Sobrien (use (const_int 1))])) 312990075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 313090075Sobrien (parallel [(set (match_dup 3) 313190075Sobrien (mult:TF (match_dup 3) (match_dup 3))) 313290075Sobrien (use (const_int 1))])) 313390075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 313490075Sobrien (parallel [(set (match_dup 6) 313590075Sobrien (plus:TF (mult:TF (match_dup 3) (match_dup 6)) 313690075Sobrien (match_dup 6))) 313790075Sobrien (use (const_int 1))])) 313890075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 313990075Sobrien (parallel [(set (match_dup 3) 314090075Sobrien (mult:TF (match_dup 3) (match_dup 3))) 314190075Sobrien (use (const_int 1))])) 314290075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 314390075Sobrien (parallel [(set (match_dup 6) 314490075Sobrien (plus:TF (mult:TF (match_dup 3) (match_dup 6)) 314590075Sobrien (match_dup 6))) 314690075Sobrien (use (const_int 1))])) 314790075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 314890075Sobrien (parallel [(set (match_dup 9) 314990075Sobrien (float_truncate:DF 315090075Sobrien (mult:TF (match_dup 7) (match_dup 3)))) 315190075Sobrien (use (const_int 1))])) 315290075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 315390075Sobrien (parallel [(set (match_dup 4) 315490075Sobrien (plus:DF (neg:DF (mult:DF (match_dup 2) (match_dup 9))) 315590075Sobrien (match_dup 1))) 315690075Sobrien (use (const_int 1))])) 315790075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 315890075Sobrien (set (match_dup 0) 315990075Sobrien (plus:DF (mult:DF (match_dup 4) (match_dup 0)) 316090075Sobrien (match_dup 9)))) 316190075Sobrien ] 3162117395Skan{ 3163117395Skan operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0])); 3164117395Skan operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1])); 3165117395Skan operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2])); 3166117395Skan operands[9] = gen_rtx_REG (DFmode, REGNO (operands[3])); 3167117395Skan operands[10] = CONST1_RTX (TFmode); 3168117395Skan} 316990075Sobrien [(set_attr "predicable" "no")]) 317090075Sobrien 317190075Sobrien;; :::::::::::::::::::: 317290075Sobrien;; :: 317390075Sobrien;; :: 80 bit floating point arithmetic 317490075Sobrien;; :: 317590075Sobrien;; :::::::::::::::::::: 317690075Sobrien 317790075Sobrien(define_insn "addtf3" 317890075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "=f") 317990075Sobrien (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 318090075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))] 318190075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 318290075Sobrien "fadd %0 = %F1, %F2" 318390075Sobrien [(set_attr "itanium_class" "fmac")]) 318490075Sobrien 318590075Sobrien(define_insn "*addtf3_truncsf" 318690075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 318790075Sobrien (float_truncate:SF 318890075Sobrien (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 318990075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))] 319090075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 319190075Sobrien "fadd.s %0 = %F1, %F2" 319290075Sobrien [(set_attr "itanium_class" "fmac")]) 319390075Sobrien 319490075Sobrien(define_insn "*addtf3_truncdf" 319590075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 319690075Sobrien (float_truncate:DF 319790075Sobrien (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 319890075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))] 319990075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 320090075Sobrien "fadd.d %0 = %F1, %F2" 320190075Sobrien [(set_attr "itanium_class" "fmac")]) 320290075Sobrien 320390075Sobrien(define_insn "subtf3" 320490075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "=f") 320590075Sobrien (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 320690075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))] 320790075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 320890075Sobrien "fsub %0 = %F1, %F2" 320990075Sobrien [(set_attr "itanium_class" "fmac")]) 321090075Sobrien 321190075Sobrien(define_insn "*subtf3_truncsf" 321290075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 321390075Sobrien (float_truncate:SF 321490075Sobrien (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 321590075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))] 321690075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 321790075Sobrien "fsub.s %0 = %F1, %F2" 321890075Sobrien [(set_attr "itanium_class" "fmac")]) 321990075Sobrien 322090075Sobrien(define_insn "*subtf3_truncdf" 322190075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 322290075Sobrien (float_truncate:DF 322390075Sobrien (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 322490075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))] 322590075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 322690075Sobrien "fsub.d %0 = %F1, %F2" 322790075Sobrien [(set_attr "itanium_class" "fmac")]) 322890075Sobrien 322990075Sobrien(define_insn "multf3" 323090075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "=f") 323190075Sobrien (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 323290075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))] 323390075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 323490075Sobrien "fmpy %0 = %F1, %F2" 323590075Sobrien [(set_attr "itanium_class" "fmac")]) 323690075Sobrien 323790075Sobrien(define_insn "*multf3_truncsf" 323890075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 323990075Sobrien (float_truncate:SF 324090075Sobrien (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 324190075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))] 324290075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 324390075Sobrien "fmpy.s %0 = %F1, %F2" 324490075Sobrien [(set_attr "itanium_class" "fmac")]) 324590075Sobrien 324690075Sobrien(define_insn "*multf3_truncdf" 324790075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 324890075Sobrien (float_truncate:DF 324990075Sobrien (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 325090075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))] 325190075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 325290075Sobrien "fmpy.d %0 = %F1, %F2" 325390075Sobrien [(set_attr "itanium_class" "fmac")]) 325490075Sobrien 325590075Sobrien(define_insn "*multf3_alts" 325690075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "=f") 325790075Sobrien (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 325890075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))) 325990075Sobrien (use (match_operand:SI 3 "const_int_operand" ""))] 326090075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 326190075Sobrien "fmpy.s%3 %0 = %F1, %F2" 326290075Sobrien [(set_attr "itanium_class" "fmac")]) 326390075Sobrien 326490075Sobrien(define_insn "*multf3_truncsf_alts" 326590075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 326690075Sobrien (float_truncate:SF 326790075Sobrien (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 326890075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))) 326990075Sobrien (use (match_operand:SI 3 "const_int_operand" ""))] 327090075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 327190075Sobrien "fmpy.s.s%3 %0 = %F1, %F2" 327290075Sobrien [(set_attr "itanium_class" "fmac")]) 327390075Sobrien 327490075Sobrien(define_insn "*multf3_truncdf_alts" 327590075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 327690075Sobrien (float_truncate:DF 327790075Sobrien (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 327890075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))) 327990075Sobrien (use (match_operand:SI 3 "const_int_operand" ""))] 328090075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 328190075Sobrien "fmpy.d.s%3 %0 = %F1, %F2" 328290075Sobrien [(set_attr "itanium_class" "fmac")]) 328390075Sobrien 328490075Sobrien(define_insn "abstf2" 328590075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "=f") 328690075Sobrien (abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))] 328790075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 328890075Sobrien "fabs %0 = %F1" 328990075Sobrien [(set_attr "itanium_class" "fmisc")]) 329090075Sobrien 329190075Sobrien(define_insn "negtf2" 329290075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "=f") 329390075Sobrien (neg:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))] 329490075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 329590075Sobrien "fneg %0 = %F1" 329690075Sobrien [(set_attr "itanium_class" "fmisc")]) 329790075Sobrien 329890075Sobrien(define_insn "*nabstf2" 329990075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "=f") 330090075Sobrien (neg:TF (abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG"))))] 330190075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 330290075Sobrien "fnegabs %0 = %F1" 330390075Sobrien [(set_attr "itanium_class" "fmisc")]) 330490075Sobrien 330590075Sobrien(define_insn "mintf3" 330690075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "=f") 330790075Sobrien (smin:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 330890075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))] 330990075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 331090075Sobrien "fmin %0 = %F1, %F2" 331190075Sobrien [(set_attr "itanium_class" "fmisc")]) 331290075Sobrien 331390075Sobrien(define_insn "maxtf3" 331490075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "=f") 331590075Sobrien (smax:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 331690075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))] 331790075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 331890075Sobrien "fmax %0 = %F1, %F2" 331990075Sobrien [(set_attr "itanium_class" "fmisc")]) 332090075Sobrien 332190075Sobrien(define_insn "*maddtf4" 332290075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "=f") 332390075Sobrien (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 332490075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")) 332590075Sobrien (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))] 332690075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 332790075Sobrien "fma %0 = %F1, %F2, %F3" 332890075Sobrien [(set_attr "itanium_class" "fmac")]) 332990075Sobrien 333090075Sobrien(define_insn "*maddtf4_truncsf" 333190075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 333290075Sobrien (float_truncate:SF 333390075Sobrien (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 333490075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")) 333590075Sobrien (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))] 333690075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 333790075Sobrien "fma.s %0 = %F1, %F2, %F3" 333890075Sobrien [(set_attr "itanium_class" "fmac")]) 333990075Sobrien 334090075Sobrien(define_insn "*maddtf4_truncdf" 334190075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 334290075Sobrien (float_truncate:DF 334390075Sobrien (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 334490075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")) 334590075Sobrien (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))] 334690075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 334790075Sobrien "fma.d %0 = %F1, %F2, %F3" 334890075Sobrien [(set_attr "itanium_class" "fmac")]) 334990075Sobrien 335090075Sobrien(define_insn "*maddtf4_alts" 335190075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "=f") 335290075Sobrien (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 335390075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")) 335490075Sobrien (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))) 335590075Sobrien (use (match_operand:SI 4 "const_int_operand" ""))] 335690075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 335790075Sobrien "fma.s%4 %0 = %F1, %F2, %F3" 335890075Sobrien [(set_attr "itanium_class" "fmac")]) 335990075Sobrien 336090075Sobrien(define_insn "*maddtf4_alts_truncdf" 336190075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 336290075Sobrien (float_truncate:DF 336390075Sobrien (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 336490075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")) 336590075Sobrien (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))) 336690075Sobrien (use (match_operand:SI 4 "const_int_operand" ""))] 336790075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 336890075Sobrien "fma.d.s%4 %0 = %F1, %F2, %F3" 336990075Sobrien [(set_attr "itanium_class" "fmac")]) 337090075Sobrien 337190075Sobrien(define_insn "*msubtf4" 337290075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "=f") 337390075Sobrien (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 337490075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")) 337590075Sobrien (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))] 337690075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 337790075Sobrien "fms %0 = %F1, %F2, %F3" 337890075Sobrien [(set_attr "itanium_class" "fmac")]) 337990075Sobrien 338090075Sobrien(define_insn "*msubtf4_truncsf" 338190075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 338290075Sobrien (float_truncate:SF 338390075Sobrien (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 338490075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")) 338590075Sobrien (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))] 338690075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 338790075Sobrien "fms.s %0 = %F1, %F2, %F3" 338890075Sobrien [(set_attr "itanium_class" "fmac")]) 338990075Sobrien 339090075Sobrien(define_insn "*msubtf4_truncdf" 339190075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 339290075Sobrien (float_truncate:DF 339390075Sobrien (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 339490075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")) 339590075Sobrien (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))] 339690075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 339790075Sobrien "fms.d %0 = %F1, %F2, %F3" 339890075Sobrien [(set_attr "itanium_class" "fmac")]) 339990075Sobrien 340090075Sobrien(define_insn "*nmultf3" 340190075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "=f") 340290075Sobrien (neg:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 340390075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))] 340490075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 340590075Sobrien "fnmpy %0 = %F1, %F2" 340690075Sobrien [(set_attr "itanium_class" "fmac")]) 340790075Sobrien 340890075Sobrien(define_insn "*nmultf3_truncsf" 340990075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 341090075Sobrien (float_truncate:SF 341190075Sobrien (neg:TF (mult:TF 341290075Sobrien (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 341390075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))))] 341490075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 341590075Sobrien "fnmpy.s %0 = %F1, %F2" 341690075Sobrien [(set_attr "itanium_class" "fmac")]) 341790075Sobrien 341890075Sobrien(define_insn "*nmultf3_truncdf" 341990075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 342090075Sobrien (float_truncate:DF 342190075Sobrien (neg:TF (mult:TF 342290075Sobrien (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 342390075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))))] 342490075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 342590075Sobrien "fnmpy.d %0 = %F1, %F2" 342690075Sobrien [(set_attr "itanium_class" "fmac")]) 342790075Sobrien 342890075Sobrien;; ??? Is it possible to canonicalize this as (minus (reg) (mult))? 342990075Sobrien 343090075Sobrien(define_insn "*nmaddtf4" 343190075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "=f") 343290075Sobrien (plus:TF (neg:TF (mult:TF 343390075Sobrien (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 343490075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))) 343590075Sobrien (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))] 343690075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 343790075Sobrien "fnma %0 = %F1, %F2, %F3" 343890075Sobrien [(set_attr "itanium_class" "fmac")]) 343990075Sobrien 344090075Sobrien(define_insn "*nmaddtf4_truncsf" 344190075Sobrien [(set (match_operand:SF 0 "fr_register_operand" "=f") 344290075Sobrien (float_truncate:SF 344390075Sobrien (plus:TF (neg:TF (mult:TF 344490075Sobrien (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 344590075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))) 344690075Sobrien (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))] 344790075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 344890075Sobrien "fnma.s %0 = %F1, %F2, %F3" 344990075Sobrien [(set_attr "itanium_class" "fmac")]) 345090075Sobrien 345190075Sobrien(define_insn "*nmaddtf4_truncdf" 345290075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 345390075Sobrien (float_truncate:DF 345490075Sobrien (plus:TF (neg:TF (mult:TF 345590075Sobrien (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 345690075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))) 345790075Sobrien (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))] 345890075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 345990075Sobrien "fnma.d %0 = %F1, %F2, %F3" 346090075Sobrien [(set_attr "itanium_class" "fmac")]) 346190075Sobrien 346290075Sobrien(define_insn "*nmaddtf4_alts" 346390075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "=f") 346490075Sobrien (plus:TF (neg:TF (mult:TF 346590075Sobrien (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 346690075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))) 346790075Sobrien (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))) 346890075Sobrien (use (match_operand:SI 4 "const_int_operand" ""))] 346990075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 347090075Sobrien "fnma.s%4 %0 = %F1, %F2, %F3" 347190075Sobrien [(set_attr "itanium_class" "fmac")]) 347290075Sobrien 347390075Sobrien(define_insn "*nmaddtf4_truncdf_alts" 347490075Sobrien [(set (match_operand:DF 0 "fr_register_operand" "=f") 347590075Sobrien (float_truncate:DF 347690075Sobrien (plus:TF (neg:TF 347790075Sobrien (mult:TF 347890075Sobrien (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") 347990075Sobrien (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))) 348090075Sobrien (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))) 348190075Sobrien (use (match_operand:SI 4 "const_int_operand" ""))] 348290075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 348390075Sobrien "fnma.d.s%4 %0 = %F1, %F2, %F3" 348490075Sobrien [(set_attr "itanium_class" "fmac")]) 348590075Sobrien 348690075Sobrien(define_expand "divtf3" 348790075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "") 348890075Sobrien (div:TF (match_operand:TF 1 "fr_register_operand" "") 348990075Sobrien (match_operand:TF 2 "fr_register_operand" "")))] 3490117395Skan "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV" 349190075Sobrien{ 349290075Sobrien rtx insn; 3493117395Skan if (TARGET_INLINE_FLOAT_DIV_LAT) 349490075Sobrien insn = gen_divtf3_internal_lat (operands[0], operands[1], operands[2]); 349590075Sobrien else 349690075Sobrien insn = gen_divtf3_internal_thr (operands[0], operands[1], operands[2]); 349790075Sobrien emit_insn (insn); 349890075Sobrien DONE; 3499117395Skan}) 350090075Sobrien 350190075Sobrien(define_insn_and_split "divtf3_internal_lat" 350290075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "=&f") 350390075Sobrien (div:TF (match_operand:TF 1 "fr_register_operand" "f") 350490075Sobrien (match_operand:TF 2 "fr_register_operand" "f"))) 350590075Sobrien (clobber (match_scratch:TF 3 "=&f")) 350690075Sobrien (clobber (match_scratch:TF 4 "=&f")) 350790075Sobrien (clobber (match_scratch:TF 5 "=&f")) 350890075Sobrien (clobber (match_scratch:TF 6 "=&f")) 350990075Sobrien (clobber (match_scratch:BI 7 "=c"))] 3510117395Skan "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_LAT" 351190075Sobrien "#" 351290075Sobrien "&& reload_completed" 351390075Sobrien [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2))) 3514117395Skan (set (match_dup 7) (unspec:BI [(match_dup 1) (match_dup 2)] 3515117395Skan UNSPEC_FR_RECIP_APPROX)) 351690075Sobrien (use (const_int 1))]) 351790075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 351890075Sobrien (parallel [(set (match_dup 3) 351990075Sobrien (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0))) 352090075Sobrien (match_dup 8))) 352190075Sobrien (use (const_int 1))])) 352290075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 352390075Sobrien (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0))) 352490075Sobrien (use (const_int 1))])) 352590075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 352690075Sobrien (parallel [(set (match_dup 5) (mult:TF (match_dup 3) (match_dup 3))) 352790075Sobrien (use (const_int 1))])) 352890075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 352990075Sobrien (parallel [(set (match_dup 6) 353090075Sobrien (plus:TF (mult:TF (match_dup 3) (match_dup 3)) 353190075Sobrien (match_dup 3))) 353290075Sobrien (use (const_int 1))])) 353390075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 353490075Sobrien (parallel [(set (match_dup 3) 353590075Sobrien (plus:TF (mult:TF (match_dup 5) (match_dup 5)) 353690075Sobrien (match_dup 3))) 353790075Sobrien (use (const_int 1))])) 353890075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 353990075Sobrien (parallel [(set (match_dup 5) 354090075Sobrien (plus:TF (mult:TF (match_dup 6) (match_dup 0)) 354190075Sobrien (match_dup 0))) 354290075Sobrien (use (const_int 1))])) 354390075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 354490075Sobrien (parallel [(set (match_dup 0) 354590075Sobrien (plus:TF (mult:TF (match_dup 5) (match_dup 3)) 354690075Sobrien (match_dup 0))) 354790075Sobrien (use (const_int 1))])) 354890075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 354990075Sobrien (parallel [(set (match_dup 4) 355090075Sobrien (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 4))) 355190075Sobrien (match_dup 1))) 355290075Sobrien (use (const_int 1))])) 355390075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 355490075Sobrien (parallel [(set (match_dup 3) 355590075Sobrien (plus:TF (mult:TF (match_dup 3) (match_dup 0)) 355690075Sobrien (match_dup 4))) 355790075Sobrien (use (const_int 1))])) 355890075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 355990075Sobrien (parallel [(set (match_dup 5) 356090075Sobrien (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0))) 356190075Sobrien (match_dup 8))) 356290075Sobrien (use (const_int 1))])) 356390075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 356490075Sobrien (parallel [(set (match_dup 0) 356590075Sobrien (plus:TF (mult:TF (match_dup 4) (match_dup 0)) 356690075Sobrien (match_dup 0))) 356790075Sobrien (use (const_int 1))])) 356890075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 356990075Sobrien (parallel [(set (match_dup 4) 357090075Sobrien (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3))) 357190075Sobrien (match_dup 1))) 357290075Sobrien (use (const_int 1))])) 357390075Sobrien (cond_exec (ne (match_dup 7) (const_int 0)) 357490075Sobrien (set (match_dup 0) 357590075Sobrien (plus:TF (mult:TF (match_dup 4) (match_dup 0)) 357690075Sobrien (match_dup 3)))) 357790075Sobrien ] 357890075Sobrien "operands[8] = CONST1_RTX (TFmode);" 357990075Sobrien [(set_attr "predicable" "no")]) 358090075Sobrien 358190075Sobrien(define_insn_and_split "divtf3_internal_thr" 358290075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "=&f") 358390075Sobrien (div:TF (match_operand:TF 1 "fr_register_operand" "f") 358490075Sobrien (match_operand:TF 2 "fr_register_operand" "f"))) 358590075Sobrien (clobber (match_scratch:TF 3 "=&f")) 358690075Sobrien (clobber (match_scratch:TF 4 "=&f")) 358790075Sobrien (clobber (match_scratch:BI 5 "=c"))] 3588117395Skan "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_THR" 358990075Sobrien "#" 359090075Sobrien "&& reload_completed" 359190075Sobrien [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2))) 3592117395Skan (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)] 3593117395Skan UNSPEC_FR_RECIP_APPROX)) 359490075Sobrien (use (const_int 1))]) 359590075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 359690075Sobrien (parallel [(set (match_dup 3) 359790075Sobrien (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0))) 359890075Sobrien (match_dup 6))) 359990075Sobrien (use (const_int 1))])) 360090075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 360190075Sobrien (parallel [(set (match_dup 4) 360290075Sobrien (plus:TF (mult:TF (match_dup 3) (match_dup 0)) 360390075Sobrien (match_dup 0))) 360490075Sobrien (use (const_int 1))])) 360590075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 360690075Sobrien (parallel [(set (match_dup 3) (mult:TF (match_dup 3) (match_dup 3))) 360790075Sobrien (use (const_int 1))])) 360890075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 360990075Sobrien (parallel [(set (match_dup 3) 361090075Sobrien (plus:TF (mult:TF (match_dup 3) (match_dup 4)) 361190075Sobrien (match_dup 4))) 361290075Sobrien (use (const_int 1))])) 361390075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 361490075Sobrien (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0))) 361590075Sobrien (use (const_int 1))])) 361690075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 361790075Sobrien (parallel [(set (match_dup 0) 361890075Sobrien (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3))) 361990075Sobrien (match_dup 6))) 362090075Sobrien (use (const_int 1))])) 362190075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 362290075Sobrien (parallel [(set (match_dup 0) 362390075Sobrien (plus:TF (mult:TF (match_dup 0) (match_dup 3)) 362490075Sobrien (match_dup 3))) 362590075Sobrien (use (const_int 1))])) 362690075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 362790075Sobrien (parallel [(set (match_dup 3) 362890075Sobrien (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 4))) 362990075Sobrien (match_dup 1))) 363090075Sobrien (use (const_int 1))])) 363190075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 363290075Sobrien (parallel [(set (match_dup 3) 363390075Sobrien (plus:TF (mult:TF (match_dup 3) (match_dup 0)) 363490075Sobrien (match_dup 4))) 363590075Sobrien (use (const_int 1))])) 363690075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 363790075Sobrien (parallel [(set (match_dup 4) 363890075Sobrien (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0))) 363990075Sobrien (match_dup 6))) 364090075Sobrien (use (const_int 1))])) 364190075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 364290075Sobrien (parallel [(set (match_dup 0) 364390075Sobrien (plus:TF (mult:TF (match_dup 4) (match_dup 0)) 364490075Sobrien (match_dup 0))) 364590075Sobrien (use (const_int 1))])) 364690075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 364790075Sobrien (parallel [(set (match_dup 4) 364890075Sobrien (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3))) 364990075Sobrien (match_dup 1))) 365090075Sobrien (use (const_int 1))])) 365190075Sobrien (cond_exec (ne (match_dup 5) (const_int 0)) 365290075Sobrien (set (match_dup 0) 365390075Sobrien (plus:TF (mult:TF (match_dup 4) (match_dup 0)) 365490075Sobrien (match_dup 3)))) 365590075Sobrien ] 365690075Sobrien "operands[6] = CONST1_RTX (TFmode);" 365790075Sobrien [(set_attr "predicable" "no")]) 365890075Sobrien 365990075Sobrien;; ??? frcpa works like cmp.foo.unc. 366090075Sobrien 366190075Sobrien(define_insn "*recip_approx" 366290075Sobrien [(set (match_operand:TF 0 "fr_register_operand" "=f") 366390075Sobrien (div:TF (const_int 1) 366490075Sobrien (match_operand:TF 3 "fr_register_operand" "f"))) 366590075Sobrien (set (match_operand:BI 1 "register_operand" "=c") 366690075Sobrien (unspec:BI [(match_operand:TF 2 "fr_register_operand" "f") 3667117395Skan (match_dup 3)] UNSPEC_FR_RECIP_APPROX)) 366890075Sobrien (use (match_operand:SI 4 "const_int_operand" ""))] 366990075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 367090075Sobrien "frcpa.s%4 %0, %1 = %2, %3" 367190075Sobrien [(set_attr "itanium_class" "fmisc") 367290075Sobrien (set_attr "predicable" "no")]) 367390075Sobrien 367490075Sobrien;; :::::::::::::::::::: 367590075Sobrien;; :: 367690075Sobrien;; :: 32 bit Integer Shifts and Rotates 367790075Sobrien;; :: 367890075Sobrien;; :::::::::::::::::::: 367990075Sobrien 368090075Sobrien(define_expand "ashlsi3" 368190075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "") 368290075Sobrien (ashift:SI (match_operand:SI 1 "gr_register_operand" "") 368390075Sobrien (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))] 368490075Sobrien "" 368590075Sobrien{ 368690075Sobrien if (GET_CODE (operands[2]) != CONST_INT) 368790075Sobrien { 368890075Sobrien /* Why oh why didn't Intel arrange for SHIFT_COUNT_TRUNCATED? Now 368990075Sobrien we've got to get rid of stray bits outside the SImode register. */ 369090075Sobrien rtx subshift = gen_reg_rtx (DImode); 369190075Sobrien emit_insn (gen_zero_extendsidi2 (subshift, operands[2])); 369290075Sobrien operands[2] = subshift; 369390075Sobrien } 3694117395Skan}) 369590075Sobrien 369690075Sobrien(define_insn "*ashlsi3_internal" 369790075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r,r,r") 369890075Sobrien (ashift:SI (match_operand:SI 1 "gr_register_operand" "r,r,r") 369990075Sobrien (match_operand:DI 2 "gr_reg_or_5bit_operand" "R,n,r")))] 370090075Sobrien "" 370190075Sobrien "@ 370290075Sobrien shladd %0 = %1, %2, r0 370390075Sobrien dep.z %0 = %1, %2, %E2 370490075Sobrien shl %0 = %1, %2" 370590075Sobrien [(set_attr "itanium_class" "ialu,ishf,mmshf")]) 370690075Sobrien 370790075Sobrien(define_expand "ashrsi3" 370890075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "") 370990075Sobrien (ashiftrt:SI (match_operand:SI 1 "gr_register_operand" "") 371090075Sobrien (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))] 371190075Sobrien "" 371290075Sobrien{ 371390075Sobrien rtx subtarget = gen_reg_rtx (DImode); 371490075Sobrien if (GET_CODE (operands[2]) == CONST_INT) 371590075Sobrien emit_insn (gen_extv (subtarget, gen_lowpart (DImode, operands[1]), 371690075Sobrien GEN_INT (32 - INTVAL (operands[2])), operands[2])); 371790075Sobrien else 371890075Sobrien { 371990075Sobrien rtx subshift = gen_reg_rtx (DImode); 372090075Sobrien emit_insn (gen_extendsidi2 (subtarget, operands[1])); 372190075Sobrien emit_insn (gen_zero_extendsidi2 (subshift, operands[2])); 372290075Sobrien emit_insn (gen_ashrdi3 (subtarget, subtarget, subshift)); 372390075Sobrien } 372490075Sobrien emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget); 372590075Sobrien DONE; 3726117395Skan}) 372790075Sobrien 372890075Sobrien(define_expand "lshrsi3" 372990075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "") 373090075Sobrien (lshiftrt:SI (match_operand:SI 1 "gr_register_operand" "") 373190075Sobrien (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))] 373290075Sobrien "" 373390075Sobrien{ 373490075Sobrien rtx subtarget = gen_reg_rtx (DImode); 373590075Sobrien if (GET_CODE (operands[2]) == CONST_INT) 373690075Sobrien emit_insn (gen_extzv (subtarget, gen_lowpart (DImode, operands[1]), 373790075Sobrien GEN_INT (32 - INTVAL (operands[2])), operands[2])); 373890075Sobrien else 373990075Sobrien { 374090075Sobrien rtx subshift = gen_reg_rtx (DImode); 374190075Sobrien emit_insn (gen_zero_extendsidi2 (subtarget, operands[1])); 374290075Sobrien emit_insn (gen_zero_extendsidi2 (subshift, operands[2])); 374390075Sobrien emit_insn (gen_lshrdi3 (subtarget, subtarget, subshift)); 374490075Sobrien } 374590075Sobrien emit_move_insn (gen_lowpart (DImode, operands[0]), subtarget); 374690075Sobrien DONE; 3747117395Skan}) 374890075Sobrien 374990075Sobrien;; Use mix4.r/shr to implement rotrsi3. We only get 32 bits of valid result 375090075Sobrien;; here, instead of 64 like the patterns above. Keep the pattern together 375190075Sobrien;; until after combine; otherwise it won't get matched often. 375290075Sobrien 375390075Sobrien(define_expand "rotrsi3" 375490075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "") 375590075Sobrien (rotatert:SI (match_operand:SI 1 "gr_register_operand" "") 375690075Sobrien (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))] 375790075Sobrien "" 375890075Sobrien{ 375990075Sobrien if (GET_MODE (operands[2]) != VOIDmode) 376090075Sobrien { 376190075Sobrien rtx tmp = gen_reg_rtx (DImode); 376290075Sobrien emit_insn (gen_zero_extendsidi2 (tmp, operands[2])); 376390075Sobrien operands[2] = tmp; 376490075Sobrien } 3765117395Skan}) 376690075Sobrien 376790075Sobrien(define_insn_and_split "*rotrsi3_internal" 376890075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=&r") 376990075Sobrien (rotatert:SI (match_operand:SI 1 "gr_register_operand" "r") 377090075Sobrien (match_operand:DI 2 "gr_reg_or_5bit_operand" "rM")))] 377190075Sobrien "" 377290075Sobrien "#" 377390075Sobrien "reload_completed" 377490075Sobrien [(set (match_dup 3) 377590075Sobrien (ior:DI (zero_extend:DI (match_dup 1)) 377690075Sobrien (ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32)))) 377790075Sobrien (set (match_dup 3) 377890075Sobrien (lshiftrt:DI (match_dup 3) (match_dup 2)))] 377990075Sobrien "operands[3] = gen_rtx_REG (DImode, REGNO (operands[0]));") 378090075Sobrien 378190075Sobrien(define_expand "rotlsi3" 378290075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "") 378390075Sobrien (rotate:SI (match_operand:SI 1 "gr_register_operand" "") 378490075Sobrien (match_operand:SI 2 "gr_reg_or_5bit_operand" "")))] 378590075Sobrien "" 378690075Sobrien{ 378790075Sobrien if (! shift_32bit_count_operand (operands[2], SImode)) 378890075Sobrien { 378990075Sobrien rtx tmp = gen_reg_rtx (SImode); 379090075Sobrien emit_insn (gen_subsi3 (tmp, GEN_INT (32), operands[2])); 379190075Sobrien emit_insn (gen_rotrsi3 (operands[0], operands[1], tmp)); 379290075Sobrien DONE; 379390075Sobrien } 3794117395Skan}) 379590075Sobrien 379690075Sobrien(define_insn_and_split "*rotlsi3_internal" 379790075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 379890075Sobrien (rotate:SI (match_operand:SI 1 "gr_register_operand" "r") 379990075Sobrien (match_operand:SI 2 "shift_32bit_count_operand" "n")))] 380090075Sobrien "" 380190075Sobrien "#" 380290075Sobrien "reload_completed" 380390075Sobrien [(set (match_dup 3) 380490075Sobrien (ior:DI (zero_extend:DI (match_dup 1)) 380590075Sobrien (ashift:DI (zero_extend:DI (match_dup 1)) (const_int 32)))) 380690075Sobrien (set (match_dup 3) 380790075Sobrien (lshiftrt:DI (match_dup 3) (match_dup 2)))] 3808117395Skan{ 3809117395Skan operands[3] = gen_rtx_REG (DImode, REGNO (operands[0])); 3810117395Skan operands[2] = GEN_INT (32 - INTVAL (operands[2])); 3811117395Skan}) 381290075Sobrien 381390075Sobrien;; :::::::::::::::::::: 381490075Sobrien;; :: 381590075Sobrien;; :: 64 bit Integer Shifts and Rotates 381690075Sobrien;; :: 381790075Sobrien;; :::::::::::::::::::: 381890075Sobrien 381990075Sobrien(define_insn "ashldi3" 382090075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r,r,r") 382190075Sobrien (ashift:DI (match_operand:DI 1 "gr_register_operand" "r,r,r") 382290075Sobrien (match_operand:DI 2 "gr_reg_or_6bit_operand" "R,r,rM")))] 382390075Sobrien "" 382490075Sobrien "@ 382590075Sobrien shladd %0 = %1, %2, r0 382690075Sobrien shl %0 = %1, %2 382790075Sobrien shl %0 = %1, %2" 382890075Sobrien [(set_attr "itanium_class" "ialu,mmshf,mmshfi")]) 382990075Sobrien 383090075Sobrien;; ??? Maybe combine this with the multiply and add instruction? 383190075Sobrien 383290075Sobrien(define_insn "*shladd" 383390075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 383490075Sobrien (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r") 383590075Sobrien (match_operand:DI 2 "shladd_operand" "n")) 383690075Sobrien (match_operand:DI 3 "gr_register_operand" "r")))] 383790075Sobrien "" 383890075Sobrien "shladd %0 = %1, %S2, %3" 383990075Sobrien [(set_attr "itanium_class" "ialu")]) 384090075Sobrien 384190075Sobrien;; This can be created by register elimination if operand3 of shladd is an 384290075Sobrien;; eliminable register or has reg_equiv_constant set. 384390075Sobrien 384490075Sobrien;; We have to use nonmemory_operand for operand 4, to ensure that the 384590075Sobrien;; validate_changes call inside eliminate_regs will always succeed. If it 384690075Sobrien;; doesn't succeed, then this remain a shladd pattern, and will be reloaded 384790075Sobrien;; incorrectly. 384890075Sobrien 384990075Sobrien(define_insn_and_split "*shladd_elim" 385090075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=&r") 385190075Sobrien (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "gr_register_operand" "r") 385290075Sobrien (match_operand:DI 2 "shladd_operand" "n")) 385390075Sobrien (match_operand:DI 3 "nonmemory_operand" "r")) 385490075Sobrien (match_operand:DI 4 "nonmemory_operand" "rI")))] 385590075Sobrien "reload_in_progress" 385690075Sobrien "* abort ();" 385790075Sobrien "reload_completed" 385890075Sobrien [(set (match_dup 0) (plus:DI (mult:DI (match_dup 1) (match_dup 2)) 385990075Sobrien (match_dup 3))) 386090075Sobrien (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))] 386190075Sobrien "" 386290075Sobrien [(set_attr "itanium_class" "unknown")]) 386390075Sobrien 386490075Sobrien(define_insn "ashrdi3" 386590075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r,r") 386690075Sobrien (ashiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r") 386790075Sobrien (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))] 386890075Sobrien "" 386990075Sobrien "@ 387090075Sobrien shr %0 = %1, %2 387190075Sobrien shr %0 = %1, %2" 387290075Sobrien [(set_attr "itanium_class" "mmshf,mmshfi")]) 387390075Sobrien 387490075Sobrien(define_insn "lshrdi3" 387590075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r,r") 387690075Sobrien (lshiftrt:DI (match_operand:DI 1 "gr_register_operand" "r,r") 387790075Sobrien (match_operand:DI 2 "gr_reg_or_6bit_operand" "r,rM")))] 387890075Sobrien "" 387990075Sobrien "@ 388090075Sobrien shr.u %0 = %1, %2 388190075Sobrien shr.u %0 = %1, %2" 388290075Sobrien [(set_attr "itanium_class" "mmshf,mmshfi")]) 388390075Sobrien 388490075Sobrien;; Using a predicate that accepts only constants doesn't work, because optabs 388590075Sobrien;; will load the operand into a register and call the pattern if the predicate 388690075Sobrien;; did not accept it on the first try. So we use nonmemory_operand and then 388790075Sobrien;; verify that we have an appropriate constant in the expander. 388890075Sobrien 388990075Sobrien(define_expand "rotrdi3" 389090075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") 389190075Sobrien (rotatert:DI (match_operand:DI 1 "gr_register_operand" "") 389290075Sobrien (match_operand:DI 2 "nonmemory_operand" "")))] 389390075Sobrien "" 389490075Sobrien{ 389590075Sobrien if (! shift_count_operand (operands[2], DImode)) 389690075Sobrien FAIL; 3897117395Skan}) 389890075Sobrien 389990075Sobrien(define_insn "*rotrdi3_internal" 390090075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 390190075Sobrien (rotatert:DI (match_operand:DI 1 "gr_register_operand" "r") 390290075Sobrien (match_operand:DI 2 "shift_count_operand" "M")))] 390390075Sobrien "" 390490075Sobrien "shrp %0 = %1, %1, %2" 390590075Sobrien [(set_attr "itanium_class" "ishf")]) 390690075Sobrien 390790075Sobrien(define_expand "rotldi3" 390890075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") 390990075Sobrien (rotate:DI (match_operand:DI 1 "gr_register_operand" "") 391090075Sobrien (match_operand:DI 2 "nonmemory_operand" "")))] 391190075Sobrien "" 391290075Sobrien{ 391390075Sobrien if (! shift_count_operand (operands[2], DImode)) 391490075Sobrien FAIL; 3915117395Skan}) 391690075Sobrien 391790075Sobrien(define_insn "*rotldi3_internal" 391890075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 391990075Sobrien (rotate:DI (match_operand:DI 1 "gr_register_operand" "r") 392090075Sobrien (match_operand:DI 2 "shift_count_operand" "M")))] 392190075Sobrien "" 392290075Sobrien "shrp %0 = %1, %1, %e2" 392390075Sobrien [(set_attr "itanium_class" "ishf")]) 392490075Sobrien 392590075Sobrien;; :::::::::::::::::::: 392690075Sobrien;; :: 392790075Sobrien;; :: 32 bit Integer Logical operations 392890075Sobrien;; :: 392990075Sobrien;; :::::::::::::::::::: 393090075Sobrien 393190075Sobrien;; We don't seem to need any other 32-bit logical operations, because gcc 393290075Sobrien;; generates zero-extend;zero-extend;DImode-op, which combine optimizes to 393390075Sobrien;; DImode-op;zero-extend, and then we can optimize away the zero-extend. 393490075Sobrien;; This doesn't work for unary logical operations, because we don't call 393590075Sobrien;; apply_distributive_law for them. 393690075Sobrien 393790075Sobrien;; ??? Likewise, this doesn't work for andnot, which isn't handled by 393890075Sobrien;; apply_distributive_law. We get inefficient code for 393990075Sobrien;; int sub4 (int i, int j) { return i & ~j; } 394090075Sobrien;; We could convert (and (not (sign_extend A)) (sign_extend B)) to 394190075Sobrien;; (zero_extend (and (not A) B)) in combine. 394290075Sobrien;; Or maybe fix this by adding andsi3/iorsi3/xorsi3 patterns like the 394390075Sobrien;; one_cmplsi2 pattern. 394490075Sobrien 394590075Sobrien(define_insn "one_cmplsi2" 394690075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 394790075Sobrien (not:SI (match_operand:SI 1 "gr_register_operand" "r")))] 394890075Sobrien "" 394990075Sobrien "andcm %0 = -1, %1" 395090075Sobrien [(set_attr "itanium_class" "ilog")]) 395190075Sobrien 395290075Sobrien;; :::::::::::::::::::: 395390075Sobrien;; :: 395490075Sobrien;; :: 64 bit Integer Logical operations 395590075Sobrien;; :: 395690075Sobrien;; :::::::::::::::::::: 395790075Sobrien 395890075Sobrien(define_insn "anddi3" 395990075Sobrien [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f") 396090075Sobrien (and:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f") 396190075Sobrien (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))] 396290075Sobrien "" 396390075Sobrien "@ 396490075Sobrien and %0 = %2, %1 396590075Sobrien fand %0 = %2, %1" 396690075Sobrien [(set_attr "itanium_class" "ilog,fmisc")]) 396790075Sobrien 396890075Sobrien(define_insn "*andnot" 396990075Sobrien [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f") 397090075Sobrien (and:DI (not:DI (match_operand:DI 1 "grfr_register_operand" "r,*f")) 397190075Sobrien (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))] 397290075Sobrien "" 397390075Sobrien "@ 397490075Sobrien andcm %0 = %2, %1 397590075Sobrien fandcm %0 = %2, %1" 397690075Sobrien [(set_attr "itanium_class" "ilog,fmisc")]) 397790075Sobrien 397890075Sobrien(define_insn "iordi3" 397990075Sobrien [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f") 398090075Sobrien (ior:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f") 398190075Sobrien (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))] 398290075Sobrien "" 398390075Sobrien "@ 398490075Sobrien or %0 = %2, %1 398590075Sobrien for %0 = %2, %1" 398690075Sobrien [(set_attr "itanium_class" "ilog,fmisc")]) 398790075Sobrien 398890075Sobrien(define_insn "xordi3" 398990075Sobrien [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f") 399090075Sobrien (xor:DI (match_operand:DI 1 "grfr_register_operand" "%r,*f") 399190075Sobrien (match_operand:DI 2 "grfr_reg_or_8bit_operand" "rK,*f")))] 399290075Sobrien "" 399390075Sobrien "@ 399490075Sobrien xor %0 = %2, %1 399590075Sobrien fxor %0 = %2, %1" 399690075Sobrien [(set_attr "itanium_class" "ilog,fmisc")]) 399790075Sobrien 399890075Sobrien(define_insn "one_cmpldi2" 399990075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 400090075Sobrien (not:DI (match_operand:DI 1 "gr_register_operand" "r")))] 400190075Sobrien "" 400290075Sobrien "andcm %0 = -1, %1" 400390075Sobrien [(set_attr "itanium_class" "ilog")]) 400490075Sobrien 400590075Sobrien;; :::::::::::::::::::: 400690075Sobrien;; :: 400790075Sobrien;; :: Comparisons 400890075Sobrien;; :: 400990075Sobrien;; :::::::::::::::::::: 401090075Sobrien 401190075Sobrien(define_expand "cmpbi" 401290075Sobrien [(set (cc0) 401390075Sobrien (compare (match_operand:BI 0 "register_operand" "") 401490075Sobrien (match_operand:BI 1 "const_int_operand" "")))] 401590075Sobrien "" 401690075Sobrien{ 401790075Sobrien ia64_compare_op0 = operands[0]; 401890075Sobrien ia64_compare_op1 = operands[1]; 401990075Sobrien DONE; 4020117395Skan}) 402190075Sobrien 402290075Sobrien(define_expand "cmpsi" 402390075Sobrien [(set (cc0) 402490075Sobrien (compare (match_operand:SI 0 "gr_register_operand" "") 402590075Sobrien (match_operand:SI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))] 402690075Sobrien "" 402790075Sobrien{ 402890075Sobrien ia64_compare_op0 = operands[0]; 402990075Sobrien ia64_compare_op1 = operands[1]; 403090075Sobrien DONE; 4031117395Skan}) 403290075Sobrien 403390075Sobrien(define_expand "cmpdi" 403490075Sobrien [(set (cc0) 403590075Sobrien (compare (match_operand:DI 0 "gr_register_operand" "") 403690075Sobrien (match_operand:DI 1 "gr_reg_or_8bit_and_adjusted_operand" "")))] 403790075Sobrien "" 403890075Sobrien{ 403990075Sobrien ia64_compare_op0 = operands[0]; 404090075Sobrien ia64_compare_op1 = operands[1]; 404190075Sobrien DONE; 4042117395Skan}) 404390075Sobrien 404490075Sobrien(define_expand "cmpsf" 404590075Sobrien [(set (cc0) 404690075Sobrien (compare (match_operand:SF 0 "fr_reg_or_fp01_operand" "") 404790075Sobrien (match_operand:SF 1 "fr_reg_or_fp01_operand" "")))] 404890075Sobrien "" 404990075Sobrien{ 405090075Sobrien ia64_compare_op0 = operands[0]; 405190075Sobrien ia64_compare_op1 = operands[1]; 405290075Sobrien DONE; 4053117395Skan}) 405490075Sobrien 405590075Sobrien(define_expand "cmpdf" 405690075Sobrien [(set (cc0) 405790075Sobrien (compare (match_operand:DF 0 "fr_reg_or_fp01_operand" "") 405890075Sobrien (match_operand:DF 1 "fr_reg_or_fp01_operand" "")))] 405990075Sobrien "" 406090075Sobrien{ 406190075Sobrien ia64_compare_op0 = operands[0]; 406290075Sobrien ia64_compare_op1 = operands[1]; 406390075Sobrien DONE; 4064117395Skan}) 406590075Sobrien 406690075Sobrien(define_expand "cmptf" 406790075Sobrien [(set (cc0) 406890075Sobrien (compare (match_operand:TF 0 "tfreg_or_fp01_operand" "") 406990075Sobrien (match_operand:TF 1 "tfreg_or_fp01_operand" "")))] 407090075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 407190075Sobrien{ 407290075Sobrien ia64_compare_op0 = operands[0]; 407390075Sobrien ia64_compare_op1 = operands[1]; 407490075Sobrien DONE; 4075117395Skan}) 407690075Sobrien 407790075Sobrien(define_insn "*cmpsi_normal" 407890075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 407990075Sobrien (match_operator:BI 1 "normal_comparison_operator" 408090075Sobrien [(match_operand:SI 2 "gr_register_operand" "r") 408190075Sobrien (match_operand:SI 3 "gr_reg_or_8bit_operand" "rK")]))] 408290075Sobrien "" 408390075Sobrien "cmp4.%C1 %0, %I0 = %3, %2" 408490075Sobrien [(set_attr "itanium_class" "icmp")]) 408590075Sobrien 408690075Sobrien;; We use %r3 because it is possible for us to match a 0, and two of the 408790075Sobrien;; unsigned comparisons don't accept immediate operands of zero. 408890075Sobrien 408990075Sobrien(define_insn "*cmpsi_adjusted" 409090075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 409190075Sobrien (match_operator:BI 1 "adjusted_comparison_operator" 409290075Sobrien [(match_operand:SI 2 "gr_register_operand" "r") 409390075Sobrien (match_operand:SI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))] 409490075Sobrien "" 409590075Sobrien "cmp4.%C1 %0, %I0 = %r3, %2" 409690075Sobrien [(set_attr "itanium_class" "icmp")]) 409790075Sobrien 409890075Sobrien(define_insn "*cmpdi_normal" 409990075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 410090075Sobrien (match_operator:BI 1 "normal_comparison_operator" 410190075Sobrien [(match_operand:DI 2 "gr_reg_or_0_operand" "rO") 410290075Sobrien (match_operand:DI 3 "gr_reg_or_8bit_operand" "rK")]))] 410390075Sobrien "" 410490075Sobrien "cmp.%C1 %0, %I0 = %3, %r2" 410590075Sobrien [(set_attr "itanium_class" "icmp")]) 410690075Sobrien 410790075Sobrien;; We use %r3 because it is possible for us to match a 0, and two of the 410890075Sobrien;; unsigned comparisons don't accept immediate operands of zero. 410990075Sobrien 411090075Sobrien(define_insn "*cmpdi_adjusted" 411190075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 411290075Sobrien (match_operator:BI 1 "adjusted_comparison_operator" 411390075Sobrien [(match_operand:DI 2 "gr_register_operand" "r") 411490075Sobrien (match_operand:DI 3 "gr_reg_or_8bit_adjusted_operand" "rL")]))] 411590075Sobrien "" 411690075Sobrien "cmp.%C1 %0, %I0 = %r3, %2" 411790075Sobrien [(set_attr "itanium_class" "icmp")]) 411890075Sobrien 411990075Sobrien(define_insn "*cmpsf_internal" 412090075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 412190075Sobrien (match_operator:BI 1 "comparison_operator" 412290075Sobrien [(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG") 412390075Sobrien (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG")]))] 412490075Sobrien "" 412590075Sobrien "fcmp.%D1 %0, %I0 = %F2, %F3" 412690075Sobrien [(set_attr "itanium_class" "fcmp")]) 412790075Sobrien 412890075Sobrien(define_insn "*cmpdf_internal" 412990075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 413090075Sobrien (match_operator:BI 1 "comparison_operator" 413190075Sobrien [(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG") 413290075Sobrien (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")]))] 413390075Sobrien "" 413490075Sobrien "fcmp.%D1 %0, %I0 = %F2, %F3" 413590075Sobrien [(set_attr "itanium_class" "fcmp")]) 413690075Sobrien 413790075Sobrien(define_insn "*cmptf_internal" 413890075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 413990075Sobrien (match_operator:BI 1 "comparison_operator" 414090075Sobrien [(match_operand:TF 2 "tfreg_or_fp01_operand" "fG") 414190075Sobrien (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")]))] 414290075Sobrien "INTEL_EXTENDED_IEEE_FORMAT" 414390075Sobrien "fcmp.%D1 %0, %I0 = %F2, %F3" 414490075Sobrien [(set_attr "itanium_class" "fcmp")]) 414590075Sobrien 414690075Sobrien;; ??? Can this pattern be generated? 414790075Sobrien 414890075Sobrien(define_insn "*bit_zero" 414990075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 415090075Sobrien (eq:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r") 415190075Sobrien (const_int 1) 415290075Sobrien (match_operand:DI 2 "immediate_operand" "n")) 415390075Sobrien (const_int 0)))] 415490075Sobrien "" 415590075Sobrien "tbit.z %0, %I0 = %1, %2" 415690075Sobrien [(set_attr "itanium_class" "tbit")]) 415790075Sobrien 415890075Sobrien(define_insn "*bit_one" 415990075Sobrien [(set (match_operand:BI 0 "register_operand" "=c") 416090075Sobrien (ne:BI (zero_extract:DI (match_operand:DI 1 "gr_register_operand" "r") 416190075Sobrien (const_int 1) 416290075Sobrien (match_operand:DI 2 "immediate_operand" "n")) 416390075Sobrien (const_int 0)))] 416490075Sobrien "" 416590075Sobrien "tbit.nz %0, %I0 = %1, %2" 416690075Sobrien [(set_attr "itanium_class" "tbit")]) 416790075Sobrien 416890075Sobrien;; :::::::::::::::::::: 416990075Sobrien;; :: 417090075Sobrien;; :: Branches 417190075Sobrien;; :: 417290075Sobrien;; :::::::::::::::::::: 417390075Sobrien 417490075Sobrien(define_expand "beq" 417590075Sobrien [(set (pc) 417690075Sobrien (if_then_else (match_dup 1) 417790075Sobrien (label_ref (match_operand 0 "" "")) 417890075Sobrien (pc)))] 417990075Sobrien "" 418090075Sobrien "operands[1] = ia64_expand_compare (EQ, VOIDmode);") 418190075Sobrien 418290075Sobrien(define_expand "bne" 418390075Sobrien [(set (pc) 418490075Sobrien (if_then_else (match_dup 1) 418590075Sobrien (label_ref (match_operand 0 "" "")) 418690075Sobrien (pc)))] 418790075Sobrien "" 418890075Sobrien "operands[1] = ia64_expand_compare (NE, VOIDmode);") 418990075Sobrien 419090075Sobrien(define_expand "blt" 419190075Sobrien [(set (pc) 419290075Sobrien (if_then_else (match_dup 1) 419390075Sobrien (label_ref (match_operand 0 "" "")) 419490075Sobrien (pc)))] 419590075Sobrien "" 419690075Sobrien "operands[1] = ia64_expand_compare (LT, VOIDmode);") 419790075Sobrien 419890075Sobrien(define_expand "ble" 419990075Sobrien [(set (pc) 420090075Sobrien (if_then_else (match_dup 1) 420190075Sobrien (label_ref (match_operand 0 "" "")) 420290075Sobrien (pc)))] 420390075Sobrien "" 420490075Sobrien "operands[1] = ia64_expand_compare (LE, VOIDmode);") 420590075Sobrien 420690075Sobrien(define_expand "bgt" 420790075Sobrien [(set (pc) 420890075Sobrien (if_then_else (match_dup 1) 420990075Sobrien (label_ref (match_operand 0 "" "")) 421090075Sobrien (pc)))] 421190075Sobrien "" 421290075Sobrien "operands[1] = ia64_expand_compare (GT, VOIDmode);") 421390075Sobrien 421490075Sobrien(define_expand "bge" 421590075Sobrien [(set (pc) 421690075Sobrien (if_then_else (match_dup 1) 421790075Sobrien (label_ref (match_operand 0 "" "")) 421890075Sobrien (pc)))] 421990075Sobrien "" 422090075Sobrien "operands[1] = ia64_expand_compare (GE, VOIDmode);") 422190075Sobrien 422290075Sobrien(define_expand "bltu" 422390075Sobrien [(set (pc) 422490075Sobrien (if_then_else (match_dup 1) 422590075Sobrien (label_ref (match_operand 0 "" "")) 422690075Sobrien (pc)))] 422790075Sobrien "" 422890075Sobrien "operands[1] = ia64_expand_compare (LTU, VOIDmode);") 422990075Sobrien 423090075Sobrien(define_expand "bleu" 423190075Sobrien [(set (pc) 423290075Sobrien (if_then_else (match_dup 1) 423390075Sobrien (label_ref (match_operand 0 "" "")) 423490075Sobrien (pc)))] 423590075Sobrien "" 423690075Sobrien "operands[1] = ia64_expand_compare (LEU, VOIDmode);") 423790075Sobrien 423890075Sobrien(define_expand "bgtu" 423990075Sobrien [(set (pc) 424090075Sobrien (if_then_else (match_dup 1) 424190075Sobrien (label_ref (match_operand 0 "" "")) 424290075Sobrien (pc)))] 424390075Sobrien "" 424490075Sobrien "operands[1] = ia64_expand_compare (GTU, VOIDmode);") 424590075Sobrien 424690075Sobrien(define_expand "bgeu" 424790075Sobrien [(set (pc) 424890075Sobrien (if_then_else (match_dup 1) 424990075Sobrien (label_ref (match_operand 0 "" "")) 425090075Sobrien (pc)))] 425190075Sobrien "" 425290075Sobrien "operands[1] = ia64_expand_compare (GEU, VOIDmode);") 425390075Sobrien 425490075Sobrien(define_expand "bunordered" 425590075Sobrien [(set (pc) 425690075Sobrien (if_then_else (match_dup 1) 425790075Sobrien (label_ref (match_operand 0 "" "")) 425890075Sobrien (pc)))] 425990075Sobrien "" 426090075Sobrien "operands[1] = ia64_expand_compare (UNORDERED, VOIDmode);") 426190075Sobrien 426290075Sobrien(define_expand "bordered" 426390075Sobrien [(set (pc) 426490075Sobrien (if_then_else (match_dup 1) 426590075Sobrien (label_ref (match_operand 0 "" "")) 426690075Sobrien (pc)))] 426790075Sobrien "" 426890075Sobrien "operands[1] = ia64_expand_compare (ORDERED, VOIDmode);") 426990075Sobrien 427090075Sobrien(define_insn "*br_true" 427190075Sobrien [(set (pc) 427290075Sobrien (if_then_else (match_operator 0 "predicate_operator" 427390075Sobrien [(match_operand:BI 1 "register_operand" "c") 427490075Sobrien (const_int 0)]) 427590075Sobrien (label_ref (match_operand 2 "" "")) 427690075Sobrien (pc)))] 427790075Sobrien "" 427890075Sobrien "(%J0) br.cond%+ %l2" 427990075Sobrien [(set_attr "itanium_class" "br") 428090075Sobrien (set_attr "predicable" "no")]) 428190075Sobrien 428290075Sobrien(define_insn "*br_false" 428390075Sobrien [(set (pc) 428490075Sobrien (if_then_else (match_operator 0 "predicate_operator" 428590075Sobrien [(match_operand:BI 1 "register_operand" "c") 428690075Sobrien (const_int 0)]) 428790075Sobrien (pc) 428890075Sobrien (label_ref (match_operand 2 "" ""))))] 428990075Sobrien "" 429090075Sobrien "(%j0) br.cond%+ %l2" 429190075Sobrien [(set_attr "itanium_class" "br") 429290075Sobrien (set_attr "predicable" "no")]) 429390075Sobrien 429490075Sobrien;; :::::::::::::::::::: 429590075Sobrien;; :: 429690075Sobrien;; :: Counted loop operations 429790075Sobrien;; :: 429890075Sobrien;; :::::::::::::::::::: 429990075Sobrien 430090075Sobrien(define_expand "doloop_end" 430190075Sobrien [(use (match_operand 0 "" "")) ; loop pseudo 430290075Sobrien (use (match_operand 1 "" "")) ; iterations; zero if unknown 430390075Sobrien (use (match_operand 2 "" "")) ; max iterations 430490075Sobrien (use (match_operand 3 "" "")) ; loop level 430590075Sobrien (use (match_operand 4 "" ""))] ; label 430690075Sobrien "" 430790075Sobrien{ 430890075Sobrien /* Only use cloop on innermost loops. */ 430990075Sobrien if (INTVAL (operands[3]) > 1) 431090075Sobrien FAIL; 431190075Sobrien emit_jump_insn (gen_doloop_end_internal (gen_rtx_REG (DImode, AR_LC_REGNUM), 431290075Sobrien operands[4])); 431390075Sobrien DONE; 4314117395Skan}) 431590075Sobrien 431690075Sobrien(define_insn "doloop_end_internal" 431790075Sobrien [(set (pc) (if_then_else (ne (match_operand:DI 0 "ar_lc_reg_operand" "") 431890075Sobrien (const_int 0)) 431990075Sobrien (label_ref (match_operand 1 "" "")) 432090075Sobrien (pc))) 432190075Sobrien (set (match_dup 0) (if_then_else:DI (ne (match_dup 0) (const_int 0)) 4322117395Skan (plus:DI (match_dup 0) (const_int -1)) 4323117395Skan (match_dup 0)))] 432490075Sobrien "" 432590075Sobrien "br.cloop.sptk.few %l1" 432690075Sobrien [(set_attr "itanium_class" "br") 432790075Sobrien (set_attr "predicable" "no")]) 432890075Sobrien 432990075Sobrien;; :::::::::::::::::::: 433090075Sobrien;; :: 433190075Sobrien;; :: Set flag operations 433290075Sobrien;; :: 433390075Sobrien;; :::::::::::::::::::: 433490075Sobrien 433590075Sobrien(define_expand "seq" 433690075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 433790075Sobrien "" 433890075Sobrien "operands[1] = ia64_expand_compare (EQ, DImode);") 433990075Sobrien 434090075Sobrien(define_expand "sne" 434190075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 434290075Sobrien "" 434390075Sobrien "operands[1] = ia64_expand_compare (NE, DImode);") 434490075Sobrien 434590075Sobrien(define_expand "slt" 434690075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 434790075Sobrien "" 434890075Sobrien "operands[1] = ia64_expand_compare (LT, DImode);") 434990075Sobrien 435090075Sobrien(define_expand "sle" 435190075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 435290075Sobrien "" 435390075Sobrien "operands[1] = ia64_expand_compare (LE, DImode);") 435490075Sobrien 435590075Sobrien(define_expand "sgt" 435690075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 435790075Sobrien "" 435890075Sobrien "operands[1] = ia64_expand_compare (GT, DImode);") 435990075Sobrien 436090075Sobrien(define_expand "sge" 436190075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 436290075Sobrien "" 436390075Sobrien "operands[1] = ia64_expand_compare (GE, DImode);") 436490075Sobrien 436590075Sobrien(define_expand "sltu" 436690075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 436790075Sobrien "" 436890075Sobrien "operands[1] = ia64_expand_compare (LTU, DImode);") 436990075Sobrien 437090075Sobrien(define_expand "sleu" 437190075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 437290075Sobrien "" 437390075Sobrien "operands[1] = ia64_expand_compare (LEU, DImode);") 437490075Sobrien 437590075Sobrien(define_expand "sgtu" 437690075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 437790075Sobrien "" 437890075Sobrien "operands[1] = ia64_expand_compare (GTU, DImode);") 437990075Sobrien 438090075Sobrien(define_expand "sgeu" 438190075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 438290075Sobrien "" 438390075Sobrien "operands[1] = ia64_expand_compare (GEU, DImode);") 438490075Sobrien 438590075Sobrien(define_expand "sunordered" 438690075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 438790075Sobrien "" 438890075Sobrien "operands[1] = ia64_expand_compare (UNORDERED, DImode);") 438990075Sobrien 439090075Sobrien(define_expand "sordered" 439190075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "") (match_dup 1))] 439290075Sobrien "" 439390075Sobrien "operands[1] = ia64_expand_compare (ORDERED, DImode);") 439490075Sobrien 439590075Sobrien;; Don't allow memory as destination here, because cmov/cmov/st is more 439690075Sobrien;; efficient than mov/mov/cst/cst. 439790075Sobrien 439890075Sobrien(define_insn_and_split "*sne_internal" 439990075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 440090075Sobrien (ne:DI (match_operand:BI 1 "register_operand" "c") 440190075Sobrien (const_int 0)))] 440290075Sobrien "" 440390075Sobrien "#" 440490075Sobrien "reload_completed" 440590075Sobrien [(cond_exec (ne (match_dup 1) (const_int 0)) 440690075Sobrien (set (match_dup 0) (const_int 1))) 440790075Sobrien (cond_exec (eq (match_dup 1) (const_int 0)) 440890075Sobrien (set (match_dup 0) (const_int 0)))] 440990075Sobrien "" 441090075Sobrien [(set_attr "itanium_class" "unknown")]) 441190075Sobrien 441290075Sobrien(define_insn_and_split "*seq_internal" 441390075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 441490075Sobrien (eq:DI (match_operand:BI 1 "register_operand" "c") 441590075Sobrien (const_int 0)))] 441690075Sobrien "" 441790075Sobrien "#" 441890075Sobrien "reload_completed" 441990075Sobrien [(cond_exec (ne (match_dup 1) (const_int 0)) 442090075Sobrien (set (match_dup 0) (const_int 0))) 442190075Sobrien (cond_exec (eq (match_dup 1) (const_int 0)) 442290075Sobrien (set (match_dup 0) (const_int 1)))] 442390075Sobrien "" 442490075Sobrien [(set_attr "itanium_class" "unknown")]) 442590075Sobrien 442690075Sobrien;; :::::::::::::::::::: 442790075Sobrien;; :: 442890075Sobrien;; :: Conditional move instructions. 442990075Sobrien;; :: 443090075Sobrien;; :::::::::::::::::::: 443190075Sobrien 443290075Sobrien;; ??? Add movXXcc patterns? 443390075Sobrien 443490075Sobrien;; 443590075Sobrien;; DImode if_then_else patterns. 443690075Sobrien;; 443790075Sobrien 443890075Sobrien(define_insn "*cmovdi_internal" 443990075Sobrien [(set (match_operand:DI 0 "destination_operand" 444090075Sobrien "= r, r, r, r, r, r, r, r, r, r, m, Q, *f,*b,*d*e") 444190075Sobrien (if_then_else:DI 444290075Sobrien (match_operator 4 "predicate_operator" 444390075Sobrien [(match_operand:BI 1 "register_operand" 444490075Sobrien "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c") 444590075Sobrien (const_int 0)]) 444690075Sobrien (match_operand:DI 2 "move_operand" 4447117395Skan "rnm, *f, *b,*d*e,rnm,rnm, rnm,*f,*b,*d*e,rO,*f,rOQ,rO, rK") 444890075Sobrien (match_operand:DI 3 "move_operand" 4449117395Skan "rnm,rnm,rnm, rnm, *f, *b,*d*e,*f,*b,*d*e,rO,*f,rOQ,rO, rK")))] 445090075Sobrien "ia64_move_ok (operands[0], operands[2]) 445190075Sobrien && ia64_move_ok (operands[0], operands[3])" 4452117395Skan { abort (); } 445390075Sobrien [(set_attr "predicable" "no")]) 445490075Sobrien 445590075Sobrien(define_split 445690075Sobrien [(set (match_operand 0 "destination_operand" "") 445790075Sobrien (if_then_else 445890075Sobrien (match_operator 4 "predicate_operator" 445990075Sobrien [(match_operand:BI 1 "register_operand" "") 446090075Sobrien (const_int 0)]) 446190075Sobrien (match_operand 2 "move_operand" "") 446290075Sobrien (match_operand 3 "move_operand" "")))] 446390075Sobrien "reload_completed" 446490075Sobrien [(const_int 0)] 446590075Sobrien{ 446690075Sobrien rtx tmp; 4467117395Skan int emitted_something; 4468117395Skan 4469117395Skan emitted_something = 0; 447090075Sobrien if (! rtx_equal_p (operands[0], operands[2])) 447190075Sobrien { 447290075Sobrien tmp = gen_rtx_SET (VOIDmode, operands[0], operands[2]); 447390075Sobrien tmp = gen_rtx_COND_EXEC (VOIDmode, operands[4], tmp); 447490075Sobrien emit_insn (tmp); 4475117395Skan emitted_something = 1; 447690075Sobrien } 447790075Sobrien if (! rtx_equal_p (operands[0], operands[3])) 447890075Sobrien { 447990075Sobrien tmp = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE, 448090075Sobrien VOIDmode, operands[1], const0_rtx); 448190075Sobrien tmp = gen_rtx_COND_EXEC (VOIDmode, tmp, 448290075Sobrien gen_rtx_SET (VOIDmode, operands[0], 448390075Sobrien operands[3])); 448490075Sobrien emit_insn (tmp); 4485117395Skan emitted_something = 1; 448690075Sobrien } 4487117395Skan if (! emitted_something) 4488117395Skan emit_note (NULL, NOTE_INSN_DELETED); 448990075Sobrien DONE; 4490117395Skan}) 449190075Sobrien 449290075Sobrien;; Absolute value pattern. 449390075Sobrien 449490075Sobrien(define_insn "*absdi2_internal" 449590075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r,r") 449690075Sobrien (if_then_else:DI 449790075Sobrien (match_operator 4 "predicate_operator" 449890075Sobrien [(match_operand:BI 1 "register_operand" "c,c") 449990075Sobrien (const_int 0)]) 450090075Sobrien (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" "rI,rI")) 450190075Sobrien (match_operand:DI 3 "gr_reg_or_22bit_operand" "0,rI")))] 450290075Sobrien "" 450390075Sobrien "#" 450490075Sobrien [(set_attr "itanium_class" "ialu,unknown") 450590075Sobrien (set_attr "predicable" "no")]) 450690075Sobrien 450790075Sobrien(define_split 450890075Sobrien [(set (match_operand:DI 0 "register_operand" "") 450990075Sobrien (if_then_else:DI 451090075Sobrien (match_operator 4 "predicate_operator" 451190075Sobrien [(match_operand:BI 1 "register_operand" "c,c") 451290075Sobrien (const_int 0)]) 451390075Sobrien (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" "")) 451490075Sobrien (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))] 451590075Sobrien "reload_completed && rtx_equal_p (operands[0], operands[3])" 451690075Sobrien [(cond_exec 451790075Sobrien (match_dup 4) 451890075Sobrien (set (match_dup 0) 451990075Sobrien (neg:DI (match_dup 2))))] 452090075Sobrien "") 452190075Sobrien 452290075Sobrien(define_split 452390075Sobrien [(set (match_operand:DI 0 "register_operand" "") 452490075Sobrien (if_then_else:DI 452590075Sobrien (match_operator 4 "predicate_operator" 452690075Sobrien [(match_operand:BI 1 "register_operand" "c,c") 452790075Sobrien (const_int 0)]) 452890075Sobrien (neg:DI (match_operand:DI 2 "gr_reg_or_22bit_operand" "")) 452990075Sobrien (match_operand:DI 3 "gr_reg_or_22bit_operand" "")))] 453090075Sobrien "reload_completed" 453190075Sobrien [(cond_exec 453290075Sobrien (match_dup 4) 453390075Sobrien (set (match_dup 0) (neg:DI (match_dup 2)))) 453490075Sobrien (cond_exec 453590075Sobrien (match_dup 5) 453690075Sobrien (set (match_dup 0) (match_dup 3)))] 453790075Sobrien{ 453890075Sobrien operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE, 453990075Sobrien VOIDmode, operands[1], const0_rtx); 4540117395Skan}) 454190075Sobrien 454290075Sobrien;; 454390075Sobrien;; SImode if_then_else patterns. 454490075Sobrien;; 454590075Sobrien 454690075Sobrien(define_insn "*cmovsi_internal" 454790075Sobrien [(set (match_operand:SI 0 "destination_operand" "=r,m,*f,r,m,*f,r,m,*f") 454890075Sobrien (if_then_else:SI 454990075Sobrien (match_operator 4 "predicate_operator" 455090075Sobrien [(match_operand:BI 1 "register_operand" "c,c,c,c,c,c,c,c,c") 455190075Sobrien (const_int 0)]) 455290075Sobrien (match_operand:SI 2 "move_operand" 4553117395Skan "0,0,0,rnm*f,rO,rO,rnm*f,rO,rO") 455490075Sobrien (match_operand:SI 3 "move_operand" 4555117395Skan "rnm*f,rO,rO,0,0,0,rnm*f,rO,rO")))] 455690075Sobrien "ia64_move_ok (operands[0], operands[2]) 455790075Sobrien && ia64_move_ok (operands[0], operands[3])" 4558117395Skan { abort (); } 455990075Sobrien [(set_attr "predicable" "no")]) 456090075Sobrien 456190075Sobrien(define_insn "*abssi2_internal" 456290075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r,r") 456390075Sobrien (if_then_else:SI 456490075Sobrien (match_operator 4 "predicate_operator" 456590075Sobrien [(match_operand:BI 1 "register_operand" "c,c") 456690075Sobrien (const_int 0)]) 456790075Sobrien (neg:SI (match_operand:SI 3 "gr_reg_or_22bit_operand" "rI,rI")) 456890075Sobrien (match_operand:SI 2 "gr_reg_or_22bit_operand" "0,rI")))] 456990075Sobrien "" 457090075Sobrien "#" 457190075Sobrien [(set_attr "itanium_class" "ialu,unknown") 457290075Sobrien (set_attr "predicable" "no")]) 457390075Sobrien 457490075Sobrien(define_split 457590075Sobrien [(set (match_operand:SI 0 "register_operand" "") 457690075Sobrien (if_then_else:SI 457790075Sobrien (match_operator 4 "predicate_operator" 457890075Sobrien [(match_operand:BI 1 "register_operand" "c,c") 457990075Sobrien (const_int 0)]) 458090075Sobrien (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" "")) 458190075Sobrien (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))] 458290075Sobrien "reload_completed && rtx_equal_p (operands[0], operands[3])" 458390075Sobrien [(cond_exec 458490075Sobrien (match_dup 4) 458590075Sobrien (set (match_dup 0) 458690075Sobrien (neg:SI (match_dup 2))))] 458790075Sobrien "") 458890075Sobrien 458990075Sobrien(define_split 459090075Sobrien [(set (match_operand:SI 0 "register_operand" "") 459190075Sobrien (if_then_else:SI 459290075Sobrien (match_operator 4 "predicate_operator" 459390075Sobrien [(match_operand:BI 1 "register_operand" "c,c") 459490075Sobrien (const_int 0)]) 459590075Sobrien (neg:SI (match_operand:SI 2 "gr_reg_or_22bit_operand" "")) 459690075Sobrien (match_operand:SI 3 "gr_reg_or_22bit_operand" "")))] 459790075Sobrien "reload_completed" 459890075Sobrien [(cond_exec 459990075Sobrien (match_dup 4) 460090075Sobrien (set (match_dup 0) (neg:SI (match_dup 2)))) 460190075Sobrien (cond_exec 460290075Sobrien (match_dup 5) 460390075Sobrien (set (match_dup 0) (match_dup 3)))] 460490075Sobrien{ 460590075Sobrien operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE, 460690075Sobrien VOIDmode, operands[1], const0_rtx); 4607117395Skan}) 460890075Sobrien 460990075Sobrien(define_insn_and_split "*cond_opsi2_internal" 461090075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 461190075Sobrien (match_operator:SI 5 "condop_operator" 461290075Sobrien [(if_then_else:SI 461390075Sobrien (match_operator 6 "predicate_operator" 461490075Sobrien [(match_operand:BI 1 "register_operand" "c") 461590075Sobrien (const_int 0)]) 461690075Sobrien (match_operand:SI 2 "gr_register_operand" "r") 461790075Sobrien (match_operand:SI 3 "gr_register_operand" "r")) 461890075Sobrien (match_operand:SI 4 "gr_register_operand" "r")]))] 461990075Sobrien "" 462090075Sobrien "#" 462190075Sobrien "reload_completed" 462290075Sobrien [(cond_exec 462390075Sobrien (match_dup 6) 462490075Sobrien (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 2) (match_dup 4)]))) 462590075Sobrien (cond_exec 462690075Sobrien (match_dup 7) 462790075Sobrien (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 3) (match_dup 4)])))] 462890075Sobrien{ 462990075Sobrien operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE, 463090075Sobrien VOIDmode, operands[1], const0_rtx); 4631117395Skan} 463290075Sobrien [(set_attr "itanium_class" "ialu") 463390075Sobrien (set_attr "predicable" "no")]) 463490075Sobrien 463590075Sobrien 463690075Sobrien(define_insn_and_split "*cond_opsi2_internal_b" 463790075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 463890075Sobrien (match_operator:SI 5 "condop_operator" 463990075Sobrien [(match_operand:SI 4 "gr_register_operand" "r") 464090075Sobrien (if_then_else:SI 464190075Sobrien (match_operator 6 "predicate_operator" 464290075Sobrien [(match_operand:BI 1 "register_operand" "c") 464390075Sobrien (const_int 0)]) 464490075Sobrien (match_operand:SI 2 "gr_register_operand" "r") 464590075Sobrien (match_operand:SI 3 "gr_register_operand" "r"))]))] 464690075Sobrien "" 464790075Sobrien "#" 464890075Sobrien "reload_completed" 464990075Sobrien [(cond_exec 465090075Sobrien (match_dup 6) 465190075Sobrien (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 2)]))) 465290075Sobrien (cond_exec 465390075Sobrien (match_dup 7) 465490075Sobrien (set (match_dup 0) (match_op_dup:SI 5 [(match_dup 4) (match_dup 3)])))] 465590075Sobrien{ 465690075Sobrien operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[6]) == NE ? EQ : NE, 465790075Sobrien VOIDmode, operands[1], const0_rtx); 4658117395Skan} 465990075Sobrien [(set_attr "itanium_class" "ialu") 466090075Sobrien (set_attr "predicable" "no")]) 466190075Sobrien 466290075Sobrien 466390075Sobrien;; :::::::::::::::::::: 466490075Sobrien;; :: 466590075Sobrien;; :: Call and branch instructions 466690075Sobrien;; :: 466790075Sobrien;; :::::::::::::::::::: 466890075Sobrien 466990075Sobrien;; Subroutine call instruction returning no value. Operand 0 is the function 467090075Sobrien;; to call; operand 1 is the number of bytes of arguments pushed (in mode 467190075Sobrien;; `SImode', except it is normally a `const_int'); operand 2 is the number of 467290075Sobrien;; registers used as operands. 467390075Sobrien 467490075Sobrien;; On most machines, operand 2 is not actually stored into the RTL pattern. It 467590075Sobrien;; is supplied for the sake of some RISC machines which need to put this 467690075Sobrien;; information into the assembler code; they can put it in the RTL instead of 467790075Sobrien;; operand 1. 467890075Sobrien 467990075Sobrien(define_expand "call" 468090075Sobrien [(use (match_operand:DI 0 "" "")) 468190075Sobrien (use (match_operand 1 "" "")) 468290075Sobrien (use (match_operand 2 "" "")) 468390075Sobrien (use (match_operand 3 "" ""))] 468490075Sobrien "" 468590075Sobrien{ 4686117395Skan ia64_expand_call (NULL_RTX, operands[0], operands[2], false); 468790075Sobrien DONE; 4688117395Skan}) 468990075Sobrien 469090075Sobrien(define_expand "sibcall" 469190075Sobrien [(use (match_operand:DI 0 "" "")) 469290075Sobrien (use (match_operand 1 "" "")) 469390075Sobrien (use (match_operand 2 "" "")) 469490075Sobrien (use (match_operand 3 "" ""))] 469590075Sobrien "" 469690075Sobrien{ 4697117395Skan ia64_expand_call (NULL_RTX, operands[0], operands[2], true); 469890075Sobrien DONE; 4699117395Skan}) 470090075Sobrien 470190075Sobrien;; Subroutine call instruction returning a value. Operand 0 is the hard 470290075Sobrien;; register in which the value is returned. There are three more operands, 470390075Sobrien;; the same as the three operands of the `call' instruction (but with numbers 470490075Sobrien;; increased by one). 470590075Sobrien;; 470690075Sobrien;; Subroutines that return `BLKmode' objects use the `call' insn. 470790075Sobrien 470890075Sobrien(define_expand "call_value" 470990075Sobrien [(use (match_operand 0 "" "")) 471090075Sobrien (use (match_operand:DI 1 "" "")) 471190075Sobrien (use (match_operand 2 "" "")) 471290075Sobrien (use (match_operand 3 "" "")) 471390075Sobrien (use (match_operand 4 "" ""))] 471490075Sobrien "" 471590075Sobrien{ 4716117395Skan ia64_expand_call (operands[0], operands[1], operands[3], false); 471790075Sobrien DONE; 4718117395Skan}) 471990075Sobrien 472090075Sobrien(define_expand "sibcall_value" 472190075Sobrien [(use (match_operand 0 "" "")) 472290075Sobrien (use (match_operand:DI 1 "" "")) 472390075Sobrien (use (match_operand 2 "" "")) 472490075Sobrien (use (match_operand 3 "" "")) 472590075Sobrien (use (match_operand 4 "" ""))] 472690075Sobrien "" 472790075Sobrien{ 4728117395Skan ia64_expand_call (operands[0], operands[1], operands[3], true); 472990075Sobrien DONE; 4730117395Skan}) 473190075Sobrien 473290075Sobrien;; Call subroutine returning any type. 473390075Sobrien 473490075Sobrien(define_expand "untyped_call" 473590075Sobrien [(parallel [(call (match_operand 0 "" "") 473690075Sobrien (const_int 0)) 473790075Sobrien (match_operand 1 "" "") 473890075Sobrien (match_operand 2 "" "")])] 473990075Sobrien "" 474090075Sobrien{ 474190075Sobrien int i; 474290075Sobrien 474390075Sobrien emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx)); 474490075Sobrien 474590075Sobrien for (i = 0; i < XVECLEN (operands[2], 0); i++) 474690075Sobrien { 474790075Sobrien rtx set = XVECEXP (operands[2], 0, i); 474890075Sobrien emit_move_insn (SET_DEST (set), SET_SRC (set)); 474990075Sobrien } 475090075Sobrien 475190075Sobrien /* The optimizer does not know that the call sets the function value 475290075Sobrien registers we stored in the result block. We avoid problems by 475390075Sobrien claiming that all hard registers are used and clobbered at this 475490075Sobrien point. */ 475590075Sobrien emit_insn (gen_blockage ()); 475690075Sobrien 475790075Sobrien DONE; 4758117395Skan}) 475990075Sobrien 4760117395Skan(define_insn "call_nogp" 4761117395Skan [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i")) 4762117395Skan (const_int 0)) 4763117395Skan (clobber (match_operand:DI 1 "register_operand" "=b,b"))] 476490075Sobrien "" 4765117395Skan "br.call%+.many %1 = %0" 476690075Sobrien [(set_attr "itanium_class" "br,scall")]) 476790075Sobrien 4768117395Skan(define_insn "call_value_nogp" 476990075Sobrien [(set (match_operand 0 "" "") 4770117395Skan (call (mem:DI (match_operand:DI 1 "call_operand" "?b,i")) 4771117395Skan (const_int 0))) 4772117395Skan (clobber (match_operand:DI 2 "register_operand" "=b,b"))] 477390075Sobrien "" 4774117395Skan "br.call%+.many %2 = %1" 477590075Sobrien [(set_attr "itanium_class" "br,scall")]) 477690075Sobrien 4777117395Skan(define_insn "sibcall_nogp" 4778117395Skan [(call (mem:DI (match_operand:DI 0 "call_operand" "?b,i")) 4779117395Skan (const_int 0))] 478090075Sobrien "" 478190075Sobrien "br%+.many %0" 478290075Sobrien [(set_attr "itanium_class" "br,scall")]) 478390075Sobrien 4784117395Skan(define_insn "call_gp" 4785117395Skan [(call (mem (match_operand 0 "call_operand" "?r,i")) 4786117395Skan (const_int 1)) 4787117395Skan (clobber (match_operand:DI 1 "register_operand" "=b,b")) 4788117395Skan (clobber (match_scratch:DI 2 "=&r,X")) 4789117395Skan (clobber (match_scratch:DI 3 "=b,X"))] 479090075Sobrien "" 4791117395Skan "#" 479290075Sobrien [(set_attr "itanium_class" "br,scall")]) 479390075Sobrien 4794117395Skan;; Irritatingly, we don't have access to INSN within the split body. 4795117395Skan;; See commentary in ia64_split_call as to why these aren't peep2. 4796117395Skan(define_split 4797117395Skan [(call (mem (match_operand 0 "call_operand" "")) 4798117395Skan (const_int 1)) 4799117395Skan (clobber (match_operand:DI 1 "register_operand" "")) 4800117395Skan (clobber (match_scratch:DI 2 "")) 4801117395Skan (clobber (match_scratch:DI 3 ""))] 4802117395Skan "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)" 4803117395Skan [(const_int 0)] 4804117395Skan{ 4805117395Skan ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2], 4806117395Skan operands[3], true, false); 4807117395Skan DONE; 4808117395Skan}) 4809117395Skan 4810117395Skan(define_split 4811117395Skan [(call (mem (match_operand 0 "call_operand" "")) 4812117395Skan (const_int 1)) 4813117395Skan (clobber (match_operand:DI 1 "register_operand" "")) 4814117395Skan (clobber (match_scratch:DI 2 "")) 4815117395Skan (clobber (match_scratch:DI 3 ""))] 4816117395Skan "reload_completed" 4817117395Skan [(const_int 0)] 4818117395Skan{ 4819117395Skan ia64_split_call (NULL_RTX, operands[0], operands[1], operands[2], 4820117395Skan operands[3], false, false); 4821117395Skan DONE; 4822117395Skan}) 4823117395Skan 4824117395Skan(define_insn "call_value_gp" 482590075Sobrien [(set (match_operand 0 "" "") 4826117395Skan (call (mem:DI (match_operand:DI 1 "call_operand" "?r,i")) 4827117395Skan (const_int 1))) 4828117395Skan (clobber (match_operand:DI 2 "register_operand" "=b,b")) 4829117395Skan (clobber (match_scratch:DI 3 "=&r,X")) 4830117395Skan (clobber (match_scratch:DI 4 "=b,X"))] 483190075Sobrien "" 4832117395Skan "#" 483390075Sobrien [(set_attr "itanium_class" "br,scall")]) 483490075Sobrien 4835117395Skan(define_split 4836117395Skan [(set (match_operand 0 "" "") 4837117395Skan (call (mem:DI (match_operand:DI 1 "call_operand" "")) 4838117395Skan (const_int 1))) 4839117395Skan (clobber (match_operand:DI 2 "register_operand" "")) 4840117395Skan (clobber (match_scratch:DI 3 "")) 4841117395Skan (clobber (match_scratch:DI 4 ""))] 4842117395Skan "reload_completed && find_reg_note (insn, REG_NORETURN, NULL_RTX)" 4843117395Skan [(const_int 0)] 4844117395Skan{ 4845117395Skan ia64_split_call (operands[0], operands[1], operands[2], operands[3], 4846117395Skan operands[4], true, false); 4847117395Skan DONE; 4848117395Skan}) 4849117395Skan 4850117395Skan(define_split 4851117395Skan [(set (match_operand 0 "" "") 4852117395Skan (call (mem:DI (match_operand:DI 1 "call_operand" "")) 4853117395Skan (const_int 1))) 4854117395Skan (clobber (match_operand:DI 2 "register_operand" "")) 4855117395Skan (clobber (match_scratch:DI 3 "")) 4856117395Skan (clobber (match_scratch:DI 4 ""))] 4857117395Skan "reload_completed" 4858117395Skan [(const_int 0)] 4859117395Skan{ 4860117395Skan ia64_split_call (operands[0], operands[1], operands[2], operands[3], 4861117395Skan operands[4], false, false); 4862117395Skan DONE; 4863117395Skan}) 4864117395Skan 4865117395Skan(define_insn_and_split "sibcall_gp" 4866117395Skan [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,i")) 4867117395Skan (const_int 1)) 4868117395Skan (clobber (match_scratch:DI 1 "=&r,X")) 4869117395Skan (clobber (match_scratch:DI 2 "=b,X"))] 487090075Sobrien "" 4871117395Skan "#" 4872117395Skan "reload_completed" 4873117395Skan [(const_int 0)] 4874117395Skan{ 4875117395Skan ia64_split_call (NULL_RTX, operands[0], NULL_RTX, operands[1], 4876117395Skan operands[2], true, true); 4877117395Skan DONE; 4878117395Skan} 487990075Sobrien [(set_attr "itanium_class" "br")]) 488090075Sobrien 488190075Sobrien(define_insn "return_internal" 488290075Sobrien [(return) 488390075Sobrien (use (match_operand:DI 0 "register_operand" "b"))] 488490075Sobrien "" 488590075Sobrien "br.ret.sptk.many %0" 488690075Sobrien [(set_attr "itanium_class" "br")]) 488790075Sobrien 488890075Sobrien(define_insn "return" 488990075Sobrien [(return)] 489090075Sobrien "ia64_direct_return ()" 489190075Sobrien "br.ret.sptk.many rp" 489290075Sobrien [(set_attr "itanium_class" "br")]) 489390075Sobrien 489490075Sobrien(define_insn "*return_true" 489590075Sobrien [(set (pc) 489690075Sobrien (if_then_else (match_operator 0 "predicate_operator" 489790075Sobrien [(match_operand:BI 1 "register_operand" "c") 489890075Sobrien (const_int 0)]) 489990075Sobrien (return) 490090075Sobrien (pc)))] 490190075Sobrien "ia64_direct_return ()" 490290075Sobrien "(%J0) br.ret%+.many rp" 490390075Sobrien [(set_attr "itanium_class" "br") 490490075Sobrien (set_attr "predicable" "no")]) 490590075Sobrien 490690075Sobrien(define_insn "*return_false" 490790075Sobrien [(set (pc) 490890075Sobrien (if_then_else (match_operator 0 "predicate_operator" 490990075Sobrien [(match_operand:BI 1 "register_operand" "c") 491090075Sobrien (const_int 0)]) 491190075Sobrien (pc) 491290075Sobrien (return)))] 491390075Sobrien "ia64_direct_return ()" 491490075Sobrien "(%j0) br.ret%+.many rp" 491590075Sobrien [(set_attr "itanium_class" "br") 491690075Sobrien (set_attr "predicable" "no")]) 491790075Sobrien 491890075Sobrien(define_insn "jump" 491990075Sobrien [(set (pc) (label_ref (match_operand 0 "" "")))] 492090075Sobrien "" 492190075Sobrien "br %l0" 492290075Sobrien [(set_attr "itanium_class" "br")]) 492390075Sobrien 492490075Sobrien(define_insn "indirect_jump" 492590075Sobrien [(set (pc) (match_operand:DI 0 "register_operand" "b"))] 492690075Sobrien "" 492790075Sobrien "br %0" 492890075Sobrien [(set_attr "itanium_class" "br")]) 492990075Sobrien 493090075Sobrien(define_expand "tablejump" 493190075Sobrien [(parallel [(set (pc) (match_operand:DI 0 "memory_operand" "")) 493290075Sobrien (use (label_ref (match_operand 1 "" "")))])] 493390075Sobrien "" 493490075Sobrien{ 493590075Sobrien rtx op0 = operands[0]; 493690075Sobrien rtx addr; 493790075Sobrien 493890075Sobrien /* ??? Bother -- do_tablejump is "helpful" and pulls the table 493990075Sobrien element into a register without bothering to see whether that 494090075Sobrien is necessary given the operand predicate. Check for MEM just 494190075Sobrien in case someone fixes this. */ 494290075Sobrien if (GET_CODE (op0) == MEM) 494390075Sobrien addr = XEXP (op0, 0); 494490075Sobrien else 494590075Sobrien { 494690075Sobrien /* Otherwise, cheat and guess that the previous insn in the 494790075Sobrien stream was the memory load. Grab the address from that. 494890075Sobrien Note we have to momentarily pop out of the sequence started 494990075Sobrien by the insn-emit wrapper in order to grab the last insn. */ 495090075Sobrien rtx last, set; 495190075Sobrien 495290075Sobrien end_sequence (); 495390075Sobrien last = get_last_insn (); 495490075Sobrien start_sequence (); 495590075Sobrien set = single_set (last); 495690075Sobrien 495790075Sobrien if (! rtx_equal_p (SET_DEST (set), op0) 495890075Sobrien || GET_CODE (SET_SRC (set)) != MEM) 495990075Sobrien abort (); 496090075Sobrien addr = XEXP (SET_SRC (set), 0); 496190075Sobrien if (rtx_equal_p (addr, op0)) 496290075Sobrien abort (); 496390075Sobrien } 496490075Sobrien 496590075Sobrien /* Jump table elements are stored pc-relative. That is, a displacement 496690075Sobrien from the entry to the label. Thus to convert to an absolute address 496790075Sobrien we add the address of the memory from which the value is loaded. */ 496890075Sobrien operands[0] = expand_simple_binop (DImode, PLUS, op0, addr, 496990075Sobrien NULL_RTX, 1, OPTAB_DIRECT); 497090075Sobrien}) 497190075Sobrien 497290075Sobrien(define_insn "*tablejump_internal" 497390075Sobrien [(set (pc) (match_operand:DI 0 "register_operand" "b")) 497490075Sobrien (use (label_ref (match_operand 1 "" "")))] 497590075Sobrien "" 497690075Sobrien "br %0" 497790075Sobrien [(set_attr "itanium_class" "br")]) 497890075Sobrien 497990075Sobrien 498090075Sobrien;; :::::::::::::::::::: 498190075Sobrien;; :: 498290075Sobrien;; :: Prologue and Epilogue instructions 498390075Sobrien;; :: 498490075Sobrien;; :::::::::::::::::::: 498590075Sobrien 498690075Sobrien(define_expand "prologue" 498790075Sobrien [(const_int 1)] 498890075Sobrien "" 498990075Sobrien{ 499090075Sobrien ia64_expand_prologue (); 499190075Sobrien DONE; 4992117395Skan}) 499390075Sobrien 499490075Sobrien(define_expand "epilogue" 499590075Sobrien [(return)] 499690075Sobrien "" 499790075Sobrien{ 499890075Sobrien ia64_expand_epilogue (0); 499990075Sobrien DONE; 5000117395Skan}) 500190075Sobrien 500290075Sobrien(define_expand "sibcall_epilogue" 500390075Sobrien [(return)] 500490075Sobrien "" 500590075Sobrien{ 500690075Sobrien ia64_expand_epilogue (1); 500790075Sobrien DONE; 5008117395Skan}) 500990075Sobrien 501090075Sobrien;; This prevents the scheduler from moving the SP decrement past FP-relative 501190075Sobrien;; stack accesses. This is the same as adddi3 plus the extra set. 501290075Sobrien 501390075Sobrien(define_insn "prologue_allocate_stack" 501490075Sobrien [(set (match_operand:DI 0 "register_operand" "=r,r,r") 501590075Sobrien (plus:DI (match_operand:DI 1 "register_operand" "%r,r,a") 501690075Sobrien (match_operand:DI 2 "gr_reg_or_22bit_operand" "r,I,J"))) 501796263Sobrien (set (match_operand:DI 3 "register_operand" "+r,r,r") 501890075Sobrien (match_dup 3))] 501990075Sobrien "" 502090075Sobrien "@ 5021117395Skan add %0 = %1, %2 5022117395Skan adds %0 = %2, %1 5023117395Skan addl %0 = %2, %1" 502490075Sobrien [(set_attr "itanium_class" "ialu")]) 502590075Sobrien 502690075Sobrien;; This prevents the scheduler from moving the SP restore past FP-relative 502790075Sobrien;; stack accesses. This is similar to movdi plus the extra set. 502890075Sobrien 502990075Sobrien(define_insn "epilogue_deallocate_stack" 503090075Sobrien [(set (match_operand:DI 0 "register_operand" "=r") 503190075Sobrien (match_operand:DI 1 "register_operand" "+r")) 503290075Sobrien (set (match_dup 1) (match_dup 1))] 503390075Sobrien "" 503490075Sobrien "mov %0 = %1" 503590075Sobrien [(set_attr "itanium_class" "ialu")]) 503690075Sobrien 5037117395Skan;; As USE insns aren't meaningful after reload, this is used instead 5038117395Skan;; to prevent deleting instructions setting registers for EH handling 5039117395Skan(define_insn "prologue_use" 5040117395Skan [(unspec:DI [(match_operand:DI 0 "register_operand" "")] 5041117395Skan UNSPEC_PROLOGUE_USE)] 5042117395Skan "" 5043117395Skan "" 5044117395Skan [(set_attr "itanium_class" "ignore") 5045117395Skan (set_attr "predicable" "no")]) 5046117395Skan 504790075Sobrien;; Allocate a new register frame. 504890075Sobrien 504990075Sobrien(define_insn "alloc" 505090075Sobrien [(set (match_operand:DI 0 "register_operand" "=r") 5051117395Skan (unspec_volatile:DI [(const_int 0)] UNSPECV_ALLOC)) 505290075Sobrien (use (match_operand:DI 1 "const_int_operand" "i")) 505390075Sobrien (use (match_operand:DI 2 "const_int_operand" "i")) 505490075Sobrien (use (match_operand:DI 3 "const_int_operand" "i")) 505590075Sobrien (use (match_operand:DI 4 "const_int_operand" "i"))] 505690075Sobrien "" 505790075Sobrien "alloc %0 = ar.pfs, %1, %2, %3, %4" 505890075Sobrien [(set_attr "itanium_class" "syst_m0") 505990075Sobrien (set_attr "predicable" "no")]) 506090075Sobrien 506190075Sobrien;; Modifies ar.unat 506290075Sobrien(define_expand "gr_spill" 506390075Sobrien [(parallel [(set (match_operand:DI 0 "memory_operand" "=m") 506490075Sobrien (unspec:DI [(match_operand:DI 1 "register_operand" "r") 5065117395Skan (match_operand:DI 2 "const_int_operand" "")] 5066117395Skan UNSPEC_GR_SPILL)) 506790075Sobrien (clobber (match_dup 3))])] 506890075Sobrien "" 506990075Sobrien "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);") 507090075Sobrien 507190075Sobrien(define_insn "gr_spill_internal" 507290075Sobrien [(set (match_operand:DI 0 "memory_operand" "=m") 507390075Sobrien (unspec:DI [(match_operand:DI 1 "register_operand" "r") 5074117395Skan (match_operand:DI 2 "const_int_operand" "")] 5075117395Skan UNSPEC_GR_SPILL)) 507690075Sobrien (clobber (match_operand:DI 3 "register_operand" ""))] 507790075Sobrien "" 507890075Sobrien{ 5079117395Skan /* Note that we use a C output pattern here to avoid the predicate 5080117395Skan being automatically added before the .mem.offset directive. */ 5081117395Skan return ".mem.offset %2, 0\;%,st8.spill %0 = %1%P0"; 5082117395Skan} 508390075Sobrien [(set_attr "itanium_class" "st")]) 508490075Sobrien 508590075Sobrien;; Reads ar.unat 508690075Sobrien(define_expand "gr_restore" 508790075Sobrien [(parallel [(set (match_operand:DI 0 "register_operand" "=r") 508890075Sobrien (unspec:DI [(match_operand:DI 1 "memory_operand" "m") 5089117395Skan (match_operand:DI 2 "const_int_operand" "")] 5090117395Skan UNSPEC_GR_RESTORE)) 509190075Sobrien (use (match_dup 3))])] 509290075Sobrien "" 509390075Sobrien "operands[3] = gen_rtx_REG (DImode, AR_UNAT_REGNUM);") 509490075Sobrien 509590075Sobrien(define_insn "gr_restore_internal" 509690075Sobrien [(set (match_operand:DI 0 "register_operand" "=r") 509790075Sobrien (unspec:DI [(match_operand:DI 1 "memory_operand" "m") 5098117395Skan (match_operand:DI 2 "const_int_operand" "")] 5099117395Skan UNSPEC_GR_RESTORE)) 510090075Sobrien (use (match_operand:DI 3 "register_operand" ""))] 510190075Sobrien "" 5102117395Skan { return ".mem.offset %2, 0\;%,ld8.fill %0 = %1%P1"; } 510390075Sobrien [(set_attr "itanium_class" "ld")]) 510490075Sobrien 510590075Sobrien(define_insn "fr_spill" 510690075Sobrien [(set (match_operand:TF 0 "memory_operand" "=m") 5107117395Skan (unspec:TF [(match_operand:TF 1 "register_operand" "f")] 5108117395Skan UNSPEC_FR_SPILL))] 510990075Sobrien "" 511090075Sobrien "stf.spill %0 = %1%P0" 511190075Sobrien [(set_attr "itanium_class" "stf")]) 511290075Sobrien 511390075Sobrien(define_insn "fr_restore" 511490075Sobrien [(set (match_operand:TF 0 "register_operand" "=f") 5115117395Skan (unspec:TF [(match_operand:TF 1 "memory_operand" "m")] 5116117395Skan UNSPEC_FR_RESTORE))] 511790075Sobrien "" 511890075Sobrien "ldf.fill %0 = %1%P1" 511990075Sobrien [(set_attr "itanium_class" "fld")]) 512090075Sobrien 512190075Sobrien;; ??? The explicit stop is not ideal. It would be better if 512290075Sobrien;; rtx_needs_barrier took care of this, but this is something that can be 512390075Sobrien;; fixed later. This avoids an RSE DV. 512490075Sobrien 512590075Sobrien(define_insn "bsp_value" 512690075Sobrien [(set (match_operand:DI 0 "register_operand" "=r") 5127117395Skan (unspec:DI [(const_int 0)] UNSPEC_BSP_VALUE))] 512890075Sobrien "" 5129117395Skan "* 5130117395Skan{ 5131117395Skan return \";;\;%,mov %0 = ar.bsp\"; 5132117395Skan}" 513390075Sobrien [(set_attr "itanium_class" "frar_i")]) 513490075Sobrien 513590075Sobrien(define_insn "set_bsp" 5136117395Skan [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")] 5137117395Skan UNSPECV_SET_BSP)] 513890075Sobrien "" 5139117395Skan "flushrs 5140117395Skan mov r19=ar.rsc 5141117395Skan ;; 5142117395Skan and r19=0x1c,r19 5143117395Skan ;; 5144117395Skan mov ar.rsc=r19 5145117395Skan ;; 5146117395Skan mov ar.bspstore=%0 5147117395Skan ;; 5148117395Skan or r19=0x3,r19 5149117395Skan ;; 5150117395Skan loadrs 5151117395Skan invala 5152117395Skan ;; 5153117395Skan mov ar.rsc=r19" 515490075Sobrien [(set_attr "itanium_class" "unknown") 515590075Sobrien (set_attr "predicable" "no")]) 515690075Sobrien 515790075Sobrien;; ??? The explicit stops are not ideal. It would be better if 515890075Sobrien;; rtx_needs_barrier took care of this, but this is something that can be 515990075Sobrien;; fixed later. This avoids an RSE DV. 516090075Sobrien 516190075Sobrien(define_insn "flushrs" 5162117395Skan [(unspec [(const_int 0)] UNSPEC_FLUSHRS)] 516390075Sobrien "" 516490075Sobrien ";;\;flushrs\;;;" 5165117395Skan [(set_attr "itanium_class" "rse_m") 5166117395Skan (set_attr "predicable" "no")]) 516790075Sobrien 516890075Sobrien;; :::::::::::::::::::: 516990075Sobrien;; :: 517090075Sobrien;; :: Miscellaneous instructions 517190075Sobrien;; :: 517290075Sobrien;; :::::::::::::::::::: 517390075Sobrien 517490075Sobrien;; ??? Emiting a NOP instruction isn't very useful. This should probably 517590075Sobrien;; be emitting ";;" to force a break in the instruction packing. 517690075Sobrien 517790075Sobrien;; No operation, needed in case the user uses -g but not -O. 517890075Sobrien(define_insn "nop" 517990075Sobrien [(const_int 0)] 518090075Sobrien "" 518190075Sobrien "nop 0" 518290075Sobrien [(set_attr "itanium_class" "unknown")]) 518390075Sobrien 518490075Sobrien(define_insn "nop_m" 518590075Sobrien [(const_int 1)] 518690075Sobrien "" 518790075Sobrien "nop.m 0" 518890075Sobrien [(set_attr "itanium_class" "nop_m")]) 518990075Sobrien 519090075Sobrien(define_insn "nop_i" 519190075Sobrien [(const_int 2)] 519290075Sobrien "" 519390075Sobrien "nop.i 0" 519490075Sobrien [(set_attr "itanium_class" "nop_i")]) 519590075Sobrien 519690075Sobrien(define_insn "nop_f" 519790075Sobrien [(const_int 3)] 519890075Sobrien "" 519990075Sobrien "nop.f 0" 520090075Sobrien [(set_attr "itanium_class" "nop_f")]) 520190075Sobrien 520290075Sobrien(define_insn "nop_b" 520390075Sobrien [(const_int 4)] 520490075Sobrien "" 520590075Sobrien "nop.b 0" 520690075Sobrien [(set_attr "itanium_class" "nop_b")]) 520790075Sobrien 520890075Sobrien(define_insn "nop_x" 520990075Sobrien [(const_int 5)] 521090075Sobrien "" 521190075Sobrien "" 521290075Sobrien [(set_attr "itanium_class" "nop_x")]) 521390075Sobrien 521490075Sobrien(define_insn "bundle_selector" 5215117395Skan [(unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BUNDLE_SELECTOR)] 521690075Sobrien "" 5217117395Skan { return get_bundle_name (INTVAL (operands[0])); } 521890075Sobrien [(set_attr "itanium_class" "ignore") 521990075Sobrien (set_attr "predicable" "no")]) 522090075Sobrien 522190075Sobrien;; Pseudo instruction that prevents the scheduler from moving code above this 522290075Sobrien;; point. 522390075Sobrien(define_insn "blockage" 5224117395Skan [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 522590075Sobrien "" 522690075Sobrien "" 522790075Sobrien [(set_attr "itanium_class" "ignore") 522890075Sobrien (set_attr "predicable" "no")]) 522990075Sobrien 523090075Sobrien(define_insn "insn_group_barrier" 5231117395Skan [(unspec_volatile [(match_operand 0 "const_int_operand" "")] 5232117395Skan UNSPECV_INSN_GROUP_BARRIER)] 523390075Sobrien "" 523490075Sobrien ";;" 523590075Sobrien [(set_attr "itanium_class" "stop_bit") 523690075Sobrien (set_attr "predicable" "no")]) 523790075Sobrien 523896263Sobrien(define_expand "trap" 523996263Sobrien [(trap_if (const_int 1) (const_int 0))] 524096263Sobrien "" 524196263Sobrien "") 524296263Sobrien 524396263Sobrien;; ??? We don't have a match-any slot type. Setting the type to unknown 524496263Sobrien;; produces worse code that setting the slot type to A. 524596263Sobrien 524696263Sobrien(define_insn "*trap" 524796263Sobrien [(trap_if (const_int 1) (match_operand 0 "const_int_operand" ""))] 524896263Sobrien "" 524996263Sobrien "break %0" 525096263Sobrien [(set_attr "itanium_class" "chk_s")]) 525196263Sobrien 525296263Sobrien(define_expand "conditional_trap" 525396263Sobrien [(trap_if (match_operand 0 "" "") (match_operand 1 "" ""))] 525496263Sobrien "" 525596263Sobrien{ 525696263Sobrien operands[0] = ia64_expand_compare (GET_CODE (operands[0]), VOIDmode); 525796263Sobrien}) 525896263Sobrien 525996263Sobrien(define_insn "*conditional_trap" 526096263Sobrien [(trap_if (match_operator 0 "predicate_operator" 526196263Sobrien [(match_operand:BI 1 "register_operand" "c") 526296263Sobrien (const_int 0)]) 526396263Sobrien (match_operand 2 "const_int_operand" ""))] 526496263Sobrien "" 526596263Sobrien "(%J0) break %2" 526696263Sobrien [(set_attr "itanium_class" "chk_s") 526796263Sobrien (set_attr "predicable" "no")]) 526896263Sobrien 526990075Sobrien(define_insn "break_f" 5270117395Skan [(unspec_volatile [(const_int 0)] UNSPECV_BREAK)] 527190075Sobrien "" 527290075Sobrien "break.f 0" 527390075Sobrien [(set_attr "itanium_class" "nop_f")]) 527490075Sobrien 527590075Sobrien(define_insn "prefetch" 527690075Sobrien [(prefetch (match_operand:DI 0 "address_operand" "p") 527790075Sobrien (match_operand:DI 1 "const_int_operand" "n") 527890075Sobrien (match_operand:DI 2 "const_int_operand" "n"))] 527990075Sobrien "" 528090075Sobrien{ 528190075Sobrien static const char * const alt[2][4] = { 528290075Sobrien { 528390075Sobrien "lfetch.nta [%0]", 528490075Sobrien "lfetch.nt1 [%0]", 528590075Sobrien "lfetch.nt2 [%0]", 528690075Sobrien "lfetch [%0]" 528790075Sobrien }, 528890075Sobrien { 528990075Sobrien "lfetch.excl.nta [%0]", 529090075Sobrien "lfetch.excl.nt1 [%0]", 529190075Sobrien "lfetch.excl.nt2 [%0]", 529290075Sobrien "lfetch.excl [%0]" 529390075Sobrien } 529490075Sobrien }; 529590075Sobrien int i = (INTVAL (operands[1])); 529690075Sobrien int j = (INTVAL (operands[2])); 529790075Sobrien 529890075Sobrien if (i != 0 && i != 1) 529990075Sobrien abort (); 530090075Sobrien if (j < 0 || j > 3) 530190075Sobrien abort (); 530290075Sobrien return alt[i][j]; 530390075Sobrien} 530490075Sobrien [(set_attr "itanium_class" "lfetch")]) 530590075Sobrien 530690075Sobrien;; Non-local goto support. 530790075Sobrien 530890075Sobrien(define_expand "save_stack_nonlocal" 530990075Sobrien [(use (match_operand:OI 0 "memory_operand" "")) 531090075Sobrien (use (match_operand:DI 1 "register_operand" ""))] 531190075Sobrien "" 531290075Sobrien{ 531390075Sobrien emit_library_call (gen_rtx_SYMBOL_REF (Pmode, 531490075Sobrien \"__ia64_save_stack_nonlocal\"), 531590075Sobrien 0, VOIDmode, 2, XEXP (operands[0], 0), Pmode, 531690075Sobrien operands[1], Pmode); 531790075Sobrien DONE; 5318117395Skan}) 531990075Sobrien 532090075Sobrien(define_expand "nonlocal_goto" 532190075Sobrien [(use (match_operand 0 "general_operand" "")) 532290075Sobrien (use (match_operand 1 "general_operand" "")) 532390075Sobrien (use (match_operand 2 "general_operand" "")) 532490075Sobrien (use (match_operand 3 "general_operand" ""))] 532590075Sobrien "" 532690075Sobrien{ 532790075Sobrien emit_library_call (gen_rtx_SYMBOL_REF (Pmode, \"__ia64_nonlocal_goto\"), 532890075Sobrien LCT_NORETURN, VOIDmode, 3, 532990075Sobrien operands[1], Pmode, 533090075Sobrien copy_to_reg (XEXP (operands[2], 0)), Pmode, 533190075Sobrien operands[3], Pmode); 533290075Sobrien emit_barrier (); 533390075Sobrien DONE; 5334117395Skan}) 533590075Sobrien 5336117395Skan(define_insn_and_split "builtin_setjmp_receiver" 5337117395Skan [(unspec_volatile [(match_operand:DI 0 "" "")] UNSPECV_SETJMP_RECEIVER)] 533890075Sobrien "" 5339117395Skan "#" 5340117395Skan "reload_completed" 5341117395Skan [(const_int 0)] 534290075Sobrien{ 5343117395Skan ia64_reload_gp (); 534490075Sobrien DONE; 5345117395Skan}) 534690075Sobrien 534790075Sobrien(define_expand "eh_epilogue" 534890075Sobrien [(use (match_operand:DI 0 "register_operand" "r")) 534990075Sobrien (use (match_operand:DI 1 "register_operand" "r")) 535090075Sobrien (use (match_operand:DI 2 "register_operand" "r"))] 535190075Sobrien "" 535290075Sobrien{ 535390075Sobrien rtx bsp = gen_rtx_REG (Pmode, 10); 535490075Sobrien rtx sp = gen_rtx_REG (Pmode, 9); 535590075Sobrien 535690075Sobrien if (GET_CODE (operands[0]) != REG || REGNO (operands[0]) != 10) 535790075Sobrien { 535890075Sobrien emit_move_insn (bsp, operands[0]); 535990075Sobrien operands[0] = bsp; 536090075Sobrien } 536190075Sobrien if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 9) 536290075Sobrien { 536390075Sobrien emit_move_insn (sp, operands[2]); 536490075Sobrien operands[2] = sp; 536590075Sobrien } 536690075Sobrien emit_insn (gen_rtx_USE (VOIDmode, sp)); 536790075Sobrien emit_insn (gen_rtx_USE (VOIDmode, bsp)); 536890075Sobrien 536990075Sobrien cfun->machine->ia64_eh_epilogue_sp = sp; 537090075Sobrien cfun->machine->ia64_eh_epilogue_bsp = bsp; 5371117395Skan}) 537290075Sobrien 537390075Sobrien;; Builtin apply support. 537490075Sobrien 537590075Sobrien(define_expand "restore_stack_nonlocal" 537690075Sobrien [(use (match_operand:DI 0 "register_operand" "")) 537790075Sobrien (use (match_operand:OI 1 "memory_operand" ""))] 537890075Sobrien "" 537990075Sobrien{ 538090075Sobrien emit_library_call (gen_rtx_SYMBOL_REF (Pmode, 5381117395Skan "__ia64_restore_stack_nonlocal"), 538290075Sobrien 0, VOIDmode, 1, 538390075Sobrien copy_to_reg (XEXP (operands[1], 0)), Pmode); 538490075Sobrien DONE; 5385117395Skan}) 538690075Sobrien 538790075Sobrien 538890075Sobrien;;; Intrinsics support. 538990075Sobrien 539090075Sobrien(define_expand "mf" 539190075Sobrien [(set (mem:BLK (match_dup 0)) 5392117395Skan (unspec:BLK [(mem:BLK (match_dup 0))] UNSPEC_MF))] 539390075Sobrien "" 539490075Sobrien{ 539590075Sobrien operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode)); 539690075Sobrien MEM_VOLATILE_P (operands[0]) = 1; 5397117395Skan}) 539890075Sobrien 539990075Sobrien(define_insn "*mf_internal" 540090075Sobrien [(set (match_operand:BLK 0 "" "") 5401117395Skan (unspec:BLK [(match_operand:BLK 1 "" "")] UNSPEC_MF))] 540290075Sobrien "" 540390075Sobrien "mf" 540490075Sobrien [(set_attr "itanium_class" "syst_m")]) 540590075Sobrien 540690075Sobrien(define_insn "fetchadd_acq_si" 540790075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 540890075Sobrien (match_dup 1)) 540990075Sobrien (set (match_operand:SI 1 "not_postinc_memory_operand" "+S") 541090075Sobrien (unspec:SI [(match_dup 1) 5411117395Skan (match_operand:SI 2 "fetchadd_operand" "n")] 5412117395Skan UNSPEC_FETCHADD_ACQ))] 541390075Sobrien "" 541490075Sobrien "fetchadd4.acq %0 = %1, %2" 541590075Sobrien [(set_attr "itanium_class" "sem")]) 541690075Sobrien 541790075Sobrien(define_insn "fetchadd_acq_di" 541890075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 541990075Sobrien (match_dup 1)) 542090075Sobrien (set (match_operand:DI 1 "not_postinc_memory_operand" "+S") 542190075Sobrien (unspec:DI [(match_dup 1) 5422117395Skan (match_operand:DI 2 "fetchadd_operand" "n")] 5423117395Skan UNSPEC_FETCHADD_ACQ))] 542490075Sobrien "" 542590075Sobrien "fetchadd8.acq %0 = %1, %2" 542690075Sobrien [(set_attr "itanium_class" "sem")]) 542790075Sobrien 542890075Sobrien(define_insn "cmpxchg_acq_si" 542990075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 543090075Sobrien (match_dup 1)) 543190075Sobrien (set (match_operand:SI 1 "not_postinc_memory_operand" "+S") 543290075Sobrien (unspec:SI [(match_dup 1) 543390075Sobrien (match_operand:SI 2 "gr_register_operand" "r") 5434117395Skan (match_operand 3 "ar_ccv_reg_operand" "")] 5435117395Skan UNSPEC_CMPXCHG_ACQ))] 543690075Sobrien "" 543790075Sobrien "cmpxchg4.acq %0 = %1, %2, %3" 543890075Sobrien [(set_attr "itanium_class" "sem")]) 543990075Sobrien 544090075Sobrien(define_insn "cmpxchg_acq_di" 544190075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 544290075Sobrien (match_dup 1)) 544390075Sobrien (set (match_operand:DI 1 "not_postinc_memory_operand" "+S") 544490075Sobrien (unspec:DI [(match_dup 1) 544590075Sobrien (match_operand:DI 2 "gr_register_operand" "r") 5446117395Skan (match_operand:DI 3 "ar_ccv_reg_operand" "")] 5447117395Skan UNSPEC_CMPXCHG_ACQ))] 544890075Sobrien "" 544990075Sobrien "cmpxchg8.acq %0 = %1, %2, %3" 545090075Sobrien [(set_attr "itanium_class" "sem")]) 545190075Sobrien 545290075Sobrien(define_insn "xchgsi" 545390075Sobrien [(set (match_operand:SI 0 "gr_register_operand" "=r") 545490075Sobrien (match_operand:SI 1 "not_postinc_memory_operand" "+S")) 545590075Sobrien (set (match_dup 1) 545690075Sobrien (match_operand:SI 2 "gr_register_operand" "r"))] 545790075Sobrien "" 545890075Sobrien "xchg4 %0 = %1, %2" 545990075Sobrien [(set_attr "itanium_class" "sem")]) 546090075Sobrien 546190075Sobrien(define_insn "xchgdi" 546290075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 546390075Sobrien (match_operand:DI 1 "not_postinc_memory_operand" "+S")) 546490075Sobrien (set (match_dup 1) 546590075Sobrien (match_operand:DI 2 "gr_register_operand" "r"))] 546690075Sobrien "" 546790075Sobrien "xchg8 %0 = %1, %2" 546890075Sobrien [(set_attr "itanium_class" "sem")]) 546990075Sobrien 547090075Sobrien;; Predication. 547190075Sobrien 547290075Sobrien(define_cond_exec 547390075Sobrien [(match_operator 0 "predicate_operator" 547490075Sobrien [(match_operand:BI 1 "register_operand" "c") 547590075Sobrien (const_int 0)])] 547690075Sobrien "" 547790075Sobrien "(%J0)") 547890075Sobrien 547990075Sobrien(define_insn "pred_rel_mutex" 548090075Sobrien [(set (match_operand:BI 0 "register_operand" "+c") 5481117395Skan (unspec:BI [(match_dup 0)] UNSPEC_PRED_REL_MUTEX))] 548290075Sobrien "" 548390075Sobrien ".pred.rel.mutex %0, %I0" 548490075Sobrien [(set_attr "itanium_class" "ignore") 548590075Sobrien (set_attr "predicable" "no")]) 548690075Sobrien 548790075Sobrien(define_insn "safe_across_calls_all" 5488117395Skan [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_ALL)] 548990075Sobrien "" 549090075Sobrien ".pred.safe_across_calls p1-p63" 549190075Sobrien [(set_attr "itanium_class" "ignore") 549290075Sobrien (set_attr "predicable" "no")]) 549390075Sobrien 549490075Sobrien(define_insn "safe_across_calls_normal" 5495117395Skan [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_NORMAL)] 549690075Sobrien "" 549790075Sobrien{ 549890075Sobrien emit_safe_across_calls (asm_out_file); 5499117395Skan return ""; 5500117395Skan} 550190075Sobrien [(set_attr "itanium_class" "ignore") 550290075Sobrien (set_attr "predicable" "no")]) 550390075Sobrien 550490075Sobrien;; UNSPEC instruction definition to "swizzle" 32 bit pointer into 64 bit 550590075Sobrien;; pointer. This is used by the HP-UX 32 bit mode. 550690075Sobrien 550790075Sobrien(define_insn "ptr_extend" 550890075Sobrien [(set (match_operand:DI 0 "gr_register_operand" "=r") 5509117395Skan (unspec:DI [(match_operand:SI 1 "gr_register_operand" "r")] 5510117395Skan UNSPEC_ADDP4))] 551190075Sobrien "" 551290075Sobrien "addp4 %0 = 0,%1" 551390075Sobrien [(set_attr "itanium_class" "ialu")]) 551490075Sobrien 551590075Sobrien;; 5516117395Skan;; Optimizations for ptr_extend 5517117395Skan 5518117395Skan(define_insn "*ptr_extend_plus_1" 5519117395Skan [(set (match_operand:DI 0 "gr_register_operand" "=r") 5520117395Skan (unspec:DI 5521117395Skan [(plus:SI (match_operand:SI 1 "basereg_operand" "r") 5522117395Skan (match_operand:SI 2 "gr_reg_or_14bit_operand" "rI"))] 5523117395Skan UNSPEC_ADDP4))] 5524117395Skan "addp4_optimize_ok (operands[1], operands[2])" 5525117395Skan "addp4 %0 = %2, %1" 5526117395Skan [(set_attr "itanium_class" "ialu")]) 5527117395Skan 5528117395Skan(define_insn "*ptr_extend_plus_2" 5529117395Skan [(set (match_operand:DI 0 "gr_register_operand" "=r") 5530117395Skan (unspec:DI 5531117395Skan [(plus:SI (match_operand:SI 1 "gr_register_operand" "r") 5532117395Skan (match_operand:SI 2 "basereg_operand" "r"))] 5533117395Skan UNSPEC_ADDP4))] 5534117395Skan "addp4_optimize_ok (operands[1], operands[2])" 5535117395Skan "addp4 %0 = %1, %2" 5536117395Skan [(set_attr "itanium_class" "ialu")]) 5537