diff options
Diffstat (limited to 'contrib/gcc/config/ia64/ia64.md')
-rw-r--r-- | contrib/gcc/config/ia64/ia64.md | 1861 |
1 files changed, 1108 insertions, 753 deletions
diff --git a/contrib/gcc/config/ia64/ia64.md b/contrib/gcc/config/ia64/ia64.md index 3b88d9f..4bda8f4 100644 --- a/contrib/gcc/config/ia64/ia64.md +++ b/contrib/gcc/config/ia64/ia64.md @@ -1,22 +1,23 @@ ;; IA-64 Machine description template -;; Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. +;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 +;; Free Software Foundation, Inc. ;; Contributed by James E. Wilson <wilson@cygnus.com> and ;; David Mosberger <davidm@hpl.hp.com>. -;; This file is part of GNU CC. +;; This file is part of GCC. -;; GNU CC is free software; you can redistribute it and/or modify +;; GCC is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. -;; GNU CC is distributed in the hope that it will be useful, +;; GCC is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with GNU CC; see the file COPYING. If not, write to +;; along with GCC; see the file COPYING. If not, write to ;; the Free Software Foundation, 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. @@ -63,7 +64,7 @@ (UNSPEC_FR_RESTORE 13) (UNSPEC_FR_RECIP_APPROX 14) (UNSPEC_PRED_REL_MUTEX 15) - (UNSPEC_POPCNT 16) + (UNSPEC_GETF_EXP 16) (UNSPEC_PIC_CALL 17) (UNSPEC_MF 18) (UNSPEC_CMPXCHG_ACQ 19) @@ -74,6 +75,8 @@ (UNSPEC_ADDP4 24) (UNSPEC_PROLOGUE_USE 25) (UNSPEC_RET_ADDR 26) + (UNSPEC_SETF_EXP 27) + (UNSPEC_FR_SQRT_RECIP_APPROX 28) ]) (define_constants @@ -93,6 +96,10 @@ ;; :: ;; :::::::::::::::::::: +;; Processor type. This attribute must exactly match the processor_type +;; enumeration in ia64.h. +(define_attr "cpu" "itanium,itanium2" (const (symbol_ref "ia64_tune"))) + ;; Instruction type. This primarily determines how instructions can be ;; packed in bundles, and secondarily affects scheduling to function units. @@ -112,8 +119,8 @@ (define_attr "itanium_class" "unknown,ignore,stop_bit,br,fcmp,fcvtfx,fld, fmac,fmisc,frar_i,frar_m,frbr,frfr,frpr,ialu,icmp,ilog,ishf,ld, chk_s,long_i,mmmul,mmshf,mmshfi,rse_m,scall,sem,stf,st,syst_m0, - syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop_b,nop_f, - nop_i,nop_m,nop_x,lfetch" + syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop,nop_b,nop_f, + nop_i,nop_m,nop_x,lfetch,pre_cycle" (const_string "unknown")) ;; chk_s has an I and an M form; use type A for convenience. @@ -147,77 +154,28 @@ (define_attr "predicable" "no,yes" (const_string "yes")) +;; Empty. True iff this insn does not generate any code. + +(define_attr "empty" "no,yes" (const_string "no")) + -;; :::::::::::::::::::: -;; :: -;; :: Function Units -;; :: -;; :::::::::::::::::::: -;; We define 6 "dummy" functional units. All the real work to decide which -;; insn uses which unit is done by our MD_SCHED_REORDER hooks. We only -;; have to ensure here that there are enough copies of the dummy unit so -;; that the scheduler doesn't get confused by MD_SCHED_REORDER. -;; Other than the 6 dummies for normal insns, we also add a single dummy unit -;; for stop bits. - -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "br") 0 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "scall") 0 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fcmp") 2 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fcvtfx") 7 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fld") 9 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fmac") 5 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fmisc") 5 0) - -;; There is only one insn `mov = ar.bsp' for frar_i: -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frar_i") 13 0) -;; There is only ony insn `mov = ar.unat' for frar_m: -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frar_m") 6 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frbr") 2 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frfr") 2 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frpr") 2 0) - -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ialu") 1 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "icmp") 1 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ilog") 1 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ishf") 1 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ld") 2 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "long_i") 1 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmmul") 2 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmshf") 2 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmshfi") 2 0) - -;; Now we have only one insn (flushrs) of such class. We assume that flushrs -;; is the 1st syllable of the bundle after stop bit. -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "rse_m") 0 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "sem") 11 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "stf") 1 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "st") 1 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "syst_m0") 1 0) -;; Now we use only one insn `mf'. Therfore latency time is set up to 0. -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "syst_m") 0 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tbit") 1 0) - -;; There is only one insn `mov ar.pfs =' for toar_i therefore we use -;; latency time equal to 0: -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "toar_i") 0 0) -;; There are only ony 2 insns `mov ar.ccv =' and `mov ar.unat =' for toar_m: -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "toar_m") 5 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tobr") 1 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tofr") 9 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "topr") 1 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "xmpy") 7 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "xtd") 1 0) - -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_m") 0 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_i") 0 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_f") 0 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_b") 0 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_x") 0 0) - -(define_function_unit "stop_bit" 1 1 (eq_attr "itanium_class" "stop_bit") 0 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ignore") 0 0) -(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "unknown") 0 0) +;; DFA descriptions of ia64 processors used for insn scheduling and +;; bundling. + +(automata_option "ndfa") + +;; Uncomment the following line to output automata for debugging. +;; (automata_option "v") + +(automata_option "w") + +;;(automata_option "no-minimization") + + +(include "itanium1.md") +(include "itanium2.md") + ;; :::::::::::::::::::: ;; :: @@ -342,29 +300,6 @@ operands[1] = op1; }) -;; This is used during early compilation to delay the decision on -;; how to refer to a variable as long as possible. This is especially -;; important between initial rtl generation and optimization for -;; deferred functions, since we may acquire additional information -;; on the variables used in the meantime. - -(define_insn_and_split "movsi_symbolic" - [(set (match_operand:SI 0 "register_operand" "=r") - (match_operand:SI 1 "symbolic_operand" "s")) - (clobber (match_scratch:DI 2 "=r")) - (use (reg:DI 1))] - "" - "* abort ();" - "!no_new_pseudos || reload_completed" - [(const_int 0)] -{ - rtx scratch = operands[2]; - if (!reload_completed) - scratch = gen_reg_rtx (Pmode); - ia64_expand_load_address (operands[0], operands[1], scratch); - DONE; -}) - (define_insn "*movsi_internal" [(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d") (match_operand:SI 1 "move_operand" "rO,J,i,m,rO,*f,rO,*f,*d,rK"))] @@ -394,53 +329,11 @@ operands[1] = op1; }) -;; This is used during early compilation to delay the decision on -;; how to refer to a variable as long as possible. This is especially -;; important between initial rtl generation and optimization for -;; deferred functions, since we may acquire additional information -;; on the variables used in the meantime. - -(define_insn_and_split "movdi_symbolic" - [(set (match_operand:DI 0 "register_operand" "=r") - (match_operand:DI 1 "symbolic_operand" "s")) - (clobber (match_scratch:DI 2 "=r")) - (use (reg:DI 1))] - "" - "* abort ();" - "!no_new_pseudos || reload_completed" - [(const_int 0)] -{ - rtx scratch = operands[2]; - if (!reload_completed) - scratch = gen_reg_rtx (Pmode); - ia64_expand_load_address (operands[0], operands[1], scratch); - DONE; -}) - -;; This is used as a placeholder for the return address during early -;; compilation. We won't know where we've placed this until during -;; reload, at which point it can wind up in b0, a general register, -;; or memory. The only safe destination under these conditions is a -;; general register. - -(define_insn_and_split "*movdi_ret_addr" - [(set (match_operand:DI 0 "register_operand" "=r") - (unspec:DI [(const_int 0)] UNSPEC_RET_ADDR))] - "" - "#" - "reload_completed" - [(const_int 0)] -{ - ia64_split_return_addr_rtx (operands[0]); - DONE; -} - [(set_attr "itanium_class" "ialu")]) - (define_insn "*movdi_internal" [(set (match_operand:DI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f,*f, Q, r,*b, r,*e, r,*d, r,*c") (match_operand:DI 1 "move_operand" - "rO,J,i,m,rO,*f,rO,*f, Q,*f,*b,rO,*e,rK,*d,rK,*c,rO"))] + "rO,JT,i,m,rO,*f,rO,*f, Q,*f,*b,rO,*e,rK,*d,rK,*c,rO"))] "ia64_move_ok (operands[0], operands[1])" { static const char * const alt[] = { @@ -473,12 +366,12 @@ [(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")]) (define_split - [(set (match_operand:DI 0 "register_operand" "") - (match_operand:DI 1 "symbolic_operand" ""))] + [(set (match_operand 0 "register_operand" "") + (match_operand 1 "symbolic_operand" ""))] "reload_completed && ! TARGET_NO_PIC" [(const_int 0)] { - ia64_expand_load_address (operands[0], operands[1], NULL_RTX); + ia64_expand_load_address (operands[0], operands[1]); DONE; }) @@ -525,16 +418,24 @@ operands[3] = pic_offset_table_rtx; }) -(define_expand "load_symptr" - [(set (match_operand:DI 2 "register_operand" "") - (plus:DI (high:DI (match_operand:DI 1 "got_symbolic_operand" "")) - (match_dup 3))) - (set (match_operand:DI 0 "register_operand" "") - (lo_sum:DI (match_dup 2) (match_dup 1)))] +;; This is used as a placeholder for the return address during early +;; compilation. We won't know where we've placed this until during +;; reload, at which point it can wind up in b0, a general register, +;; or memory. The only safe destination under these conditions is a +;; general register. + +(define_insn_and_split "*movdi_ret_addr" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(const_int 0)] UNSPEC_RET_ADDR))] "" + "#" + "reload_completed" + [(const_int 0)] { - operands[3] = pic_offset_table_rtx; -}) + ia64_split_return_addr_rtx (operands[0]); + DONE; +} + [(set_attr "itanium_class" "ialu")]) (define_insn "*load_symptr_high" [(set (match_operand:DI 0 "register_operand" "=r") @@ -688,11 +589,12 @@ [(set_attr "itanium_class" "ialu")]) ;; With no offsettable memory references, we've got to have a scratch -;; around to play with the second word. +;; around to play with the second word. However, in order to avoid a +;; reload nightmare we lie, claim we don't need one, and fix it up +;; in ia64_split_tmode_move. (define_expand "movti" - [(parallel [(set (match_operand:TI 0 "general_operand" "") - (match_operand:TI 1 "general_operand" "")) - (clobber (match_scratch:DI 2 ""))])] + [(set (match_operand:TI 0 "general_operand" "") + (match_operand:TI 1 "general_operand" ""))] "" { rtx op1 = ia64_expand_move (operands[0], operands[1]); @@ -703,106 +605,18 @@ (define_insn_and_split "*movti_internal" [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m") - (match_operand:TI 1 "general_operand" "ri,m,r")) - (clobber (match_scratch:DI 2 "=X,&r,&r"))] + (match_operand:TI 1 "general_operand" "ri,m,r"))] "ia64_move_ok (operands[0], operands[1])" "#" "reload_completed" [(const_int 0)] { - rtx adj1, adj2, in[2], out[2], insn; - int first; - - adj1 = ia64_split_timode (in, operands[1], operands[2]); - adj2 = ia64_split_timode (out, operands[0], operands[2]); - - first = 0; - if (reg_overlap_mentioned_p (out[0], in[1])) - { - if (reg_overlap_mentioned_p (out[1], in[0])) - abort (); - first = 1; - } - - if (adj1 && adj2) - abort (); - if (adj1) - emit_insn (adj1); - if (adj2) - emit_insn (adj2); - insn = emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first])); - if (GET_CODE (out[first]) == MEM - && GET_CODE (XEXP (out[first], 0)) == POST_MODIFY) - REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, - XEXP (XEXP (out[first], 0), 0), - REG_NOTES (insn)); - insn = emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first])); - if (GET_CODE (out[!first]) == MEM - && GET_CODE (XEXP (out[!first], 0)) == POST_MODIFY) - REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, - XEXP (XEXP (out[!first], 0), 0), - REG_NOTES (insn)); - DONE; -} - [(set_attr "itanium_class" "unknown") - (set_attr "predicable" "no")]) - -;; ??? SSA creates these. Can't allow memories since we don't have -;; the scratch register. Fortunately combine will know how to add -;; the clobber and scratch. -(define_insn_and_split "*movti_internal_reg" - [(set (match_operand:TI 0 "register_operand" "=r") - (match_operand:TI 1 "nonmemory_operand" "ri"))] - "" - "#" - "reload_completed" - [(const_int 0)] -{ - rtx in[2], out[2]; - int first; - - ia64_split_timode (in, operands[1], NULL_RTX); - ia64_split_timode (out, operands[0], NULL_RTX); - - first = 0; - if (reg_overlap_mentioned_p (out[0], in[1])) - { - if (reg_overlap_mentioned_p (out[1], in[0])) - abort (); - first = 1; - } - - emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first])); - emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first])); + ia64_split_tmode_move (operands); DONE; } [(set_attr "itanium_class" "unknown") (set_attr "predicable" "no")]) -(define_expand "reload_inti" - [(parallel [(set (match_operand:TI 0 "register_operand" "=r") - (match_operand:TI 1 "" "m")) - (clobber (match_operand:TI 2 "register_operand" "=&r"))])] - "" -{ - unsigned int s_regno = REGNO (operands[2]); - if (s_regno == REGNO (operands[0])) - s_regno += 1; - operands[2] = gen_rtx_REG (DImode, s_regno); -}) - -(define_expand "reload_outti" - [(parallel [(set (match_operand:TI 0 "" "=m") - (match_operand:TI 1 "register_operand" "r")) - (clobber (match_operand:TI 2 "register_operand" "=&r"))])] - "" -{ - unsigned int s_regno = REGNO (operands[2]); - if (s_regno == REGNO (operands[1])) - s_regno += 1; - operands[2] = gen_rtx_REG (DImode, s_regno); -}) - ;; Floating Point Moves ;; ;; Note - Patterns for SF mode moves are compulsory, but @@ -862,19 +676,19 @@ ;; With no offsettable memory references, we've got to have a scratch ;; around to play with the second word if the variable winds up in GRs. -(define_expand "movtf" - [(set (match_operand:TF 0 "general_operand" "") - (match_operand:TF 1 "general_operand" ""))] - "INTEL_EXTENDED_IEEE_FORMAT" +(define_expand "movxf" + [(set (match_operand:XF 0 "general_operand" "") + (match_operand:XF 1 "general_operand" ""))] + "" { - /* We must support TFmode loads into general registers for stdarg/vararg + /* We must support XFmode loads into general registers for stdarg/vararg and unprototyped calls. We split them into DImode loads for convenience. - We don't need TFmode stores from general regs, because a stdarg/vararg + We don't need XFmode stores from general regs, because a stdarg/vararg routine does a block store to memory of unnamed arguments. */ if (GET_CODE (operands[0]) == REG && GR_REGNO_P (REGNO (operands[0]))) { - /* We're hoping to transform everything that deals with TFmode + /* We're hoping to transform everything that deals with XFmode quantities and GR registers early in the compiler. */ if (no_new_pseudos) abort (); @@ -893,15 +707,15 @@ if (GET_CODE (operands[1]) == CONST_DOUBLE) { emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0])), - operand_subword (operands[1], 0, 0, TFmode)); + operand_subword (operands[1], 0, 0, XFmode)); emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0]) + 1), - operand_subword (operands[1], 1, 0, TFmode)); + operand_subword (operands[1], 1, 0, XFmode)); DONE; } /* If the quantity is in a register not known to be GR, spill it. */ - if (register_operand (operands[1], TFmode)) - operands[1] = spill_tfmode_operand (operands[1], 1); + if (register_operand (operands[1], XFmode)) + operands[1] = spill_xfmode_operand (operands[1], 1); if (GET_CODE (operands[1]) == MEM) { @@ -920,25 +734,53 @@ if (! reload_in_progress && ! reload_completed) { - operands[0] = spill_tfmode_operand (operands[0], 0); - operands[1] = spill_tfmode_operand (operands[1], 0); + operands[0] = spill_xfmode_operand (operands[0], 0); + operands[1] = spill_xfmode_operand (operands[1], 0); if (! ia64_move_ok (operands[0], operands[1])) - operands[1] = force_reg (TFmode, operands[1]); + operands[1] = force_reg (XFmode, operands[1]); } }) ;; ??? There's no easy way to mind volatile acquire/release semantics. -(define_insn "*movtf_internal" - [(set (match_operand:TF 0 "destination_tfmode_operand" "=f,f, m") - (match_operand:TF 1 "general_tfmode_operand" "fG,m,fG"))] - "INTEL_EXTENDED_IEEE_FORMAT && ia64_move_ok (operands[0], operands[1])" +(define_insn "*movxf_internal" + [(set (match_operand:XF 0 "destination_xfmode_operand" "=f,f, m") + (match_operand:XF 1 "general_xfmode_operand" "fG,m,fG"))] + "ia64_move_ok (operands[0], operands[1])" "@ mov %0 = %F1 ldfe %0 = %1%P1 stfe %0 = %F1%P0" [(set_attr "itanium_class" "fmisc,fld,stf")]) + +;; Better code generation via insns that deal with TFmode register pairs +;; directly. Same concerns apply as for TImode. +(define_expand "movtf" + [(set (match_operand:TF 0 "general_operand" "") + (match_operand:TF 1 "general_operand" ""))] + "" +{ + rtx op1 = ia64_expand_move (operands[0], operands[1]); + if (!op1) + DONE; + operands[1] = op1; +}) + +(define_insn_and_split "*movtf_internal" + [(set (match_operand:TF 0 "nonimmediate_operand" "=r,r,m") + (match_operand:TF 1 "general_operand" "ri,m,r"))] + "ia64_move_ok (operands[0], operands[1])" + "#" + "reload_completed" + [(const_int 0)] +{ + ia64_split_tmode_move (operands); + DONE; +} + [(set_attr "itanium_class" "unknown") + (set_attr "predicable" "no")]) + ;; :::::::::::::::::::: ;; :: @@ -1025,17 +867,17 @@ "fnorm.d %0 = %1" [(set_attr "itanium_class" "fmac")]) -(define_insn "extendsftf2" - [(set (match_operand:TF 0 "fr_register_operand" "=f") - (float_extend:TF (match_operand:SF 1 "fr_register_operand" "f")))] - "INTEL_EXTENDED_IEEE_FORMAT" +(define_insn "extendsfxf2" + [(set (match_operand:XF 0 "fr_register_operand" "=f") + (float_extend:XF (match_operand:SF 1 "fr_register_operand" "f")))] + "" "fnorm %0 = %1" [(set_attr "itanium_class" "fmac")]) -(define_insn "extenddftf2" - [(set (match_operand:TF 0 "fr_register_operand" "=f") - (float_extend:TF (match_operand:DF 1 "fr_register_operand" "f")))] - "INTEL_EXTENDED_IEEE_FORMAT" +(define_insn "extenddfxf2" + [(set (match_operand:XF 0 "fr_register_operand" "=f") + (float_extend:XF (match_operand:DF 1 "fr_register_operand" "f")))] + "" "fnorm %0 = %1" [(set_attr "itanium_class" "fmac")]) @@ -1046,45 +888,29 @@ "fnorm.s %0 = %1" [(set_attr "itanium_class" "fmac")]) -(define_insn "trunctfsf2" +(define_insn "truncxfsf2" [(set (match_operand:SF 0 "fr_register_operand" "=f") - (float_truncate:SF (match_operand:TF 1 "fr_register_operand" "f")))] - "INTEL_EXTENDED_IEEE_FORMAT" + (float_truncate:SF (match_operand:XF 1 "fr_register_operand" "f")))] + "" "fnorm.s %0 = %1" [(set_attr "itanium_class" "fmac")]) -(define_insn "trunctfdf2" +(define_insn "truncxfdf2" [(set (match_operand:DF 0 "fr_register_operand" "=f") - (float_truncate:DF (match_operand:TF 1 "fr_register_operand" "f")))] - "INTEL_EXTENDED_IEEE_FORMAT" + (float_truncate:DF (match_operand:XF 1 "fr_register_operand" "f")))] + "" "fnorm.d %0 = %1" [(set_attr "itanium_class" "fmac")]) ;; Convert between signed integer types and floating point. -(define_insn "floatditf2" - [(set (match_operand:TF 0 "fr_register_operand" "=f") - (float:TF (match_operand:DI 1 "fr_register_operand" "f")))] - "INTEL_EXTENDED_IEEE_FORMAT" +(define_insn "floatdixf2" + [(set (match_operand:XF 0 "fr_register_operand" "=f") + (float:XF (match_operand:DI 1 "fr_register_operand" "f")))] + "" "fcvt.xf %0 = %1" [(set_attr "itanium_class" "fcvtfx")]) -;; ??? Suboptimal. This should be split somehow. -(define_insn "floatdidf2" - [(set (match_operand:DF 0 "register_operand" "=f") - (float:DF (match_operand:DI 1 "register_operand" "f")))] - "!INTEL_EXTENDED_IEEE_FORMAT" - "fcvt.xf %0 = %1\;;;\;%,fnorm.d %0 = %0" - [(set_attr "itanium_class" "fcvtfx")]) - -;; ??? Suboptimal. This should be split somehow. -(define_insn "floatdisf2" - [(set (match_operand:SF 0 "register_operand" "=f") - (float:SF (match_operand:DI 1 "register_operand" "f")))] - "!INTEL_EXTENDED_IEEE_FORMAT" - "fcvt.xf %0 = %1\;;;\;%,fnorm.s %0 = %0" - [(set_attr "itanium_class" "fcvtfx")]) - (define_insn "fix_truncsfdi2" [(set (match_operand:DI 0 "fr_register_operand" "=f") (fix:DI (match_operand:SF 1 "fr_register_operand" "f")))] @@ -1099,18 +925,18 @@ "fcvt.fx.trunc %0 = %1" [(set_attr "itanium_class" "fcvtfx")]) -(define_insn "fix_trunctfdi2" +(define_insn "fix_truncxfdi2" [(set (match_operand:DI 0 "fr_register_operand" "=f") - (fix:DI (match_operand:TF 1 "fr_register_operand" "f")))] - "INTEL_EXTENDED_IEEE_FORMAT" + (fix:DI (match_operand:XF 1 "fr_register_operand" "f")))] + "" "fcvt.fx.trunc %0 = %1" [(set_attr "itanium_class" "fcvtfx")]) -(define_insn "fix_trunctfdi2_alts" +(define_insn "fix_truncxfdi2_alts" [(set (match_operand:DI 0 "fr_register_operand" "=f") - (fix:DI (match_operand:TF 1 "fr_register_operand" "f"))) + (fix:DI (match_operand:XF 1 "fr_register_operand" "f"))) (use (match_operand:SI 2 "const_int_operand" ""))] - "INTEL_EXTENDED_IEEE_FORMAT" + "" "fcvt.fx.trunc.s%2 %0 = %1" [(set_attr "itanium_class" "fcvtfx")]) @@ -1130,10 +956,10 @@ "fcvt.xuf.d %0 = %1" [(set_attr "itanium_class" "fcvtfx")]) -(define_insn "floatunsditf2" - [(set (match_operand:TF 0 "fr_register_operand" "=f") - (unsigned_float:TF (match_operand:DI 1 "fr_register_operand" "f")))] - "INTEL_EXTENDED_IEEE_FORMAT" +(define_insn "floatunsdixf2" + [(set (match_operand:XF 0 "fr_register_operand" "=f") + (unsigned_float:XF (match_operand:DI 1 "fr_register_operand" "f")))] + "" "fcvt.xuf %0 = %1" [(set_attr "itanium_class" "fcvtfx")]) @@ -1151,18 +977,18 @@ "fcvt.fxu.trunc %0 = %1" [(set_attr "itanium_class" "fcvtfx")]) -(define_insn "fixuns_trunctfdi2" +(define_insn "fixuns_truncxfdi2" [(set (match_operand:DI 0 "fr_register_operand" "=f") - (unsigned_fix:DI (match_operand:TF 1 "fr_register_operand" "f")))] - "INTEL_EXTENDED_IEEE_FORMAT" + (unsigned_fix:DI (match_operand:XF 1 "fr_register_operand" "f")))] + "" "fcvt.fxu.trunc %0 = %1" [(set_attr "itanium_class" "fcvtfx")]) -(define_insn "fixuns_trunctfdi2_alts" +(define_insn "fixuns_truncxfdi2_alts" [(set (match_operand:DI 0 "fr_register_operand" "=f") - (unsigned_fix:DI (match_operand:TF 1 "fr_register_operand" "f"))) + (unsigned_fix:DI (match_operand:XF 1 "fr_register_operand" "f"))) (use (match_operand:SI 2 "const_int_operand" ""))] - "INTEL_EXTENDED_IEEE_FORMAT" + "" "fcvt.fxu.trunc.s%2 %0 = %1" [(set_attr "itanium_class" "fcvtfx")]) @@ -2027,32 +1853,32 @@ [(set (match_operand:SI 0 "register_operand" "") (div:SI (match_operand:SI 1 "general_operand" "") (match_operand:SI 2 "general_operand" "")))] - "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV" + "TARGET_INLINE_INT_DIV" { - rtx op1_tf, op2_tf, op0_tf, op0_di, twon34; + rtx op1_xf, op2_xf, op0_xf, op0_di, twon34; REAL_VALUE_TYPE twon34_r; - op0_tf = gen_reg_rtx (TFmode); + op0_xf = gen_reg_rtx (XFmode); op0_di = gen_reg_rtx (DImode); if (CONSTANT_P (operands[1])) operands[1] = force_reg (SImode, operands[1]); - op1_tf = gen_reg_rtx (TFmode); - expand_float (op1_tf, operands[1], 0); + op1_xf = gen_reg_rtx (XFmode); + expand_float (op1_xf, operands[1], 0); if (CONSTANT_P (operands[2])) operands[2] = force_reg (SImode, operands[2]); - op2_tf = gen_reg_rtx (TFmode); - expand_float (op2_tf, operands[2], 0); + op2_xf = gen_reg_rtx (XFmode); + expand_float (op2_xf, operands[2], 0); /* 2^-34 */ real_2expN (&twon34_r, -34); - twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, TFmode); - twon34 = force_reg (TFmode, twon34); + twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, XFmode); + twon34 = force_reg (XFmode, twon34); - emit_insn (gen_divsi3_internal (op0_tf, op1_tf, op2_tf, twon34)); + emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34)); - emit_insn (gen_fix_trunctfdi2_alts (op0_di, op0_tf, const1_rtx)); + emit_insn (gen_fix_truncxfdi2_alts (op0_di, op0_xf, const1_rtx)); emit_move_insn (operands[0], gen_lowpart (SImode, op0_di)); DONE; }) @@ -2061,7 +1887,7 @@ [(set (match_operand:SI 0 "register_operand" "") (mod:SI (match_operand:SI 1 "general_operand" "") (match_operand:SI 2 "general_operand" "")))] - "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV" + "TARGET_INLINE_INT_DIV" { rtx op2_neg, op1_di, div; @@ -2084,32 +1910,32 @@ [(set (match_operand:SI 0 "register_operand" "") (udiv:SI (match_operand:SI 1 "general_operand" "") (match_operand:SI 2 "general_operand" "")))] - "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV" + "TARGET_INLINE_INT_DIV" { - rtx op1_tf, op2_tf, op0_tf, op0_di, twon34; + rtx op1_xf, op2_xf, op0_xf, op0_di, twon34; REAL_VALUE_TYPE twon34_r; - op0_tf = gen_reg_rtx (TFmode); + op0_xf = gen_reg_rtx (XFmode); op0_di = gen_reg_rtx (DImode); if (CONSTANT_P (operands[1])) operands[1] = force_reg (SImode, operands[1]); - op1_tf = gen_reg_rtx (TFmode); - expand_float (op1_tf, operands[1], 1); + op1_xf = gen_reg_rtx (XFmode); + expand_float (op1_xf, operands[1], 1); if (CONSTANT_P (operands[2])) operands[2] = force_reg (SImode, operands[2]); - op2_tf = gen_reg_rtx (TFmode); - expand_float (op2_tf, operands[2], 1); + op2_xf = gen_reg_rtx (XFmode); + expand_float (op2_xf, operands[2], 1); /* 2^-34 */ real_2expN (&twon34_r, -34); - twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, TFmode); - twon34 = force_reg (TFmode, twon34); + twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, XFmode); + twon34 = force_reg (XFmode, twon34); - emit_insn (gen_divsi3_internal (op0_tf, op1_tf, op2_tf, twon34)); + emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34)); - emit_insn (gen_fixuns_trunctfdi2_alts (op0_di, op0_tf, const1_rtx)); + emit_insn (gen_fixuns_truncxfdi2_alts (op0_di, op0_xf, const1_rtx)); emit_move_insn (operands[0], gen_lowpart (SImode, op0_di)); DONE; }) @@ -2118,7 +1944,7 @@ [(set (match_operand:SI 0 "register_operand" "") (umod:SI (match_operand:SI 1 "general_operand" "") (match_operand:SI 2 "general_operand" "")))] - "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV" + "TARGET_INLINE_INT_DIV" { rtx op2_neg, op1_di, div; @@ -2138,45 +1964,45 @@ }) (define_insn_and_split "divsi3_internal" - [(set (match_operand:TF 0 "fr_register_operand" "=&f") - (float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f") - (match_operand:TF 2 "fr_register_operand" "f")))) - (clobber (match_scratch:TF 4 "=&f")) - (clobber (match_scratch:TF 5 "=&f")) + [(set (match_operand:XF 0 "fr_register_operand" "=&f") + (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f") + (match_operand:XF 2 "fr_register_operand" "f")))) + (clobber (match_scratch:XF 4 "=&f")) + (clobber (match_scratch:XF 5 "=&f")) (clobber (match_scratch:BI 6 "=c")) - (use (match_operand:TF 3 "fr_register_operand" "f"))] - "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV" + (use (match_operand:XF 3 "fr_register_operand" "f"))] + "TARGET_INLINE_INT_DIV" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2))) + [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2))) (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)] UNSPEC_FR_RECIP_APPROX)) (use (const_int 1))]) (cond_exec (ne (match_dup 6) (const_int 0)) - (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0))) + (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0))) (use (const_int 1))])) (cond_exec (ne (match_dup 6) (const_int 0)) (parallel [(set (match_dup 5) - (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0))) + (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0))) (match_dup 7))) (use (const_int 1))])) (cond_exec (ne (match_dup 6) (const_int 0)) (parallel [(set (match_dup 4) - (plus:TF (mult:TF (match_dup 5) (match_dup 4)) + (plus:XF (mult:XF (match_dup 5) (match_dup 4)) (match_dup 4))) (use (const_int 1))])) (cond_exec (ne (match_dup 6) (const_int 0)) (parallel [(set (match_dup 5) - (plus:TF (mult:TF (match_dup 5) (match_dup 5)) + (plus:XF (mult:XF (match_dup 5) (match_dup 5)) (match_dup 3))) (use (const_int 1))])) (cond_exec (ne (match_dup 6) (const_int 0)) (parallel [(set (match_dup 0) - (plus:TF (mult:TF (match_dup 5) (match_dup 4)) + (plus:XF (mult:XF (match_dup 5) (match_dup 4)) (match_dup 4))) (use (const_int 1))])) ] - "operands[7] = CONST1_RTX (TFmode);" + "operands[7] = CONST1_RTX (XFmode);" [(set_attr "predicable" "no")]) ;; :::::::::::::::::::: @@ -2390,7 +2216,7 @@ (set (match_dup 2) (plus:DI (match_dup 1) (const_int -1))) (set (match_dup 5) (const_int 0)) (set (match_dup 3) (xor:DI (match_dup 1) (match_dup 2))) - (set (match_dup 4) (unspec:DI [(match_dup 3)] UNSPEC_POPCNT)) + (set (match_dup 4) (popcount:DI (match_dup 3))) (set (match_operand:DI 0 "gr_register_operand" "") (if_then_else:DI (ne (match_dup 6) (const_int 0)) (match_dup 5) (match_dup 4)))] @@ -2403,40 +2229,77 @@ operands[6] = gen_reg_rtx (BImode); }) -(define_insn "*popcnt" +(define_expand "ctzdi2" + [(set (match_dup 2) (plus:DI (match_operand:DI 1 "gr_register_operand" "") + (const_int -1))) + (set (match_dup 3) (not:DI (match_dup 1))) + (set (match_dup 4) (and:DI (match_dup 2) (match_dup 3))) + (set (match_operand:DI 0 "gr_register_operand" "") + (popcount:DI (match_dup 4)))] + "" +{ + operands[2] = gen_reg_rtx (DImode); + operands[3] = gen_reg_rtx (DImode); + operands[4] = gen_reg_rtx (DImode); +}) + +;; Note the computation here is op0 = 63 - (exp - 0xffff). +(define_expand "clzdi2" + [(set (match_dup 2) + (unsigned_float:XF (match_operand:DI 1 "fr_register_operand" ""))) + (set (match_dup 3) + (unspec:DI [(match_dup 2)] UNSPEC_GETF_EXP)) + (set (match_dup 4) (const_int 65598)) + (set (match_operand:DI 0 "gr_register_operand" "") + (minus:DI (match_dup 4) (match_dup 3)))] + "" +{ + operands[2] = gen_reg_rtx (XFmode); + operands[3] = gen_reg_rtx (DImode); + operands[4] = gen_reg_rtx (DImode); +}) + +(define_insn "popcountdi2" [(set (match_operand:DI 0 "gr_register_operand" "=r") - (unspec:DI [(match_operand:DI 1 "gr_register_operand" "r")] - UNSPEC_POPCNT))] + (popcount:DI (match_operand:DI 1 "gr_register_operand" "r")))] "" "popcnt %0 = %1" [(set_attr "itanium_class" "mmmul")]) +(define_insn "*getf_exp_xf" + [(set (match_operand:DI 0 "gr_register_operand" "=r") + (unspec:DI [(match_operand:XF 1 "fr_register_operand" "f")] + UNSPEC_GETF_EXP))] + "" + "getf.exp %0 = %1" + [(set_attr "itanium_class" "frfr")]) + (define_expand "divdi3" [(set (match_operand:DI 0 "register_operand" "") (div:DI (match_operand:DI 1 "general_operand" "") (match_operand:DI 2 "general_operand" "")))] - "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV" + "TARGET_INLINE_INT_DIV" { - rtx op1_tf, op2_tf, op0_tf; + rtx op1_xf, op2_xf, op0_xf; - op0_tf = gen_reg_rtx (TFmode); + op0_xf = gen_reg_rtx (XFmode); if (CONSTANT_P (operands[1])) operands[1] = force_reg (DImode, operands[1]); - op1_tf = gen_reg_rtx (TFmode); - expand_float (op1_tf, operands[1], 0); + op1_xf = gen_reg_rtx (XFmode); + expand_float (op1_xf, operands[1], 0); if (CONSTANT_P (operands[2])) operands[2] = force_reg (DImode, operands[2]); - op2_tf = gen_reg_rtx (TFmode); - expand_float (op2_tf, operands[2], 0); + op2_xf = gen_reg_rtx (XFmode); + expand_float (op2_xf, operands[2], 0); if (TARGET_INLINE_INT_DIV_LAT) - emit_insn (gen_divdi3_internal_lat (op0_tf, op1_tf, op2_tf)); + emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf)); else - emit_insn (gen_divdi3_internal_thr (op0_tf, op1_tf, op2_tf)); + emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf)); - emit_insn (gen_fix_trunctfdi2_alts (operands[0], op0_tf, const1_rtx)); + emit_insn (gen_fix_truncxfdi2_alts (operands[0], op0_xf, const1_rtx)); DONE; }) @@ -2444,7 +2307,7 @@ [(set (match_operand:DI 0 "register_operand" "") (mod:SI (match_operand:DI 1 "general_operand" "") (match_operand:DI 2 "general_operand" "")))] - "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV" + "TARGET_INLINE_INT_DIV" { rtx op2_neg, div; @@ -2461,28 +2324,28 @@ [(set (match_operand:DI 0 "register_operand" "") (udiv:DI (match_operand:DI 1 "general_operand" "") (match_operand:DI 2 "general_operand" "")))] - "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV" + "TARGET_INLINE_INT_DIV" { - rtx op1_tf, op2_tf, op0_tf; + rtx op1_xf, op2_xf, op0_xf; - op0_tf = gen_reg_rtx (TFmode); + op0_xf = gen_reg_rtx (XFmode); if (CONSTANT_P (operands[1])) operands[1] = force_reg (DImode, operands[1]); - op1_tf = gen_reg_rtx (TFmode); - expand_float (op1_tf, operands[1], 1); + op1_xf = gen_reg_rtx (XFmode); + expand_float (op1_xf, operands[1], 1); if (CONSTANT_P (operands[2])) operands[2] = force_reg (DImode, operands[2]); - op2_tf = gen_reg_rtx (TFmode); - expand_float (op2_tf, operands[2], 1); + op2_xf = gen_reg_rtx (XFmode); + expand_float (op2_xf, operands[2], 1); if (TARGET_INLINE_INT_DIV_LAT) - emit_insn (gen_divdi3_internal_lat (op0_tf, op1_tf, op2_tf)); + emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf)); else - emit_insn (gen_divdi3_internal_thr (op0_tf, op1_tf, op2_tf)); + emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf)); - emit_insn (gen_fixuns_trunctfdi2_alts (operands[0], op0_tf, const1_rtx)); + emit_insn (gen_fixuns_truncxfdi2_alts (operands[0], op0_xf, const1_rtx)); DONE; }) @@ -2490,7 +2353,7 @@ [(set (match_operand:DI 0 "register_operand" "") (umod:DI (match_operand:DI 1 "general_operand" "") (match_operand:DI 2 "general_operand" "")))] - "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV" + "TARGET_INLINE_INT_DIV" { rtx op2_neg, div; @@ -2504,112 +2367,112 @@ }) (define_insn_and_split "divdi3_internal_lat" - [(set (match_operand:TF 0 "fr_register_operand" "=&f") - (float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f") - (match_operand:TF 2 "fr_register_operand" "f")))) - (clobber (match_scratch:TF 3 "=&f")) - (clobber (match_scratch:TF 4 "=&f")) - (clobber (match_scratch:TF 5 "=&f")) + [(set (match_operand:XF 0 "fr_register_operand" "=&f") + (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f") + (match_operand:XF 2 "fr_register_operand" "f")))) + (clobber (match_scratch:XF 3 "=&f")) + (clobber (match_scratch:XF 4 "=&f")) + (clobber (match_scratch:XF 5 "=&f")) (clobber (match_scratch:BI 6 "=c"))] - "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV_LAT" + "TARGET_INLINE_INT_DIV_LAT" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2))) + [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2))) (set (match_dup 6) (unspec:BI [(match_dup 1) (match_dup 2)] UNSPEC_FR_RECIP_APPROX)) (use (const_int 1))]) (cond_exec (ne (match_dup 6) (const_int 0)) (parallel [(set (match_dup 3) - (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0))) + (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0))) (match_dup 7))) (use (const_int 1))])) (cond_exec (ne (match_dup 6) (const_int 0)) - (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0))) + (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0))) (use (const_int 1))])) (cond_exec (ne (match_dup 6) (const_int 0)) - (parallel [(set (match_dup 5) (mult:TF (match_dup 3) (match_dup 3))) + (parallel [(set (match_dup 5) (mult:XF (match_dup 3) (match_dup 3))) (use (const_int 1))])) (cond_exec (ne (match_dup 6) (const_int 0)) (parallel [(set (match_dup 4) - (plus:TF (mult:TF (match_dup 3) (match_dup 4)) + (plus:XF (mult:XF (match_dup 3) (match_dup 4)) (match_dup 4))) (use (const_int 1))])) (cond_exec (ne (match_dup 6) (const_int 0)) (parallel [(set (match_dup 0) - (plus:TF (mult:TF (match_dup 3) (match_dup 0)) + (plus:XF (mult:XF (match_dup 3) (match_dup 0)) (match_dup 0))) (use (const_int 1))])) (cond_exec (ne (match_dup 6) (const_int 0)) (parallel [(set (match_dup 3) - (plus:TF (mult:TF (match_dup 5) (match_dup 4)) + (plus:XF (mult:XF (match_dup 5) (match_dup 4)) (match_dup 4))) (use (const_int 1))])) (cond_exec (ne (match_dup 6) (const_int 0)) (parallel [(set (match_dup 0) - (plus:TF (mult:TF (match_dup 5) (match_dup 0)) + (plus:XF (mult:XF (match_dup 5) (match_dup 0)) (match_dup 0))) (use (const_int 1))])) (cond_exec (ne (match_dup 6) (const_int 0)) (parallel [(set (match_dup 4) - (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3))) + (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3))) (match_dup 1))) (use (const_int 1))])) (cond_exec (ne (match_dup 6) (const_int 0)) (parallel [(set (match_dup 0) - (plus:TF (mult:TF (match_dup 4) (match_dup 0)) + (plus:XF (mult:XF (match_dup 4) (match_dup 0)) (match_dup 3))) (use (const_int 1))])) ] - "operands[7] = CONST1_RTX (TFmode);" + "operands[7] = CONST1_RTX (XFmode);" [(set_attr "predicable" "no")]) (define_insn_and_split "divdi3_internal_thr" - [(set (match_operand:TF 0 "fr_register_operand" "=&f") - (float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f") - (match_operand:TF 2 "fr_register_operand" "f")))) - (clobber (match_scratch:TF 3 "=&f")) - (clobber (match_scratch:TF 4 "=f")) + [(set (match_operand:XF 0 "fr_register_operand" "=&f") + (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f") + (match_operand:XF 2 "fr_register_operand" "f")))) + (clobber (match_scratch:XF 3 "=&f")) + (clobber (match_scratch:XF 4 "=f")) (clobber (match_scratch:BI 5 "=c"))] - "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV_THR" + "TARGET_INLINE_INT_DIV_THR" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2))) + [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2))) (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)] UNSPEC_FR_RECIP_APPROX)) (use (const_int 1))]) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 3) - (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0))) + (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0))) (match_dup 6))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 0) - (plus:TF (mult:TF (match_dup 3) (match_dup 0)) + (plus:XF (mult:XF (match_dup 3) (match_dup 0)) (match_dup 0))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) - (parallel [(set (match_dup 3) (mult:TF (match_dup 3) (match_dup 3))) + (parallel [(set (match_dup 3) (mult:XF (match_dup 3) (match_dup 3))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 0) - (plus:TF (mult:TF (match_dup 3) (match_dup 0)) + (plus:XF (mult:XF (match_dup 3) (match_dup 0)) (match_dup 0))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) - (parallel [(set (match_dup 3) (mult:TF (match_dup 0) (match_dup 1))) + (parallel [(set (match_dup 3) (mult:XF (match_dup 0) (match_dup 1))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 4) - (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3))) + (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3))) (match_dup 1))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 0) - (plus:TF (mult:TF (match_dup 4) (match_dup 0)) + (plus:XF (mult:XF (match_dup 4) (match_dup 0)) (match_dup 3))) (use (const_int 1))])) ] - "operands[6] = CONST1_RTX (TFmode);" + "operands[6] = CONST1_RTX (XFmode);" [(set_attr "predicable" "no")]) ;; :::::::::::::::::::: @@ -2721,7 +2584,7 @@ [(set (match_operand:SF 0 "fr_register_operand" "") (div:SF (match_operand:SF 1 "fr_register_operand" "") (match_operand:SF 2 "fr_register_operand" "")))] - "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV" + "TARGET_INLINE_FLOAT_DIV" { rtx insn; if (TARGET_INLINE_FLOAT_DIV_LAT) @@ -2736,44 +2599,44 @@ [(set (match_operand:SF 0 "fr_register_operand" "=&f") (div:SF (match_operand:SF 1 "fr_register_operand" "f") (match_operand:SF 2 "fr_register_operand" "f"))) - (clobber (match_scratch:TF 3 "=&f")) - (clobber (match_scratch:TF 4 "=f")) + (clobber (match_scratch:XF 3 "=&f")) + (clobber (match_scratch:XF 4 "=f")) (clobber (match_scratch:BI 5 "=c"))] - "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_LAT" + "TARGET_INLINE_FLOAT_DIV_LAT" "#" "&& reload_completed" - [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8))) + [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8))) (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)] UNSPEC_FR_RECIP_APPROX)) (use (const_int 1))]) (cond_exec (ne (match_dup 5) (const_int 0)) - (parallel [(set (match_dup 3) (mult:TF (match_dup 7) (match_dup 6))) + (parallel [(set (match_dup 3) (mult:XF (match_dup 7) (match_dup 6))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 4) - (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6))) + (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 6))) (match_dup 10))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 3) - (plus:TF (mult:TF (match_dup 4) (match_dup 3)) + (plus:XF (mult:XF (match_dup 4) (match_dup 3)) (match_dup 3))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) - (parallel [(set (match_dup 4) (mult:TF (match_dup 4) (match_dup 4))) + (parallel [(set (match_dup 4) (mult:XF (match_dup 4) (match_dup 4))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 3) - (plus:TF (mult:TF (match_dup 4) (match_dup 3)) + (plus:XF (mult:XF (match_dup 4) (match_dup 3)) (match_dup 3))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) - (parallel [(set (match_dup 4) (mult:TF (match_dup 4) (match_dup 4))) + (parallel [(set (match_dup 4) (mult:XF (match_dup 4) (match_dup 4))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 9) (float_truncate:DF - (plus:TF (mult:TF (match_dup 4) (match_dup 3)) + (plus:XF (mult:XF (match_dup 4) (match_dup 3)) (match_dup 3)))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) @@ -2781,11 +2644,11 @@ (float_truncate:SF (match_dup 6)))) ] { - operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0])); - operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1])); - operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2])); + operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0])); + operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1])); + operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2])); operands[9] = gen_rtx_REG (DFmode, REGNO (operands[0])); - operands[10] = CONST1_RTX (TFmode); + operands[10] = CONST1_RTX (XFmode); } [(set_attr "predicable" "no")]) @@ -2793,53 +2656,202 @@ [(set (match_operand:SF 0 "fr_register_operand" "=&f") (div:SF (match_operand:SF 1 "fr_register_operand" "f") (match_operand:SF 2 "fr_register_operand" "f"))) - (clobber (match_scratch:TF 3 "=&f")) - (clobber (match_scratch:TF 4 "=f")) + (clobber (match_scratch:XF 3 "=&f")) + (clobber (match_scratch:XF 4 "=f")) (clobber (match_scratch:BI 5 "=c"))] - "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_THR" + "TARGET_INLINE_FLOAT_DIV_THR" "#" "&& reload_completed" - [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8))) + [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8))) (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)] UNSPEC_FR_RECIP_APPROX)) (use (const_int 1))]) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 3) - (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6))) + (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 6))) (match_dup 10))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 3) - (plus:TF (mult:TF (match_dup 3) (match_dup 3)) + (plus:XF (mult:XF (match_dup 3) (match_dup 3)) (match_dup 3))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 6) - (plus:TF (mult:TF (match_dup 3) (match_dup 6)) + (plus:XF (mult:XF (match_dup 3) (match_dup 6)) (match_dup 6))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 9) (float_truncate:SF - (mult:TF (match_dup 7) (match_dup 6)))) + (mult:XF (match_dup 7) (match_dup 6)))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 4) - (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 3))) + (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 3))) (match_dup 7))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (set (match_dup 0) (float_truncate:SF - (plus:TF (mult:TF (match_dup 4) (match_dup 6)) + (plus:XF (mult:XF (match_dup 4) (match_dup 6)) (match_dup 3))))) ] { - operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0])); - operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1])); - operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2])); + operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0])); + operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1])); + operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2])); operands[9] = gen_rtx_REG (SFmode, REGNO (operands[3])); - operands[10] = CONST1_RTX (TFmode); + operands[10] = CONST1_RTX (XFmode); +} + [(set_attr "predicable" "no")]) + +;; Inline square root. + +(define_insn "*sqrt_approx" + [(set (match_operand:XF 0 "fr_register_operand" "=f") + (div:XF (const_int 1) + (sqrt:XF (match_operand:XF 2 "fr_register_operand" "f")))) + (set (match_operand:BI 1 "register_operand" "=c") + (unspec:BI [(match_dup 2)] UNSPEC_FR_SQRT_RECIP_APPROX)) + (use (match_operand:SI 3 "const_int_operand" "")) ] + "" + "frsqrta.s%3 %0, %1 = %2" + [(set_attr "itanium_class" "fmisc") + (set_attr "predicable" "no")]) + +(define_insn "*setf_exp_xf" + [(set (match_operand:XF 0 "fr_register_operand" "=f") + (unspec:XF [(match_operand:DI 1 "register_operand" "r")] + UNSPEC_SETF_EXP))] + "" + "setf.exp %0 = %1" + [(set_attr "itanium_class" "frfr")]) + +(define_expand "sqrtsf2" + [(set (match_operand:SF 0 "fr_register_operand" "=&f") + (sqrt:SF (match_operand:SF 1 "fr_register_operand" "f")))] + "TARGET_INLINE_SQRT" +{ + rtx insn; + if (TARGET_INLINE_SQRT_LAT) +#if 0 + insn = gen_sqrtsf2_internal_lat (operands[0], operands[1]); +#else + abort (); +#endif + else + insn = gen_sqrtsf2_internal_thr (operands[0], operands[1]); + emit_insn (insn); + DONE; +}) + +;; Latency-optimized square root. +;; FIXME: Implement. + +;; Throughput-optimized square root. + +(define_insn_and_split "sqrtsf2_internal_thr" + [(set (match_operand:SF 0 "fr_register_operand" "=&f") + (sqrt:SF (match_operand:SF 1 "fr_register_operand" "f"))) + ;; Register r2 in optimization guide. + (clobber (match_scratch:DI 2 "=r")) + ;; Register f8 in optimization guide + (clobber (match_scratch:XF 3 "=&f")) + ;; Register f9 in optimization guide + (clobber (match_scratch:XF 4 "=&f")) + ;; Register f10 in optimization guide + (clobber (match_scratch:XF 5 "=&f")) + ;; Register p6 in optimization guide. + (clobber (match_scratch:BI 6 "=c"))] + "TARGET_INLINE_SQRT_THR" + "#" + "&& reload_completed" + [ ;; exponent of +1/2 in r2 + (set (match_dup 2) (const_int 65534)) + ;; +1/2 in f8 + (set (match_dup 3) + (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP)) + ;; Step 1 + ;; y0 = 1/sqrt(a) in f7 + (parallel [(set (match_dup 7) + (div:XF (const_int 1) + (sqrt:XF (match_dup 8)))) + (set (match_dup 6) + (unspec:BI [(match_dup 8)] + UNSPEC_FR_SQRT_RECIP_APPROX)) + (use (const_int 0))]) + ;; Step 2 + ;; H0 = 1/2 * y0 in f9 + (cond_exec (ne (match_dup 6) (const_int 0)) + (parallel [(set (match_dup 4) + (plus:XF (mult:XF (match_dup 3) (match_dup 7)) + (match_dup 9))) + (use (const_int 1))])) + ;; Step 3 + ;; S0 = a * y0 in f7 + (cond_exec (ne (match_dup 6) (const_int 0)) + (parallel [(set (match_dup 7) + (plus:XF (mult:XF (match_dup 8) (match_dup 7)) + (match_dup 9))) + (use (const_int 1))])) + ;; Step 4 + ;; d = 1/2 - S0 * H0 in f10 + (cond_exec (ne (match_dup 6) (const_int 0)) + (parallel [(set (match_dup 5) + (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 4))) + (match_dup 3))) + (use (const_int 1))])) + ;; Step 5 + ;; d' = d + 1/2 * d in f8 + (cond_exec (ne (match_dup 6) (const_int 0)) + (parallel [(set (match_dup 3) + (plus:XF (mult:XF (match_dup 3) (match_dup 5)) + (match_dup 5))) + (use (const_int 1))])) + ;; Step 6 + ;; e = d + d * d' in f8 + (cond_exec (ne (match_dup 6) (const_int 0)) + (parallel [(set (match_dup 3) + (plus:XF (mult:XF (match_dup 5) (match_dup 3)) + (match_dup 5))) + (use (const_int 1))])) + ;; Step 7 + ;; S1 = S0 + e * S0 in f7 + (cond_exec (ne (match_dup 6) (const_int 0)) + (parallel [(set (match_dup 0) + (float_truncate:SF + (plus:XF (mult:XF (match_dup 3) (match_dup 7)) + (match_dup 7)))) + (use (const_int 1))])) + ;; Step 8 + ;; H1 = H0 + e * H0 in f8 + (cond_exec (ne (match_dup 6) (const_int 0)) + (parallel [(set (match_dup 3) + (plus:XF (mult:XF (match_dup 3) (match_dup 4)) + (match_dup 4))) + (use (const_int 1))])) + ;; Step 9 + ;; d1 = a - S1 * S1 in f9 + (cond_exec (ne (match_dup 6) (const_int 0)) + (parallel [(set (match_dup 4) + (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 7))) + (match_dup 8))) + (use (const_int 1))])) + ;; Step 10 + ;; S = S1 + d1 * H1 in f7 + (cond_exec (ne (match_dup 6) (const_int 0)) + (parallel [(set (match_dup 0) + (float_truncate:SF + (plus:XF (mult:XF (match_dup 4) (match_dup 3)) + (match_dup 7)))) + (use (const_int 0))]))] +{ + /* Generate 82-bit versions of the input and output operands. */ + operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0])); + operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1])); + /* Generate required floating-point constants. */ + operands[9] = CONST0_RTX (XFmode); } [(set_attr "predicable" "no")]) @@ -3030,7 +3042,7 @@ [(set (match_operand:DF 0 "fr_register_operand" "") (div:DF (match_operand:DF 1 "fr_register_operand" "") (match_operand:DF 2 "fr_register_operand" "")))] - "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV" + "TARGET_INLINE_FLOAT_DIV" { rtx insn; if (TARGET_INLINE_FLOAT_DIV_LAT) @@ -3045,80 +3057,80 @@ [(set (match_operand:DF 0 "fr_register_operand" "=&f") (div:DF (match_operand:DF 1 "fr_register_operand" "f") (match_operand:DF 2 "fr_register_operand" "f"))) - (clobber (match_scratch:TF 3 "=&f")) - (clobber (match_scratch:TF 4 "=&f")) - (clobber (match_scratch:TF 5 "=&f")) + (clobber (match_scratch:XF 3 "=&f")) + (clobber (match_scratch:XF 4 "=&f")) + (clobber (match_scratch:XF 5 "=&f")) (clobber (match_scratch:BI 6 "=c"))] - "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_LAT" + "TARGET_INLINE_FLOAT_DIV_LAT" "#" "&& reload_completed" - [(parallel [(set (match_dup 7) (div:TF (const_int 1) (match_dup 9))) + [(parallel [(set (match_dup 7) (div:XF (const_int 1) (match_dup 9))) (set (match_dup 6) (unspec:BI [(match_dup 8) (match_dup 9)] UNSPEC_FR_RECIP_APPROX)) (use (const_int 1))]) (cond_exec (ne (match_dup 6) (const_int 0)) - (parallel [(set (match_dup 3) (mult:TF (match_dup 8) (match_dup 7))) + (parallel [(set (match_dup 3) (mult:XF (match_dup 8) (match_dup 7))) (use (const_int 1))])) (cond_exec (ne (match_dup 6) (const_int 0)) (parallel [(set (match_dup 4) - (plus:TF (neg:TF (mult:TF (match_dup 9) (match_dup 7))) + (plus:XF (neg:XF (mult:XF (match_dup 9) (match_dup 7))) (match_dup 12))) (use (const_int 1))])) (cond_exec (ne (match_dup 6) (const_int 0)) (parallel [(set (match_dup 3) - (plus:TF (mult:TF (match_dup 4) (match_dup 3)) + (plus:XF (mult:XF (match_dup 4) (match_dup 3)) (match_dup 3))) (use (const_int 1))])) (cond_exec (ne (match_dup 6) (const_int 0)) - (parallel [(set (match_dup 5) (mult:TF (match_dup 4) (match_dup 4))) + (parallel [(set (match_dup 5) (mult:XF (match_dup 4) (match_dup 4))) (use (const_int 1))])) (cond_exec (ne (match_dup 6) (const_int 0)) (parallel [(set (match_dup 7) - (plus:TF (mult:TF (match_dup 4) (match_dup 7)) + (plus:XF (mult:XF (match_dup 4) (match_dup 7)) (match_dup 7))) (use (const_int 1))])) (cond_exec (ne (match_dup 6) (const_int 0)) (parallel [(set (match_dup 3) - (plus:TF (mult:TF (match_dup 5) (match_dup 3)) + (plus:XF (mult:XF (match_dup 5) (match_dup 3)) (match_dup 3))) (use (const_int 1))])) (cond_exec (ne (match_dup 6) (const_int 0)) - (parallel [(set (match_dup 4) (mult:TF (match_dup 5) (match_dup 5))) + (parallel [(set (match_dup 4) (mult:XF (match_dup 5) (match_dup 5))) (use (const_int 1))])) (cond_exec (ne (match_dup 6) (const_int 0)) (parallel [(set (match_dup 7) - (plus:TF (mult:TF (match_dup 5) (match_dup 7)) + (plus:XF (mult:XF (match_dup 5) (match_dup 7)) (match_dup 7))) (use (const_int 1))])) (cond_exec (ne (match_dup 6) (const_int 0)) (parallel [(set (match_dup 10) (float_truncate:DF - (plus:TF (mult:TF (match_dup 4) (match_dup 3)) + (plus:XF (mult:XF (match_dup 4) (match_dup 3)) (match_dup 3)))) (use (const_int 1))])) (cond_exec (ne (match_dup 6) (const_int 0)) (parallel [(set (match_dup 7) - (plus:TF (mult:TF (match_dup 4) (match_dup 7)) + (plus:XF (mult:XF (match_dup 4) (match_dup 7)) (match_dup 7))) (use (const_int 1))])) (cond_exec (ne (match_dup 6) (const_int 0)) (parallel [(set (match_dup 11) (float_truncate:DF - (plus:TF (neg:TF (mult:TF (match_dup 9) (match_dup 3))) + (plus:XF (neg:XF (mult:XF (match_dup 9) (match_dup 3))) (match_dup 8)))) (use (const_int 1))])) (cond_exec (ne (match_dup 6) (const_int 0)) (set (match_dup 0) - (float_truncate:DF (plus:TF (mult:TF (match_dup 5) (match_dup 7)) + (float_truncate:DF (plus:XF (mult:XF (match_dup 5) (match_dup 7)) (match_dup 3))))) ] { - operands[7] = gen_rtx_REG (TFmode, REGNO (operands[0])); - operands[8] = gen_rtx_REG (TFmode, REGNO (operands[1])); - operands[9] = gen_rtx_REG (TFmode, REGNO (operands[2])); + operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0])); + operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1])); + operands[9] = gen_rtx_REG (XFmode, REGNO (operands[2])); operands[10] = gen_rtx_REG (DFmode, REGNO (operands[3])); operands[11] = gen_rtx_REG (DFmode, REGNO (operands[5])); - operands[12] = CONST1_RTX (TFmode); + operands[12] = CONST1_RTX (XFmode); } [(set_attr "predicable" "no")]) @@ -3126,48 +3138,48 @@ [(set (match_operand:DF 0 "fr_register_operand" "=&f") (div:DF (match_operand:DF 1 "fr_register_operand" "f") (match_operand:DF 2 "fr_register_operand" "f"))) - (clobber (match_scratch:TF 3 "=&f")) + (clobber (match_scratch:XF 3 "=&f")) (clobber (match_scratch:DF 4 "=f")) (clobber (match_scratch:BI 5 "=c"))] - "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_THR" + "TARGET_INLINE_FLOAT_DIV_THR" "#" "&& reload_completed" - [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8))) + [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8))) (set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)] UNSPEC_FR_RECIP_APPROX)) (use (const_int 1))]) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 3) - (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6))) + (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 6))) (match_dup 10))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 6) - (plus:TF (mult:TF (match_dup 3) (match_dup 6)) + (plus:XF (mult:XF (match_dup 3) (match_dup 6)) (match_dup 6))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 3) - (mult:TF (match_dup 3) (match_dup 3))) + (mult:XF (match_dup 3) (match_dup 3))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 6) - (plus:TF (mult:TF (match_dup 3) (match_dup 6)) + (plus:XF (mult:XF (match_dup 3) (match_dup 6)) (match_dup 6))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 3) - (mult:TF (match_dup 3) (match_dup 3))) + (mult:XF (match_dup 3) (match_dup 3))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 6) - (plus:TF (mult:TF (match_dup 3) (match_dup 6)) + (plus:XF (mult:XF (match_dup 3) (match_dup 6)) (match_dup 6))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 9) (float_truncate:DF - (mult:TF (match_dup 7) (match_dup 3)))) + (mult:XF (match_dup 7) (match_dup 3)))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 4) @@ -3180,11 +3192,160 @@ (match_dup 9)))) ] { - operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0])); - operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1])); - operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2])); + operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0])); + operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1])); + operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2])); operands[9] = gen_rtx_REG (DFmode, REGNO (operands[3])); - operands[10] = CONST1_RTX (TFmode); + operands[10] = CONST1_RTX (XFmode); +} + [(set_attr "predicable" "no")]) + +;; Inline square root. + +(define_expand "sqrtdf2" + [(set (match_operand:DF 0 "fr_register_operand" "=&f") + (sqrt:DF (match_operand:DF 1 "fr_register_operand" "f")))] + "TARGET_INLINE_SQRT" +{ + rtx insn; + if (TARGET_INLINE_SQRT_LAT) +#if 0 + insn = gen_sqrtdf2_internal_lat (operands[0], operands[1]); +#else + abort (); +#endif + else + insn = gen_sqrtdf2_internal_thr (operands[0], operands[1]); + emit_insn (insn); + DONE; +}) + +;; Latency-optimized square root. +;; FIXME: Implement. + +;; Throughput-optimized square root. + +(define_insn_and_split "sqrtdf2_internal_thr" + [(set (match_operand:DF 0 "fr_register_operand" "=&f") + (sqrt:DF (match_operand:DF 1 "fr_register_operand" "f"))) + ;; Register r2 in optimization guide. + (clobber (match_scratch:DI 2 "=r")) + ;; Register f8 in optimization guide + (clobber (match_scratch:XF 3 "=&f")) + ;; Register f9 in optimization guide + (clobber (match_scratch:XF 4 "=&f")) + ;; Register f10 in optimization guide + (clobber (match_scratch:XF 5 "=&f")) + ;; Register p6 in optimization guide. + (clobber (match_scratch:BI 6 "=c"))] + "TARGET_INLINE_SQRT_THR" + "#" + "&& reload_completed" + [ ;; exponent of +1/2 in r2 + (set (match_dup 2) (const_int 65534)) + ;; +1/2 in f10 + (set (match_dup 5) + (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP)) + ;; Step 1 + ;; y0 = 1/sqrt(a) in f7 + (parallel [(set (match_dup 7) + (div:XF (const_int 1) + (sqrt:XF (match_dup 8)))) + (set (match_dup 6) + (unspec:BI [(match_dup 8)] + UNSPEC_FR_SQRT_RECIP_APPROX)) + (use (const_int 0))]) + ;; Step 2 + ;; H0 = 1/2 * y0 in f8 + (cond_exec (ne (match_dup 6) (const_int 0)) + (parallel [(set (match_dup 3) + (plus:XF (mult:XF (match_dup 5) (match_dup 7)) + (match_dup 9))) + (use (const_int 1))])) + ;; Step 3 + ;; G0 = a * y0 in f7 + (cond_exec (ne (match_dup 6) (const_int 0)) + (parallel [(set (match_dup 7) + (plus:XF (mult:XF (match_dup 8) (match_dup 7)) + (match_dup 9))) + (use (const_int 1))])) + ;; Step 4 + ;; r0 = 1/2 - G0 * H0 in f9 + (cond_exec (ne (match_dup 6) (const_int 0)) + (parallel [(set (match_dup 4) + (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 3))) + (match_dup 5))) + (use (const_int 1))])) + ;; Step 5 + ;; H1 = H0 + r0 * H0 in f8 + (cond_exec (ne (match_dup 6) (const_int 0)) + (parallel [(set (match_dup 3) + (plus:XF (mult:XF (match_dup 4) (match_dup 3)) + (match_dup 3))) + (use (const_int 1))])) + ;; Step 6 + ;; G1 = G0 + r0 * G0 in f7 + (cond_exec (ne (match_dup 6) (const_int 0)) + (parallel [(set (match_dup 7) + (plus:XF (mult:XF (match_dup 4) (match_dup 7)) + (match_dup 7))) + (use (const_int 1))])) + ;; Step 7 + ;; r1 = 1/2 - G1 * H1 in f9 + (cond_exec (ne (match_dup 6) (const_int 0)) + (parallel [(set (match_dup 4) + (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 3))) + (match_dup 5))) + (use (const_int 1))])) + ;; Step 8 + ;; H2 = H1 + r1 * H1 in f8 + (cond_exec (ne (match_dup 6) (const_int 0)) + (parallel [(set (match_dup 3) + (plus:XF (mult:XF (match_dup 4) (match_dup 3)) + (match_dup 3))) + (use (const_int 1))])) + ;; Step 9 + ;; G2 = G1 + r1 * G1 in f7 + (cond_exec (ne (match_dup 6) (const_int 0)) + (parallel [(set (match_dup 7) + (plus:XF (mult:XF (match_dup 4) (match_dup 7)) + (match_dup 7))) + (use (const_int 1))])) + ;; Step 10 + ;; d2 = a - G2 * G2 in f9 + (cond_exec (ne (match_dup 6) (const_int 0)) + (parallel [(set (match_dup 4) + (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 7))) + (match_dup 8))) + (use (const_int 1))])) + ;; Step 11 + ;; G3 = G2 + d2 * H2 in f7 + (cond_exec (ne (match_dup 6) (const_int 0)) + (parallel [(set (match_dup 7) + (plus:XF (mult:XF (match_dup 4) (match_dup 3)) + (match_dup 7))) + (use (const_int 1))])) + ;; Step 12 + ;; d3 = a - G3 * G3 in f9 + (cond_exec (ne (match_dup 6) (const_int 0)) + (parallel [(set (match_dup 4) + (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 7))) + (match_dup 8))) + (use (const_int 1))])) + ;; Step 13 + ;; S = G3 + d3 * H2 in f7 + (cond_exec (ne (match_dup 6) (const_int 0)) + (parallel [(set (match_dup 0) + (float_truncate:DF + (plus:XF (mult:XF (match_dup 4) (match_dup 3)) + (match_dup 7)))) + (use (const_int 0))]))] +{ + /* Generate 82-bit versions of the input and output operands. */ + operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0])); + operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1])); + /* Generate required floating-point constants. */ + operands[9] = CONST0_RTX (XFmode); } [(set_attr "predicable" "no")]) @@ -3194,499 +3355,674 @@ ;; :: ;; :::::::::::::::::::: -(define_insn "addtf3" - [(set (match_operand:TF 0 "fr_register_operand" "=f") - (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))] - "INTEL_EXTENDED_IEEE_FORMAT" +(define_insn "addxf3" + [(set (match_operand:XF 0 "fr_register_operand" "=f") + (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))] + "" "fadd %0 = %F1, %F2" [(set_attr "itanium_class" "fmac")]) -(define_insn "*addtf3_truncsf" +(define_insn "*addxf3_truncsf" [(set (match_operand:SF 0 "fr_register_operand" "=f") (float_truncate:SF - (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))] - "INTEL_EXTENDED_IEEE_FORMAT" + (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))] + "" "fadd.s %0 = %F1, %F2" [(set_attr "itanium_class" "fmac")]) -(define_insn "*addtf3_truncdf" +(define_insn "*addxf3_truncdf" [(set (match_operand:DF 0 "fr_register_operand" "=f") (float_truncate:DF - (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))] - "INTEL_EXTENDED_IEEE_FORMAT" + (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))] + "" "fadd.d %0 = %F1, %F2" [(set_attr "itanium_class" "fmac")]) -(define_insn "subtf3" - [(set (match_operand:TF 0 "fr_register_operand" "=f") - (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))] - "INTEL_EXTENDED_IEEE_FORMAT" +(define_insn "subxf3" + [(set (match_operand:XF 0 "fr_register_operand" "=f") + (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))] + "" "fsub %0 = %F1, %F2" [(set_attr "itanium_class" "fmac")]) -(define_insn "*subtf3_truncsf" +(define_insn "*subxf3_truncsf" [(set (match_operand:SF 0 "fr_register_operand" "=f") (float_truncate:SF - (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))] - "INTEL_EXTENDED_IEEE_FORMAT" + (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))] + "" "fsub.s %0 = %F1, %F2" [(set_attr "itanium_class" "fmac")]) -(define_insn "*subtf3_truncdf" +(define_insn "*subxf3_truncdf" [(set (match_operand:DF 0 "fr_register_operand" "=f") (float_truncate:DF - (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))] - "INTEL_EXTENDED_IEEE_FORMAT" + (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))] + "" "fsub.d %0 = %F1, %F2" [(set_attr "itanium_class" "fmac")]) -(define_insn "multf3" - [(set (match_operand:TF 0 "fr_register_operand" "=f") - (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))] - "INTEL_EXTENDED_IEEE_FORMAT" +(define_insn "mulxf3" + [(set (match_operand:XF 0 "fr_register_operand" "=f") + (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))] + "" "fmpy %0 = %F1, %F2" [(set_attr "itanium_class" "fmac")]) -(define_insn "*multf3_truncsf" +(define_insn "*mulxf3_truncsf" [(set (match_operand:SF 0 "fr_register_operand" "=f") (float_truncate:SF - (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))] - "INTEL_EXTENDED_IEEE_FORMAT" + (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))] + "" "fmpy.s %0 = %F1, %F2" [(set_attr "itanium_class" "fmac")]) -(define_insn "*multf3_truncdf" +(define_insn "*mulxf3_truncdf" [(set (match_operand:DF 0 "fr_register_operand" "=f") (float_truncate:DF - (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))] - "INTEL_EXTENDED_IEEE_FORMAT" + (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))] + "" "fmpy.d %0 = %F1, %F2" [(set_attr "itanium_class" "fmac")]) -(define_insn "*multf3_alts" - [(set (match_operand:TF 0 "fr_register_operand" "=f") - (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))) +(define_insn "*mulxf3_alts" + [(set (match_operand:XF 0 "fr_register_operand" "=f") + (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))) (use (match_operand:SI 3 "const_int_operand" ""))] - "INTEL_EXTENDED_IEEE_FORMAT" + "" "fmpy.s%3 %0 = %F1, %F2" [(set_attr "itanium_class" "fmac")]) -(define_insn "*multf3_truncsf_alts" +(define_insn "*mulxf3_truncsf_alts" [(set (match_operand:SF 0 "fr_register_operand" "=f") (float_truncate:SF - (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))) + (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))) (use (match_operand:SI 3 "const_int_operand" ""))] - "INTEL_EXTENDED_IEEE_FORMAT" + "" "fmpy.s.s%3 %0 = %F1, %F2" [(set_attr "itanium_class" "fmac")]) -(define_insn "*multf3_truncdf_alts" +(define_insn "*mulxf3_truncdf_alts" [(set (match_operand:DF 0 "fr_register_operand" "=f") (float_truncate:DF - (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))) + (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))) (use (match_operand:SI 3 "const_int_operand" ""))] - "INTEL_EXTENDED_IEEE_FORMAT" + "" "fmpy.d.s%3 %0 = %F1, %F2" [(set_attr "itanium_class" "fmac")]) -(define_insn "abstf2" - [(set (match_operand:TF 0 "fr_register_operand" "=f") - (abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))] - "INTEL_EXTENDED_IEEE_FORMAT" +(define_insn "absxf2" + [(set (match_operand:XF 0 "fr_register_operand" "=f") + (abs:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")))] + "" "fabs %0 = %F1" [(set_attr "itanium_class" "fmisc")]) -(define_insn "negtf2" - [(set (match_operand:TF 0 "fr_register_operand" "=f") - (neg:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))] - "INTEL_EXTENDED_IEEE_FORMAT" +(define_insn "negxf2" + [(set (match_operand:XF 0 "fr_register_operand" "=f") + (neg:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")))] + "" "fneg %0 = %F1" [(set_attr "itanium_class" "fmisc")]) -(define_insn "*nabstf2" - [(set (match_operand:TF 0 "fr_register_operand" "=f") - (neg:TF (abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG"))))] - "INTEL_EXTENDED_IEEE_FORMAT" +(define_insn "*nabsxf2" + [(set (match_operand:XF 0 "fr_register_operand" "=f") + (neg:XF (abs:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG"))))] + "" "fnegabs %0 = %F1" [(set_attr "itanium_class" "fmisc")]) -(define_insn "mintf3" - [(set (match_operand:TF 0 "fr_register_operand" "=f") - (smin:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))] - "INTEL_EXTENDED_IEEE_FORMAT" +(define_insn "minxf3" + [(set (match_operand:XF 0 "fr_register_operand" "=f") + (smin:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))] + "" "fmin %0 = %F1, %F2" [(set_attr "itanium_class" "fmisc")]) -(define_insn "maxtf3" - [(set (match_operand:TF 0 "fr_register_operand" "=f") - (smax:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))] - "INTEL_EXTENDED_IEEE_FORMAT" +(define_insn "maxxf3" + [(set (match_operand:XF 0 "fr_register_operand" "=f") + (smax:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))] + "" "fmax %0 = %F1, %F2" [(set_attr "itanium_class" "fmisc")]) -(define_insn "*maddtf4" - [(set (match_operand:TF 0 "fr_register_operand" "=f") - (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")) - (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))] - "INTEL_EXTENDED_IEEE_FORMAT" +(define_insn "*maddxf4" + [(set (match_operand:XF 0 "fr_register_operand" "=f") + (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) + (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))] + "" "fma %0 = %F1, %F2, %F3" [(set_attr "itanium_class" "fmac")]) -(define_insn "*maddtf4_truncsf" +(define_insn "*maddxf4_truncsf" [(set (match_operand:SF 0 "fr_register_operand" "=f") (float_truncate:SF - (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")) - (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))] - "INTEL_EXTENDED_IEEE_FORMAT" + (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) + (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))] + "" "fma.s %0 = %F1, %F2, %F3" [(set_attr "itanium_class" "fmac")]) -(define_insn "*maddtf4_truncdf" +(define_insn "*maddxf4_truncdf" [(set (match_operand:DF 0 "fr_register_operand" "=f") (float_truncate:DF - (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")) - (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))] - "INTEL_EXTENDED_IEEE_FORMAT" + (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) + (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))] + "" "fma.d %0 = %F1, %F2, %F3" [(set_attr "itanium_class" "fmac")]) -(define_insn "*maddtf4_alts" - [(set (match_operand:TF 0 "fr_register_operand" "=f") - (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")) - (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))) +(define_insn "*maddxf4_alts" + [(set (match_operand:XF 0 "fr_register_operand" "=f") + (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) + (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))) (use (match_operand:SI 4 "const_int_operand" ""))] - "INTEL_EXTENDED_IEEE_FORMAT" + "" "fma.s%4 %0 = %F1, %F2, %F3" [(set_attr "itanium_class" "fmac")]) -(define_insn "*maddtf4_alts_truncdf" +(define_insn "*maddxf4_alts_truncsf" + [(set (match_operand:SF 0 "fr_register_operand" "=f") + (float_truncate:SF + (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) + (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))) + (use (match_operand:SI 4 "const_int_operand" ""))] + "" + "fma.s.s%4 %0 = %F1, %F2, %F3" + [(set_attr "itanium_class" "fmac")]) + +(define_insn "*maddxf4_alts_truncdf" [(set (match_operand:DF 0 "fr_register_operand" "=f") (float_truncate:DF - (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")) - (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))) + (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) + (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))) (use (match_operand:SI 4 "const_int_operand" ""))] - "INTEL_EXTENDED_IEEE_FORMAT" + "" "fma.d.s%4 %0 = %F1, %F2, %F3" [(set_attr "itanium_class" "fmac")]) -(define_insn "*msubtf4" - [(set (match_operand:TF 0 "fr_register_operand" "=f") - (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")) - (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))] - "INTEL_EXTENDED_IEEE_FORMAT" +(define_insn "*msubxf4" + [(set (match_operand:XF 0 "fr_register_operand" "=f") + (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) + (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))] + "" "fms %0 = %F1, %F2, %F3" [(set_attr "itanium_class" "fmac")]) -(define_insn "*msubtf4_truncsf" +(define_insn "*msubxf4_truncsf" [(set (match_operand:SF 0 "fr_register_operand" "=f") (float_truncate:SF - (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")) - (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))] - "INTEL_EXTENDED_IEEE_FORMAT" + (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) + (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))] + "" "fms.s %0 = %F1, %F2, %F3" [(set_attr "itanium_class" "fmac")]) -(define_insn "*msubtf4_truncdf" +(define_insn "*msubxf4_truncdf" [(set (match_operand:DF 0 "fr_register_operand" "=f") (float_truncate:DF - (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")) - (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))] - "INTEL_EXTENDED_IEEE_FORMAT" + (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")) + (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))] + "" "fms.d %0 = %F1, %F2, %F3" [(set_attr "itanium_class" "fmac")]) -(define_insn "*nmultf3" - [(set (match_operand:TF 0 "fr_register_operand" "=f") - (neg:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))] - "INTEL_EXTENDED_IEEE_FORMAT" +(define_insn "*nmulxf3" + [(set (match_operand:XF 0 "fr_register_operand" "=f") + (neg:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))] + "" "fnmpy %0 = %F1, %F2" [(set_attr "itanium_class" "fmac")]) -(define_insn "*nmultf3_truncsf" +(define_insn "*nmulxf3_truncsf" [(set (match_operand:SF 0 "fr_register_operand" "=f") (float_truncate:SF - (neg:TF (mult:TF - (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))))] - "INTEL_EXTENDED_IEEE_FORMAT" + (neg:XF (mult:XF + (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))))] + "" "fnmpy.s %0 = %F1, %F2" [(set_attr "itanium_class" "fmac")]) -(define_insn "*nmultf3_truncdf" +(define_insn "*nmulxf3_truncdf" [(set (match_operand:DF 0 "fr_register_operand" "=f") (float_truncate:DF - (neg:TF (mult:TF - (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))))] - "INTEL_EXTENDED_IEEE_FORMAT" + (neg:XF (mult:XF + (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))))] + "" "fnmpy.d %0 = %F1, %F2" [(set_attr "itanium_class" "fmac")]) ;; ??? Is it possible to canonicalize this as (minus (reg) (mult))? -(define_insn "*nmaddtf4" - [(set (match_operand:TF 0 "fr_register_operand" "=f") - (plus:TF (neg:TF (mult:TF - (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))) - (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))] - "INTEL_EXTENDED_IEEE_FORMAT" +(define_insn "*nmaddxf4" + [(set (match_operand:XF 0 "fr_register_operand" "=f") + (plus:XF (neg:XF (mult:XF + (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))) + (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))] + "" "fnma %0 = %F1, %F2, %F3" [(set_attr "itanium_class" "fmac")]) -(define_insn "*nmaddtf4_truncsf" +(define_insn "*nmaddxf4_truncsf" [(set (match_operand:SF 0 "fr_register_operand" "=f") (float_truncate:SF - (plus:TF (neg:TF (mult:TF - (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))) - (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))] - "INTEL_EXTENDED_IEEE_FORMAT" + (plus:XF (neg:XF (mult:XF + (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))) + (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))] + "" "fnma.s %0 = %F1, %F2, %F3" [(set_attr "itanium_class" "fmac")]) -(define_insn "*nmaddtf4_truncdf" +(define_insn "*nmaddxf4_truncdf" [(set (match_operand:DF 0 "fr_register_operand" "=f") (float_truncate:DF - (plus:TF (neg:TF (mult:TF - (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))) - (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))] - "INTEL_EXTENDED_IEEE_FORMAT" + (plus:XF (neg:XF (mult:XF + (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))) + (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))))] + "" "fnma.d %0 = %F1, %F2, %F3" [(set_attr "itanium_class" "fmac")]) -(define_insn "*nmaddtf4_alts" - [(set (match_operand:TF 0 "fr_register_operand" "=f") - (plus:TF (neg:TF (mult:TF - (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))) - (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))) +(define_insn "*nmaddxf4_alts" + [(set (match_operand:XF 0 "fr_register_operand" "=f") + (plus:XF (neg:XF (mult:XF + (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))) + (match_operand:XF 3 "xfreg_or_fp01_operand" "fG"))) (use (match_operand:SI 4 "const_int_operand" ""))] - "INTEL_EXTENDED_IEEE_FORMAT" + "" "fnma.s%4 %0 = %F1, %F2, %F3" [(set_attr "itanium_class" "fmac")]) -(define_insn "*nmaddtf4_truncdf_alts" +(define_insn "*nmaddxf4_truncdf_alts" [(set (match_operand:DF 0 "fr_register_operand" "=f") (float_truncate:DF - (plus:TF (neg:TF - (mult:TF - (match_operand:TF 1 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))) - (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))) + (plus:XF (neg:XF + (mult:XF + (match_operand:XF 1 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))) + (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")))) (use (match_operand:SI 4 "const_int_operand" ""))] - "INTEL_EXTENDED_IEEE_FORMAT" + "" "fnma.d.s%4 %0 = %F1, %F2, %F3" [(set_attr "itanium_class" "fmac")]) -(define_expand "divtf3" - [(set (match_operand:TF 0 "fr_register_operand" "") - (div:TF (match_operand:TF 1 "fr_register_operand" "") - (match_operand:TF 2 "fr_register_operand" "")))] - "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV" +(define_expand "divxf3" + [(set (match_operand:XF 0 "fr_register_operand" "") + (div:XF (match_operand:XF 1 "fr_register_operand" "") + (match_operand:XF 2 "fr_register_operand" "")))] + "TARGET_INLINE_FLOAT_DIV" { rtx insn; if (TARGET_INLINE_FLOAT_DIV_LAT) - insn = gen_divtf3_internal_lat (operands[0], operands[1], operands[2]); + insn = gen_divxf3_internal_lat (operands[0], operands[1], operands[2]); else - insn = gen_divtf3_internal_thr (operands[0], operands[1], operands[2]); + insn = gen_divxf3_internal_thr (operands[0], operands[1], operands[2]); emit_insn (insn); DONE; }) -(define_insn_and_split "divtf3_internal_lat" - [(set (match_operand:TF 0 "fr_register_operand" "=&f") - (div:TF (match_operand:TF 1 "fr_register_operand" "f") - (match_operand:TF 2 "fr_register_operand" "f"))) - (clobber (match_scratch:TF 3 "=&f")) - (clobber (match_scratch:TF 4 "=&f")) - (clobber (match_scratch:TF 5 "=&f")) - (clobber (match_scratch:TF 6 "=&f")) +(define_insn_and_split "divxf3_internal_lat" + [(set (match_operand:XF 0 "fr_register_operand" "=&f") + (div:XF (match_operand:XF 1 "fr_register_operand" "f") + (match_operand:XF 2 "fr_register_operand" "f"))) + (clobber (match_scratch:XF 3 "=&f")) + (clobber (match_scratch:XF 4 "=&f")) + (clobber (match_scratch:XF 5 "=&f")) + (clobber (match_scratch:XF 6 "=&f")) (clobber (match_scratch:BI 7 "=c"))] - "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_LAT" + "TARGET_INLINE_FLOAT_DIV_LAT" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2))) + [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2))) (set (match_dup 7) (unspec:BI [(match_dup 1) (match_dup 2)] UNSPEC_FR_RECIP_APPROX)) (use (const_int 1))]) (cond_exec (ne (match_dup 7) (const_int 0)) (parallel [(set (match_dup 3) - (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0))) + (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0))) (match_dup 8))) (use (const_int 1))])) (cond_exec (ne (match_dup 7) (const_int 0)) - (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0))) + (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0))) (use (const_int 1))])) (cond_exec (ne (match_dup 7) (const_int 0)) - (parallel [(set (match_dup 5) (mult:TF (match_dup 3) (match_dup 3))) + (parallel [(set (match_dup 5) (mult:XF (match_dup 3) (match_dup 3))) (use (const_int 1))])) (cond_exec (ne (match_dup 7) (const_int 0)) (parallel [(set (match_dup 6) - (plus:TF (mult:TF (match_dup 3) (match_dup 3)) + (plus:XF (mult:XF (match_dup 3) (match_dup 3)) (match_dup 3))) (use (const_int 1))])) (cond_exec (ne (match_dup 7) (const_int 0)) (parallel [(set (match_dup 3) - (plus:TF (mult:TF (match_dup 5) (match_dup 5)) + (plus:XF (mult:XF (match_dup 5) (match_dup 5)) (match_dup 3))) (use (const_int 1))])) (cond_exec (ne (match_dup 7) (const_int 0)) (parallel [(set (match_dup 5) - (plus:TF (mult:TF (match_dup 6) (match_dup 0)) + (plus:XF (mult:XF (match_dup 6) (match_dup 0)) (match_dup 0))) (use (const_int 1))])) (cond_exec (ne (match_dup 7) (const_int 0)) (parallel [(set (match_dup 0) - (plus:TF (mult:TF (match_dup 5) (match_dup 3)) + (plus:XF (mult:XF (match_dup 5) (match_dup 3)) (match_dup 0))) (use (const_int 1))])) (cond_exec (ne (match_dup 7) (const_int 0)) (parallel [(set (match_dup 4) - (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 4))) + (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 4))) (match_dup 1))) (use (const_int 1))])) (cond_exec (ne (match_dup 7) (const_int 0)) (parallel [(set (match_dup 3) - (plus:TF (mult:TF (match_dup 3) (match_dup 0)) + (plus:XF (mult:XF (match_dup 3) (match_dup 0)) (match_dup 4))) (use (const_int 1))])) (cond_exec (ne (match_dup 7) (const_int 0)) (parallel [(set (match_dup 5) - (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0))) + (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0))) (match_dup 8))) (use (const_int 1))])) (cond_exec (ne (match_dup 7) (const_int 0)) (parallel [(set (match_dup 0) - (plus:TF (mult:TF (match_dup 4) (match_dup 0)) + (plus:XF (mult:XF (match_dup 4) (match_dup 0)) (match_dup 0))) (use (const_int 1))])) (cond_exec (ne (match_dup 7) (const_int 0)) (parallel [(set (match_dup 4) - (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3))) + (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3))) (match_dup 1))) (use (const_int 1))])) (cond_exec (ne (match_dup 7) (const_int 0)) (set (match_dup 0) - (plus:TF (mult:TF (match_dup 4) (match_dup 0)) + (plus:XF (mult:XF (match_dup 4) (match_dup 0)) (match_dup 3)))) ] - "operands[8] = CONST1_RTX (TFmode);" + "operands[8] = CONST1_RTX (XFmode);" [(set_attr "predicable" "no")]) -(define_insn_and_split "divtf3_internal_thr" - [(set (match_operand:TF 0 "fr_register_operand" "=&f") - (div:TF (match_operand:TF 1 "fr_register_operand" "f") - (match_operand:TF 2 "fr_register_operand" "f"))) - (clobber (match_scratch:TF 3 "=&f")) - (clobber (match_scratch:TF 4 "=&f")) +(define_insn_and_split "divxf3_internal_thr" + [(set (match_operand:XF 0 "fr_register_operand" "=&f") + (div:XF (match_operand:XF 1 "fr_register_operand" "f") + (match_operand:XF 2 "fr_register_operand" "f"))) + (clobber (match_scratch:XF 3 "=&f")) + (clobber (match_scratch:XF 4 "=&f")) (clobber (match_scratch:BI 5 "=c"))] - "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_THR" + "TARGET_INLINE_FLOAT_DIV_THR" "#" "&& reload_completed" - [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2))) + [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2))) (set (match_dup 5) (unspec:BI [(match_dup 1) (match_dup 2)] UNSPEC_FR_RECIP_APPROX)) (use (const_int 1))]) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 3) - (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0))) + (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0))) (match_dup 6))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 4) - (plus:TF (mult:TF (match_dup 3) (match_dup 0)) + (plus:XF (mult:XF (match_dup 3) (match_dup 0)) (match_dup 0))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) - (parallel [(set (match_dup 3) (mult:TF (match_dup 3) (match_dup 3))) + (parallel [(set (match_dup 3) (mult:XF (match_dup 3) (match_dup 3))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 3) - (plus:TF (mult:TF (match_dup 3) (match_dup 4)) + (plus:XF (mult:XF (match_dup 3) (match_dup 4)) (match_dup 4))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) - (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0))) + (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 0) - (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3))) + (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3))) (match_dup 6))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 0) - (plus:TF (mult:TF (match_dup 0) (match_dup 3)) + (plus:XF (mult:XF (match_dup 0) (match_dup 3)) (match_dup 3))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 3) - (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 4))) + (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 4))) (match_dup 1))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 3) - (plus:TF (mult:TF (match_dup 3) (match_dup 0)) + (plus:XF (mult:XF (match_dup 3) (match_dup 0)) (match_dup 4))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 4) - (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0))) + (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0))) (match_dup 6))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 0) - (plus:TF (mult:TF (match_dup 4) (match_dup 0)) + (plus:XF (mult:XF (match_dup 4) (match_dup 0)) (match_dup 0))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (parallel [(set (match_dup 4) - (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3))) + (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3))) (match_dup 1))) (use (const_int 1))])) (cond_exec (ne (match_dup 5) (const_int 0)) (set (match_dup 0) - (plus:TF (mult:TF (match_dup 4) (match_dup 0)) + (plus:XF (mult:XF (match_dup 4) (match_dup 0)) (match_dup 3)))) ] - "operands[6] = CONST1_RTX (TFmode);" + "operands[6] = CONST1_RTX (XFmode);" + [(set_attr "predicable" "no")]) + +;; Inline square root. + +(define_expand "sqrtxf2" + [(set (match_operand:XF 0 "fr_register_operand" "=&f") + (sqrt:XF (match_operand:XF 1 "fr_register_operand" "f")))] + "TARGET_INLINE_SQRT" +{ + rtx insn; + if (TARGET_INLINE_SQRT_LAT) +#if 0 + insn = gen_sqrtxf2_internal_lat (operands[0], operands[1]); +#else + abort (); +#endif + else + insn = gen_sqrtxf2_internal_thr (operands[0], operands[1]); + emit_insn (insn); + DONE; +}) + +;; Latency-optimized square root. +;; FIXME: Implement. + +;; Throughput-optimized square root. + +(define_insn_and_split "sqrtxf2_internal_thr" + [(set (match_operand:XF 0 "fr_register_operand" "=&f") + (sqrt:XF (match_operand:XF 1 "fr_register_operand" "f"))) + ;; Register r2 in optimization guide. + (clobber (match_scratch:DI 2 "=r")) + ;; Register f8 in optimization guide + (clobber (match_scratch:XF 3 "=&f")) + ;; Register f9 in optimization guide + (clobber (match_scratch:XF 4 "=&f")) + ;; Register f10 in optimization guide + (clobber (match_scratch:XF 5 "=&f")) + ;; Register f11 in optimization guide + (clobber (match_scratch:XF 6 "=&f")) + ;; Register p6 in optimization guide. + (clobber (match_scratch:BI 7 "=c"))] + "TARGET_INLINE_SQRT_THR" + "#" + "&& reload_completed" + [ ;; exponent of +1/2 in r2 + (set (match_dup 2) (const_int 65534)) + ;; +1/2 in f8. The Intel manual mistakenly specifies f10. + (set (match_dup 3) + (unspec:XF [(match_dup 2)] UNSPEC_SETF_EXP)) + ;; Step 1 + ;; y0 = 1/sqrt(a) in f7 + (parallel [(set (match_dup 8) + (div:XF (const_int 1) + (sqrt:XF (match_dup 9)))) + (set (match_dup 7) + (unspec:BI [(match_dup 9)] + UNSPEC_FR_SQRT_RECIP_APPROX)) + (use (const_int 0))]) + ;; Step 2 + ;; H0 = 1/2 * y0 in f9 + (cond_exec (ne (match_dup 7) (const_int 0)) + (parallel [(set (match_dup 4) + (plus:XF (mult:XF (match_dup 3) (match_dup 8)) + (match_dup 10))) + (use (const_int 1))])) + ;; Step 3 + ;; S0 = a * y0 in f7 + (cond_exec (ne (match_dup 7) (const_int 0)) + (parallel [(set (match_dup 8) + (plus:XF (mult:XF (match_dup 9) (match_dup 8)) + (match_dup 10))) + (use (const_int 1))])) + ;; Step 4 + ;; d0 = 1/2 - S0 * H0 in f10 + (cond_exec (ne (match_dup 7) (const_int 0)) + (parallel [(set (match_dup 5) + (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 4))) + (match_dup 3))) + (use (const_int 1))])) + ;; Step 5 + ;; H1 = H0 + d0 * H0 in f9 + (cond_exec (ne (match_dup 7) (const_int 0)) + (parallel [(set (match_dup 4) + (plus:XF (mult:XF (match_dup 5) (match_dup 4)) + (match_dup 4))) + (use (const_int 1))])) + ;; Step 6 + ;; S1 = S0 + d0 * S0 in f7 + (cond_exec (ne (match_dup 7) (const_int 0)) + (parallel [(set (match_dup 8) + (plus:XF (mult:XF (match_dup 5) (match_dup 8)) + (match_dup 8))) + (use (const_int 1))])) + ;; Step 7 + ;; d1 = 1/2 - S1 * H1 in f10 + (cond_exec (ne (match_dup 7) (const_int 0)) + (parallel [(set (match_dup 5) + (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 4))) + (match_dup 3))) + (use (const_int 1))])) + ;; Step 8 + ;; H2 = H1 + d1 * H1 in f9 + (cond_exec (ne (match_dup 7) (const_int 0)) + (parallel [(set (match_dup 4) + (plus:XF (mult:XF (match_dup 5) (match_dup 4)) + (match_dup 4))) + (use (const_int 1))])) + ;; Step 9 + ;; S2 = S1 + d1 * S1 in f7 + (cond_exec (ne (match_dup 7) (const_int 0)) + (parallel [(set (match_dup 8) + (plus:XF (mult:XF (match_dup 5) (match_dup 8)) + (match_dup 8))) + (use (const_int 1))])) + ;; Step 10 + ;; d2 = 1/2 - S2 * H2 in f10 + (cond_exec (ne (match_dup 7) (const_int 0)) + (parallel [(set (match_dup 5) + (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 4))) + (match_dup 3))) + (use (const_int 1))])) + ;; Step 11 + ;; e2 = a - S2 * S2 in f8 + (cond_exec (ne (match_dup 7) (const_int 0)) + (parallel [(set (match_dup 3) + (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 8))) + (match_dup 9))) + (use (const_int 1))])) + ;; Step 12 + ;; S3 = S2 + e2 * H2 in f7 + (cond_exec (ne (match_dup 7) (const_int 0)) + (parallel [(set (match_dup 8) + (plus:XF (mult:XF (match_dup 3) (match_dup 4)) + (match_dup 8))) + (use (const_int 1))])) + ;; Step 13 + ;; H3 = H2 + d2 * H2 in f9 + (cond_exec (ne (match_dup 7) (const_int 0)) + (parallel [(set (match_dup 4) + (plus:XF (mult:XF (match_dup 5) (match_dup 4)) + (match_dup 4))) + (use (const_int 1))])) + ;; Step 14 + ;; e3 = a - S3 * S3 in f8 + (cond_exec (ne (match_dup 7) (const_int 0)) + (parallel [(set (match_dup 3) + (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 8))) + (match_dup 9))) + (use (const_int 1))])) + ;; Step 15 + ;; S = S3 + e3 * H3 in f7 + (cond_exec (ne (match_dup 7) (const_int 0)) + (parallel [(set (match_dup 0) + (plus:XF (mult:XF (match_dup 3) (match_dup 4)) + (match_dup 8))) + (use (const_int 0))]))] +{ + /* Generate 82-bit versions of the input and output operands. */ + operands[8] = gen_rtx_REG (XFmode, REGNO (operands[0])); + operands[9] = gen_rtx_REG (XFmode, REGNO (operands[1])); + /* Generate required floating-point constants. */ + operands[10] = CONST0_RTX (XFmode); +} [(set_attr "predicable" "no")]) ;; ??? frcpa works like cmp.foo.unc. (define_insn "*recip_approx" - [(set (match_operand:TF 0 "fr_register_operand" "=f") - (div:TF (const_int 1) - (match_operand:TF 3 "fr_register_operand" "f"))) + [(set (match_operand:XF 0 "fr_register_operand" "=f") + (div:XF (const_int 1) + (match_operand:XF 3 "fr_register_operand" "f"))) (set (match_operand:BI 1 "register_operand" "=c") - (unspec:BI [(match_operand:TF 2 "fr_register_operand" "f") + (unspec:BI [(match_operand:XF 2 "fr_register_operand" "f") (match_dup 3)] UNSPEC_FR_RECIP_APPROX)) (use (match_operand:SI 4 "const_int_operand" ""))] - "INTEL_EXTENDED_IEEE_FORMAT" + "" "frcpa.s%4 %0, %1 = %2, %3" [(set_attr "itanium_class" "fmisc") (set_attr "predicable" "no")]) @@ -4083,11 +4419,22 @@ DONE; }) +(define_expand "cmpxf" + [(set (cc0) + (compare (match_operand:XF 0 "xfreg_or_fp01_operand" "") + (match_operand:XF 1 "xfreg_or_fp01_operand" "")))] + "" +{ + ia64_compare_op0 = operands[0]; + ia64_compare_op1 = operands[1]; + DONE; +}) + (define_expand "cmptf" [(set (cc0) - (compare (match_operand:TF 0 "tfreg_or_fp01_operand" "") - (match_operand:TF 1 "tfreg_or_fp01_operand" "")))] - "INTEL_EXTENDED_IEEE_FORMAT" + (compare (match_operand:TF 0 "gr_register_operand" "") + (match_operand:TF 1 "gr_register_operand" "")))] + "TARGET_HPUX" { ia64_compare_op0 = operands[0]; ia64_compare_op1 = operands[1]; @@ -4154,12 +4501,12 @@ "fcmp.%D1 %0, %I0 = %F2, %F3" [(set_attr "itanium_class" "fcmp")]) -(define_insn "*cmptf_internal" +(define_insn "*cmpxf_internal" [(set (match_operand:BI 0 "register_operand" "=c") (match_operator:BI 1 "comparison_operator" - [(match_operand:TF 2 "tfreg_or_fp01_operand" "fG") - (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")]))] - "INTEL_EXTENDED_IEEE_FORMAT" + [(match_operand:XF 2 "xfreg_or_fp01_operand" "fG") + (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")]))] + "" "fcmp.%D1 %0, %I0 = %F2, %F3" [(set_attr "itanium_class" "fcmp")]) @@ -4464,9 +4811,9 @@ "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c") (const_int 0)]) (match_operand:DI 2 "move_operand" - "rnm, *f, *b,*d*e,rnm,rnm, rnm,*f,*b,*d*e,rO,*f,rOQ,rO, rK") + "rim, *f, *b,*d*e,rim,rim, rim,*f,*b,*d*e,rO,*f,rOQ,rO, rK") (match_operand:DI 3 "move_operand" - "rnm,rnm,rnm, rnm, *f, *b,*d*e,*f,*b,*d*e,rO,*f,rOQ,rO, rK")))] + "rim,rim,rim, rim, *f, *b,*d*e,*f,*b,*d*e,rO,*f,rOQ,rO, rK")))] "ia64_move_ok (operands[0], operands[2]) && ia64_move_ok (operands[0], operands[3])" { abort (); } @@ -4483,29 +4830,26 @@ "reload_completed" [(const_int 0)] { - rtx tmp; - int emitted_something; + bool emitted_something = false; + rtx dest = operands[0]; + rtx srct = operands[2]; + rtx srcf = operands[3]; + rtx cond = operands[4]; - emitted_something = 0; - if (! rtx_equal_p (operands[0], operands[2])) + if (! rtx_equal_p (dest, srct)) { - tmp = gen_rtx_SET (VOIDmode, operands[0], operands[2]); - tmp = gen_rtx_COND_EXEC (VOIDmode, operands[4], tmp); - emit_insn (tmp); - emitted_something = 1; + ia64_emit_cond_move (dest, srct, cond); + emitted_something = true; } - if (! rtx_equal_p (operands[0], operands[3])) + if (! rtx_equal_p (dest, srcf)) { - tmp = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE, - VOIDmode, operands[1], const0_rtx); - tmp = gen_rtx_COND_EXEC (VOIDmode, tmp, - gen_rtx_SET (VOIDmode, operands[0], - operands[3])); - emit_insn (tmp); - emitted_something = 1; + cond = gen_rtx_fmt_ee (GET_CODE (cond) == NE ? EQ : NE, + VOIDmode, operands[1], const0_rtx); + ia64_emit_cond_move (dest, srcf, cond); + emitted_something = true; } if (! emitted_something) - emit_note (NULL, NOTE_INSN_DELETED); + emit_note (NOTE_INSN_DELETED); DONE; }) @@ -4570,9 +4914,9 @@ [(match_operand:BI 1 "register_operand" "c,c,c,c,c,c,c,c,c") (const_int 0)]) (match_operand:SI 2 "move_operand" - "0,0,0,rnm*f,rO,rO,rnm*f,rO,rO") + "0,0,0,rim*f,rO,rO,rim*f,rO,rO") (match_operand:SI 3 "move_operand" - "rnm*f,rO,rO,0,0,0,rnm*f,rO,rO")))] + "rim*f,rO,rO,0,0,0,rim*f,rO,rO")))] "ia64_move_ok (operands[0], operands[2]) && ia64_move_ok (operands[0], operands[3])" { abort (); } @@ -4786,7 +5130,7 @@ [(set_attr "itanium_class" "br,scall")]) (define_insn "call_value_nogp" - [(set (match_operand 0 "" "") + [(set (match_operand 0 "" "=X,X") (call (mem:DI (match_operand:DI 1 "call_operand" "?b,i")) (const_int 0))) (clobber (match_operand:DI 2 "register_operand" "=b,b"))] @@ -4802,7 +5146,7 @@ [(set_attr "itanium_class" "br,scall")]) (define_insn "call_gp" - [(call (mem (match_operand 0 "call_operand" "?r,i")) + [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,i")) (const_int 1)) (clobber (match_operand:DI 1 "register_operand" "=b,b")) (clobber (match_scratch:DI 2 "=&r,X")) @@ -4842,7 +5186,7 @@ }) (define_insn "call_value_gp" - [(set (match_operand 0 "" "") + [(set (match_operand 0 "" "=X,X") (call (mem:DI (match_operand:DI 1 "call_operand" "?r,i")) (const_int 1))) (clobber (match_operand:DI 2 "register_operand" "=b,b")) @@ -5062,7 +5406,8 @@ "" "" [(set_attr "itanium_class" "ignore") - (set_attr "predicable" "no")]) + (set_attr "predicable" "no") + (set_attr "empty" "yes")]) ;; Allocate a new register frame. @@ -5123,16 +5468,16 @@ [(set_attr "itanium_class" "ld")]) (define_insn "fr_spill" - [(set (match_operand:TF 0 "memory_operand" "=m") - (unspec:TF [(match_operand:TF 1 "register_operand" "f")] + [(set (match_operand:XF 0 "memory_operand" "=m") + (unspec:XF [(match_operand:XF 1 "register_operand" "f")] UNSPEC_FR_SPILL))] "" "stf.spill %0 = %1%P0" [(set_attr "itanium_class" "stf")]) (define_insn "fr_restore" - [(set (match_operand:TF 0 "register_operand" "=f") - (unspec:TF [(match_operand:TF 1 "memory_operand" "m")] + [(set (match_operand:XF 0 "register_operand" "=f") + (unspec:XF [(match_operand:XF 1 "memory_operand" "m")] UNSPEC_FR_RESTORE))] "" "ldf.fill %0 = %1%P1" @@ -5191,7 +5536,7 @@ ;; :: ;; :::::::::::::::::::: -;; ??? Emiting a NOP instruction isn't very useful. This should probably +;; ??? Emitting a NOP instruction isn't very useful. This should probably ;; be emitting ";;" to force a break in the instruction packing. ;; No operation, needed in case the user uses -g but not -O. @@ -5199,7 +5544,7 @@ [(const_int 0)] "" "nop 0" - [(set_attr "itanium_class" "unknown")]) + [(set_attr "itanium_class" "nop")]) (define_insn "nop_m" [(const_int 1)] @@ -5229,7 +5574,16 @@ [(const_int 5)] "" "" - [(set_attr "itanium_class" "nop_x")]) + [(set_attr "itanium_class" "nop_x") + (set_attr "empty" "yes")]) + +;; The following insn will be never generated. It is used only by +;; insn scheduler to change state before advancing cycle. +(define_insn "pre_cycle" + [(const_int 6)] + "" + "" + [(set_attr "itanium_class" "pre_cycle")]) (define_insn "bundle_selector" [(unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BUNDLE_SELECTOR)] @@ -5253,7 +5607,8 @@ "" ";;" [(set_attr "itanium_class" "stop_bit") - (set_attr "predicable" "no")]) + (set_attr "predicable" "no") + (set_attr "empty" "yes")]) (define_expand "trap" [(trap_if (const_int 1) (const_int 0))] @@ -5425,8 +5780,8 @@ (define_insn "fetchadd_acq_si" [(set (match_operand:SI 0 "gr_register_operand" "=r") - (match_dup 1)) - (set (match_operand:SI 1 "not_postinc_memory_operand" "+S") + (match_operand:SI 1 "not_postinc_memory_operand" "+S")) + (set (match_dup 1) (unspec:SI [(match_dup 1) (match_operand:SI 2 "fetchadd_operand" "n")] UNSPEC_FETCHADD_ACQ))] @@ -5436,8 +5791,8 @@ (define_insn "fetchadd_acq_di" [(set (match_operand:DI 0 "gr_register_operand" "=r") - (match_dup 1)) - (set (match_operand:DI 1 "not_postinc_memory_operand" "+S") + (match_operand:DI 1 "not_postinc_memory_operand" "+S")) + (set (match_dup 1) (unspec:DI [(match_dup 1) (match_operand:DI 2 "fetchadd_operand" "n")] UNSPEC_FETCHADD_ACQ))] @@ -5447,11 +5802,11 @@ (define_insn "cmpxchg_acq_si" [(set (match_operand:SI 0 "gr_register_operand" "=r") - (match_dup 1)) - (set (match_operand:SI 1 "not_postinc_memory_operand" "+S") + (match_operand:SI 1 "not_postinc_memory_operand" "+S")) + (set (match_dup 1) (unspec:SI [(match_dup 1) (match_operand:SI 2 "gr_register_operand" "r") - (match_operand 3 "ar_ccv_reg_operand" "")] + (match_operand:DI 3 "ar_ccv_reg_operand" "")] UNSPEC_CMPXCHG_ACQ))] "" "cmpxchg4.acq %0 = %1, %2, %3" @@ -5459,8 +5814,8 @@ (define_insn "cmpxchg_acq_di" [(set (match_operand:DI 0 "gr_register_operand" "=r") - (match_dup 1)) - (set (match_operand:DI 1 "not_postinc_memory_operand" "+S") + (match_operand:DI 1 "not_postinc_memory_operand" "+S")) + (set (match_dup 1) (unspec:DI [(match_dup 1) (match_operand:DI 2 "gr_register_operand" "r") (match_operand:DI 3 "ar_ccv_reg_operand" "")] @@ -5515,7 +5870,7 @@ [(unspec_volatile [(const_int 0)] UNSPECV_PSAC_NORMAL)] "" { - emit_safe_across_calls (asm_out_file); + emit_safe_across_calls (); return ""; } [(set_attr "itanium_class" "ignore") @@ -5535,7 +5890,7 @@ ;; ;; Optimizations for ptr_extend -(define_insn "*ptr_extend_plus_1" +(define_insn "ptr_extend_plus_imm" [(set (match_operand:DI 0 "gr_register_operand" "=r") (unspec:DI [(plus:SI (match_operand:SI 1 "basereg_operand" "r") |