comparison gcc/config/rs6000/rs6000.md @ 69:1b10fe6932e1

merge 69
author Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp>
date Sun, 21 Aug 2011 07:53:12 +0900
parents 326d9e06c2e3 f6334be47118
children ab0bcb71f44d
comparison
equal deleted inserted replaced
66:b362627d71ba 69:1b10fe6932e1
1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler 1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2 ;; Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 3 ;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc. 4 ;; Free Software Foundation, Inc.
5 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) 5 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
6 6
7 ;; This file is part of GCC. 7 ;; This file is part of GCC.
8 8
37 (CR4_REGNO 72) 37 (CR4_REGNO 72)
38 (CR5_REGNO 73) 38 (CR5_REGNO 73)
39 (CR6_REGNO 74) 39 (CR6_REGNO 74)
40 (CR7_REGNO 75) 40 (CR7_REGNO 75)
41 (MAX_CR_REGNO 75) 41 (MAX_CR_REGNO 75)
42 (XER_REGNO 76) 42 (CA_REGNO 76)
43 (FIRST_ALTIVEC_REGNO 77) 43 (FIRST_ALTIVEC_REGNO 77)
44 (LAST_ALTIVEC_REGNO 108) 44 (LAST_ALTIVEC_REGNO 108)
45 (VRSAVE_REGNO 109) 45 (VRSAVE_REGNO 109)
46 (VSCR_REGNO 110) 46 (VSCR_REGNO 110)
47 (SPE_ACC_REGNO 111) 47 (SPE_ACC_REGNO 111)
101 (UNSPEC_DLMZB_STRLEN 47) 101 (UNSPEC_DLMZB_STRLEN 47)
102 (UNSPEC_RSQRT 48) 102 (UNSPEC_RSQRT 48)
103 (UNSPEC_TOCREL 49) 103 (UNSPEC_TOCREL 49)
104 (UNSPEC_MACHOPIC_OFFSET 50) 104 (UNSPEC_MACHOPIC_OFFSET 50)
105 (UNSPEC_BPERM 51) 105 (UNSPEC_BPERM 51)
106 (UNSPEC_COPYSIGN 52)
107 (UNSPEC_PARITY 53)
108 (UNSPEC_FCTIW 54)
109 (UNSPEC_FCTID 55)
110 (UNSPEC_LFIWAX 56)
111 (UNSPEC_LFIWZX 57)
112 (UNSPEC_FCTIWUZ 58)
106 ]) 113 ])
107 114
108 ;; 115 ;;
109 ;; UNSPEC_VOLATILE usage 116 ;; UNSPEC_VOLATILE usage
110 ;; 117 ;;
111 118
112 (define_constants 119 (define_constants
113 [(UNSPECV_BLOCK 0) 120 [(UNSPECV_BLOCK 0)
114 (UNSPECV_LL 1) ; load-locked 121 (UNSPECV_LL 1) ; load-locked
115 (UNSPECV_SC 2) ; store-conditional 122 (UNSPECV_SC 2) ; store-conditional
123 (UNSPECV_PROBE_STACK_RANGE 3) ; probe range of stack addresses
116 (UNSPECV_EH_RR 9) ; eh_reg_restore 124 (UNSPECV_EH_RR 9) ; eh_reg_restore
117 ]) 125 ])
118 126
119 ;; Define an insn type attribute. This is used in function unit delay 127 ;; Define an insn type attribute. This is used in function unit delay
120 ;; computations. 128 ;; computations.
138 (const_int 4))) 146 (const_int 4)))
139 147
140 ;; Processor type -- this attribute must exactly match the processor_type 148 ;; Processor type -- this attribute must exactly match the processor_type
141 ;; enumeration in rs6000.h. 149 ;; enumeration in rs6000.h.
142 150
143 (define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc476,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,power4,power5,power6,power7,cell,ppca2" 151 (define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc476,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,power4,power5,power6,power7,cell,ppca2,titan"
144 (const (symbol_ref "rs6000_cpu_attr"))) 152 (const (symbol_ref "rs6000_cpu_attr")))
145 153
146 154
147 ;; If this instruction is microcoded on the CELL processor 155 ;; If this instruction is microcoded on the CELL processor
148 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded 156 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
173 (include "power6.md") 181 (include "power6.md")
174 (include "power7.md") 182 (include "power7.md")
175 (include "cell.md") 183 (include "cell.md")
176 (include "xfpu.md") 184 (include "xfpu.md")
177 (include "a2.md") 185 (include "a2.md")
186 (include "titan.md")
178 187
179 (include "predicates.md") 188 (include "predicates.md")
180 (include "constraints.md") 189 (include "constraints.md")
181 190
182 (include "darwin.md") 191 (include "darwin.md")
199 208
200 ; SImode or DImode, even if DImode doesn't fit in GPRs. 209 ; SImode or DImode, even if DImode doesn't fit in GPRs.
201 (define_mode_iterator SDI [SI DI]) 210 (define_mode_iterator SDI [SI DI])
202 211
203 ; The size of a pointer. Also, the size of the value that a record-condition 212 ; The size of a pointer. Also, the size of the value that a record-condition
204 ; (one with a '.') will compare. 213 ; (one with a '.') will compare; and the size used for arithmetic carries.
205 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")]) 214 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
206 215
207 ; Any hardware-supported floating-point mode 216 ; Any hardware-supported floating-point mode
208 (define_mode_iterator FP [ 217 (define_mode_iterator FP [
209 (SF "TARGET_HARD_FLOAT 218 (SF "TARGET_HARD_FLOAT
215 && (TARGET_FPRS || TARGET_E500_DOUBLE) 224 && (TARGET_FPRS || TARGET_E500_DOUBLE)
216 && TARGET_LONG_DOUBLE_128") 225 && TARGET_LONG_DOUBLE_128")
217 (DD "TARGET_DFP") 226 (DD "TARGET_DFP")
218 (TD "TARGET_DFP")]) 227 (TD "TARGET_DFP")])
219 228
229 ; Any fma capable floating-point mode.
230 (define_mode_iterator FMA_F [
231 (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT")
232 (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT)
233 || VECTOR_UNIT_VSX_P (DFmode)")
234 (V2SF "TARGET_PAIRED_FLOAT")
235 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
236 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
237 ])
238
239 ; These modes do not fit in integer registers in 32-bit mode.
240 ; but on e500v2, the gpr are 64 bit registers
241 (define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
242
243 ; Iterator for reciprocal estimate instructions
244 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
245
246 ; Iterator for just SF/DF
247 (define_mode_iterator SFDF [SF DF])
248
220 ; Various instructions that come in SI and DI forms. 249 ; Various instructions that come in SI and DI forms.
221 ; A generic w/d attribute, for things like cmpw/cmpd. 250 ; A generic w/d attribute, for things like cmpw/cmpd.
222 (define_mode_attr wd [(QI "b") (HI "h") (SI "w") (DI "d")]) 251 (define_mode_attr wd [(QI "b") (HI "h") (SI "w") (DI "d")])
223 252
224 ; DImode bits 253 ; DImode bits
235 (DI "TARGET_64BIT")]) 264 (DI "TARGET_64BIT")])
236 265
237 (define_mode_attr mptrsize [(SI "si") 266 (define_mode_attr mptrsize [(SI "si")
238 (DI "di")]) 267 (DI "di")])
239 268
269 (define_mode_attr rreg [(SF "f")
270 (DF "ws")
271 (V4SF "wf")
272 (V2DF "wd")])
273
274 (define_mode_attr rreg2 [(SF "f")
275 (DF "d")])
276
277 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
278 (DF "TARGET_FCFID")])
279
280 (define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS")
281 (DF "TARGET_E500_DOUBLE")])
282
283 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
284 (DF "TARGET_DOUBLE_FLOAT")])
240 285
241 ;; Start with fixed-point load and store insns. Here we put only the more 286 ;; Start with fixed-point load and store insns. Here we put only the more
242 ;; complex forms. Basic data transfer is done later. 287 ;; complex forms. Basic data transfer is done later.
243 288
244 (define_expand "zero_extend<mode>di2" 289 (define_expand "zero_extend<mode>di2"
2090 [(set (match_dup 2) (neg:GPR (match_dup 1))) 2135 [(set (match_dup 2) (neg:GPR (match_dup 1)))
2091 (set (match_dup 3) 2136 (set (match_dup 3)
2092 (compare:CC (match_dup 1) 2137 (compare:CC (match_dup 1)
2093 (const_int 0))) 2138 (const_int 0)))
2094 (set (match_dup 0) 2139 (set (match_dup 0)
2095 (if_then_else:GPR (ge (match_dup 3) 2140 (if_then_else:GPR (lt (match_dup 3)
2096 (const_int 0)) 2141 (const_int 0))
2097 (match_dup 1) 2142 (match_dup 2)
2098 (match_dup 2)))] 2143 (match_dup 1)))]
2099 "") 2144 "")
2100 2145
2101 (define_insn_and_split "nabs<mode>2_isel" 2146 (define_insn_and_split "nabs<mode>2_isel"
2102 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2147 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2103 (neg:GPR (abs:GPR (match_operand:GPR 1 "gpc_reg_operand" "b")))) 2148 (neg:GPR (abs:GPR (match_operand:GPR 1 "gpc_reg_operand" "b"))))
2109 [(set (match_dup 2) (neg:GPR (match_dup 1))) 2154 [(set (match_dup 2) (neg:GPR (match_dup 1)))
2110 (set (match_dup 3) 2155 (set (match_dup 3)
2111 (compare:CC (match_dup 1) 2156 (compare:CC (match_dup 1)
2112 (const_int 0))) 2157 (const_int 0)))
2113 (set (match_dup 0) 2158 (set (match_dup 0)
2114 (if_then_else:GPR (ge (match_dup 3) 2159 (if_then_else:GPR (lt (match_dup 3)
2115 (const_int 0)) 2160 (const_int 0))
2116 (match_dup 2) 2161 (match_dup 1)
2117 (match_dup 1)))] 2162 (match_dup 2)))]
2118 "") 2163 "")
2119 2164
2120 (define_insn_and_split "abssi2_nopower" 2165 (define_insn_and_split "abssi2_nopower"
2121 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r") 2166 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
2122 (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0"))) 2167 (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0")))
2257 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] 2302 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2258 UNSPEC_POPCNTB))] 2303 UNSPEC_POPCNTB))]
2259 "TARGET_POPCNTB" 2304 "TARGET_POPCNTB"
2260 "popcntb %0,%1") 2305 "popcntb %0,%1")
2261 2306
2262 (define_insn "popcntwsi2" 2307 (define_insn "popcntd<mode>2"
2263 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 2308 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2264 (popcount:SI (match_operand:SI 1 "gpc_reg_operand" "r")))] 2309 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2265 "TARGET_POPCNTD" 2310 "TARGET_POPCNTD"
2266 "popcntw %0,%1") 2311 "popcnt<wd> %0,%1")
2267
2268 (define_insn "popcntddi2"
2269 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2270 (popcount:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2271 "TARGET_POPCNTD && TARGET_POWERPC64"
2272 "popcntd %0,%1")
2273 2312
2274 (define_expand "popcount<mode>2" 2313 (define_expand "popcount<mode>2"
2275 [(set (match_operand:GPR 0 "gpc_reg_operand" "") 2314 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2276 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))] 2315 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2277 "TARGET_POPCNTB || TARGET_POPCNTD" 2316 "TARGET_POPCNTB || TARGET_POPCNTD"
2278 { 2317 {
2279 rs6000_emit_popcount (operands[0], operands[1]); 2318 rs6000_emit_popcount (operands[0], operands[1]);
2280 DONE; 2319 DONE;
2281 }) 2320 })
2321
2322 (define_insn "parity<mode>2_cmpb"
2323 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2324 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2325 "TARGET_CMPB && TARGET_POPCNTB"
2326 "prty<wd> %0,%1")
2282 2327
2283 (define_expand "parity<mode>2" 2328 (define_expand "parity<mode>2"
2284 [(set (match_operand:GPR 0 "gpc_reg_operand" "") 2329 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2285 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))] 2330 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2286 "TARGET_POPCNTB" 2331 "TARGET_POPCNTB"
5558 # 5603 #
5559 #" 5604 #"
5560 [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare") 5605 [(set_attr "type" "var_delayed_compare,delayed_compare,var_delayed_compare,delayed_compare")
5561 (set_attr "length" "4,4,8,8")]) 5606 (set_attr "length" "4,4,8,8")])
5562 5607
5608 ;; Builtins to replace a division to generate FRE reciprocal estimate
5609 ;; instructions and the necessary fixup instructions
5610 (define_expand "recip<mode>3"
5611 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
5612 (match_operand:RECIPF 1 "gpc_reg_operand" "")
5613 (match_operand:RECIPF 2 "gpc_reg_operand" "")]
5614 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
5615 {
5616 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
5617 DONE;
5618 })
5619
5620 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
5621 ;; hardware division. This is only done before register allocation and with
5622 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
5623 (define_split
5624 [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
5625 (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
5626 (match_operand 2 "gpc_reg_operand" "")))]
5627 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
5628 && can_create_pseudo_p () && optimize_insn_for_speed_p ()
5629 && flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math"
5630 [(const_int 0)]
5631 {
5632 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
5633 DONE;
5634 })
5635
5636 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
5637 ;; appropriate fixup.
5638 (define_expand "rsqrt<mode>2"
5639 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
5640 (match_operand:RECIPF 1 "gpc_reg_operand" "")]
5641 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
5642 {
5643 rs6000_emit_swrsqrt (operands[0], operands[1]);
5644 DONE;
5645 })
5646
5563 (define_split 5647 (define_split
5564 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "") 5648 [(set (match_operand:CC 3 "cc_reg_not_micro_cr0_operand" "")
5565 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "") 5649 (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
5566 (match_operand:SI 2 "reg_or_cint_operand" "")) 5650 (match_operand:SI 2 "reg_or_cint_operand" ""))
5567 (const_int 0))) 5651 (const_int 0)))
5761 "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 5845 "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS
5762 && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU" 5846 && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
5763 "{fd|fdiv} %0,%1,%2" 5847 "{fd|fdiv} %0,%1,%2"
5764 [(set_attr "type" "ddiv")]) 5848 [(set_attr "type" "ddiv")])
5765 5849
5766 (define_expand "recipsf3"
5767 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5768 (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")
5769 (match_operand:SF 2 "gpc_reg_operand" "f")]
5770 UNSPEC_FRES))]
5771 "TARGET_RECIP && TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT && !optimize_size
5772 && flag_finite_math_only && !flag_trapping_math"
5773 {
5774 rs6000_emit_swdivsf (operands[0], operands[1], operands[2]);
5775 DONE;
5776 })
5777
5778 (define_insn "fres" 5850 (define_insn "fres"
5779 [(set (match_operand:SF 0 "gpc_reg_operand" "=f") 5851 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5780 (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))] 5852 (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))]
5781 "TARGET_PPC_GFXOPT && flag_finite_math_only" 5853 "TARGET_FRES"
5782 "fres %0,%1" 5854 "fres %0,%1"
5783 [(set_attr "type" "fp")]) 5855 [(set_attr "type" "fp")])
5784 5856
5785 (define_insn "*fmaddsf4_powerpc" 5857 ; builtin fmaf support
5858 (define_insn "*fmasf4_fpr"
5786 [(set (match_operand:SF 0 "gpc_reg_operand" "=f") 5859 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5787 (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") 5860 (fma:SF (match_operand:SF 1 "gpc_reg_operand" "f")
5788 (match_operand:SF 2 "gpc_reg_operand" "f")) 5861 (match_operand:SF 2 "gpc_reg_operand" "f")
5789 (match_operand:SF 3 "gpc_reg_operand" "f")))] 5862 (match_operand:SF 3 "gpc_reg_operand" "f")))]
5790 "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS 5863 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
5791 && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD" 5864 {
5792 "fmadds %0,%1,%2,%3" 5865 return (TARGET_POWERPC
5866 ? "fmadds %0,%1,%2,%3"
5867 : "{fma|fmadd} %0,%1,%2,%3");
5868 }
5793 [(set_attr "type" "fp") 5869 [(set_attr "type" "fp")
5794 (set_attr "fp_type" "fp_maddsub_s")]) 5870 (set_attr "fp_type" "fp_maddsub_s")])
5795 5871
5796 (define_insn "*fmaddsf4_power" 5872 (define_insn "*fmssf4_fpr"
5797 [(set (match_operand:SF 0 "gpc_reg_operand" "=f") 5873 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5798 (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") 5874 (fma:SF (match_operand:SF 1 "gpc_reg_operand" "f")
5799 (match_operand:SF 2 "gpc_reg_operand" "f")) 5875 (match_operand:SF 2 "gpc_reg_operand" "f")
5800 (match_operand:SF 3 "gpc_reg_operand" "f")))] 5876 (neg:SF (match_operand:SF 3 "gpc_reg_operand" "f"))))]
5801 "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD" 5877 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
5802 "{fma|fmadd} %0,%1,%2,%3" 5878 {
5803 [(set_attr "type" "dmul")]) 5879 return (TARGET_POWERPC
5804 5880 ? "fmsubs %0,%1,%2,%3"
5805 (define_insn "*fmsubsf4_powerpc" 5881 : "{fms|fmsub} %0,%1,%2,%3");
5806 [(set (match_operand:SF 0 "gpc_reg_operand" "=f") 5882 }
5807 (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
5808 (match_operand:SF 2 "gpc_reg_operand" "f"))
5809 (match_operand:SF 3 "gpc_reg_operand" "f")))]
5810 "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS
5811 && TARGET_SINGLE_FLOAT && TARGET_FUSED_MADD"
5812 "fmsubs %0,%1,%2,%3"
5813 [(set_attr "type" "fp") 5883 [(set_attr "type" "fp")
5814 (set_attr "fp_type" "fp_maddsub_s")]) 5884 (set_attr "fp_type" "fp_maddsub_s")])
5815 5885
5816 (define_insn "*fmsubsf4_power" 5886 (define_insn "*nfmasf4_fpr"
5817 [(set (match_operand:SF 0 "gpc_reg_operand" "=f") 5887 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5818 (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") 5888 (neg:SF (fma:SF (match_operand:SF 1 "gpc_reg_operand" "f")
5819 (match_operand:SF 2 "gpc_reg_operand" "f")) 5889 (match_operand:SF 2 "gpc_reg_operand" "f")
5820 (match_operand:SF 3 "gpc_reg_operand" "f")))] 5890 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
5821 "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD" 5891 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
5822 "{fms|fmsub} %0,%1,%2,%3" 5892 {
5823 [(set_attr "type" "dmul")]) 5893 return (TARGET_POWERPC
5824 5894 ? "fnmadds %0,%1,%2,%3"
5825 (define_insn "*fnmaddsf4_powerpc_1" 5895 : "{fnma|fnmadd} %0,%1,%2,%3");
5826 [(set (match_operand:SF 0 "gpc_reg_operand" "=f") 5896 }
5827 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
5828 (match_operand:SF 2 "gpc_reg_operand" "f"))
5829 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
5830 "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
5831 && TARGET_SINGLE_FLOAT"
5832 "fnmadds %0,%1,%2,%3"
5833 [(set_attr "type" "fp") 5897 [(set_attr "type" "fp")
5834 (set_attr "fp_type" "fp_maddsub_s")]) 5898 (set_attr "fp_type" "fp_maddsub_s")])
5835 5899
5836 (define_insn "*fnmaddsf4_powerpc_2" 5900 (define_insn "*nfmssf4_fpr"
5837 [(set (match_operand:SF 0 "gpc_reg_operand" "=f") 5901 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5838 (minus:SF (mult:SF (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f")) 5902 (neg:SF (fma:SF (match_operand:SF 1 "gpc_reg_operand" "f")
5839 (match_operand:SF 2 "gpc_reg_operand" "f")) 5903 (match_operand:SF 2 "gpc_reg_operand" "f")
5840 (match_operand:SF 3 "gpc_reg_operand" "f")))] 5904 (neg:SF (match_operand:SF 3 "gpc_reg_operand" "f")))))]
5841 "TARGET_POWERPC && TARGET_SINGLE_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD 5905 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
5842 && ! HONOR_SIGNED_ZEROS (SFmode)" 5906 {
5843 "fnmadds %0,%1,%2,%3" 5907 return (TARGET_POWERPC
5908 ? "fnmsubs %0,%1,%2,%3"
5909 : "{fnms|fnmsub} %0,%1,%2,%3");
5910 }
5844 [(set_attr "type" "fp") 5911 [(set_attr "type" "fp")
5845 (set_attr "fp_type" "fp_maddsub_s")]) 5912 (set_attr "fp_type" "fp_maddsub_s")])
5846
5847 (define_insn "*fnmaddsf4_power_1"
5848 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5849 (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
5850 (match_operand:SF 2 "gpc_reg_operand" "f"))
5851 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
5852 "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
5853 "{fnma|fnmadd} %0,%1,%2,%3"
5854 [(set_attr "type" "dmul")])
5855
5856 (define_insn "*fnmaddsf4_power_2"
5857 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5858 (minus:SF (mult:SF (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f"))
5859 (match_operand:SF 2 "gpc_reg_operand" "f"))
5860 (match_operand:SF 3 "gpc_reg_operand" "f")))]
5861 "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
5862 && ! HONOR_SIGNED_ZEROS (SFmode)"
5863 "{fnma|fnmadd} %0,%1,%2,%3"
5864 [(set_attr "type" "dmul")])
5865
5866 (define_insn "*fnmsubsf4_powerpc_1"
5867 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5868 (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
5869 (match_operand:SF 2 "gpc_reg_operand" "f"))
5870 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
5871 "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
5872 && TARGET_SINGLE_FLOAT"
5873 "fnmsubs %0,%1,%2,%3"
5874 [(set_attr "type" "fp")
5875 (set_attr "fp_type" "fp_maddsub_s")])
5876
5877 (define_insn "*fnmsubsf4_powerpc_2"
5878 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5879 (minus:SF (match_operand:SF 3 "gpc_reg_operand" "f")
5880 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
5881 (match_operand:SF 2 "gpc_reg_operand" "f"))))]
5882 "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
5883 && TARGET_SINGLE_FLOAT && ! HONOR_SIGNED_ZEROS (SFmode)"
5884 "fnmsubs %0,%1,%2,%3"
5885 [(set_attr "type" "fp")
5886 (set_attr "fp_type" "fp_maddsub_s")])
5887
5888 (define_insn "*fnmsubsf4_power_1"
5889 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5890 (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
5891 (match_operand:SF 2 "gpc_reg_operand" "f"))
5892 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
5893 "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
5894 "{fnms|fnmsub} %0,%1,%2,%3"
5895 [(set_attr "type" "dmul")])
5896
5897 (define_insn "*fnmsubsf4_power_2"
5898 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5899 (minus:SF (match_operand:SF 3 "gpc_reg_operand" "f")
5900 (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
5901 (match_operand:SF 2 "gpc_reg_operand" "f"))))]
5902 "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
5903 && ! HONOR_SIGNED_ZEROS (SFmode)"
5904 "{fnms|fnmsub} %0,%1,%2,%3"
5905 [(set_attr "type" "dmul")])
5906 5913
5907 (define_expand "sqrtsf2" 5914 (define_expand "sqrtsf2"
5908 [(set (match_operand:SF 0 "gpc_reg_operand" "") 5915 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5909 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))] 5916 (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
5910 "(TARGET_PPC_GPOPT || TARGET_POWER2 || TARGET_XILINX_FPU) 5917 "(TARGET_PPC_GPOPT || TARGET_POWER2 || TARGET_XILINX_FPU)
5926 "TARGET_POWER2 && TARGET_HARD_FLOAT && TARGET_FPRS 5933 "TARGET_POWER2 && TARGET_HARD_FLOAT && TARGET_FPRS
5927 && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU" 5934 && TARGET_SINGLE_FLOAT && !TARGET_SIMPLE_FPU"
5928 "fsqrt %0,%1" 5935 "fsqrt %0,%1"
5929 [(set_attr "type" "dsqrt")]) 5936 [(set_attr "type" "dsqrt")])
5930 5937
5931 (define_expand "rsqrtsf2" 5938 (define_insn "*rsqrtsf_internal1"
5932 [(set (match_operand:SF 0 "gpc_reg_operand" "=f") 5939 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5933 (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] 5940 (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")]
5934 UNSPEC_RSQRT))] 5941 UNSPEC_RSQRT))]
5935 "TARGET_RECIP && TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT && !optimize_size 5942 "TARGET_FRSQRTES"
5936 && flag_finite_math_only && !flag_trapping_math" 5943 "frsqrtes %0,%1"
5937 {
5938 rs6000_emit_swrsqrtsf (operands[0], operands[1]);
5939 DONE;
5940 })
5941
5942 (define_insn "*rsqrt_internal1"
5943 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5944 (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")]
5945 UNSPEC_RSQRT))]
5946 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5947 "frsqrte %0,%1"
5948 [(set_attr "type" "fp")]) 5944 [(set_attr "type" "fp")])
5949 5945
5950 (define_expand "copysignsf3" 5946 (define_expand "copysign<mode>3"
5951 [(set (match_dup 3) 5947 [(set (match_dup 3)
5952 (abs:SF (match_operand:SF 1 "gpc_reg_operand" ""))) 5948 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
5953 (set (match_dup 4) 5949 (set (match_dup 4)
5954 (neg:SF (abs:SF (match_dup 1)))) 5950 (neg:SFDF (abs:SFDF (match_dup 1))))
5955 (set (match_operand:SF 0 "gpc_reg_operand" "") 5951 (set (match_operand:SFDF 0 "gpc_reg_operand" "")
5956 (if_then_else:SF (ge (match_operand:SF 2 "gpc_reg_operand" "") 5952 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
5957 (match_dup 5)) 5953 (match_dup 5))
5958 (match_dup 3) 5954 (match_dup 3)
5959 (match_dup 4)))] 5955 (match_dup 4)))]
5960 "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 5956 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
5961 && !HONOR_NANS (SFmode) && !HONOR_SIGNED_ZEROS (SFmode)" 5957 && ((TARGET_PPC_GFXOPT
5962 { 5958 && !HONOR_NANS (<MODE>mode)
5963 operands[3] = gen_reg_rtx (SFmode); 5959 && !HONOR_SIGNED_ZEROS (<MODE>mode))
5964 operands[4] = gen_reg_rtx (SFmode); 5960 || TARGET_CMPB
5965 operands[5] = CONST0_RTX (SFmode); 5961 || VECTOR_UNIT_VSX_P (<MODE>mode))"
5962 {
5963 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
5964 {
5965 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
5966 operands[2]));
5967 DONE;
5968 }
5969
5970 operands[3] = gen_reg_rtx (<MODE>mode);
5971 operands[4] = gen_reg_rtx (<MODE>mode);
5972 operands[5] = CONST0_RTX (<MODE>mode);
5966 }) 5973 })
5967 5974
5968 (define_expand "copysigndf3" 5975 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
5969 [(set (match_dup 3) 5976 ;; compiler from optimizing -0.0
5970 (abs:DF (match_operand:DF 1 "gpc_reg_operand" ""))) 5977 (define_insn "copysign<mode>3_fcpsgn"
5971 (set (match_dup 4) 5978 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5972 (neg:DF (abs:DF (match_dup 1)))) 5979 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")
5973 (set (match_operand:DF 0 "gpc_reg_operand" "") 5980 (match_operand:SFDF 2 "gpc_reg_operand" "<rreg2>")]
5974 (if_then_else:DF (ge (match_operand:DF 2 "gpc_reg_operand" "") 5981 UNSPEC_COPYSIGN))]
5975 (match_dup 5)) 5982 "TARGET_CMPB && !VECTOR_UNIT_VSX_P (<MODE>mode)"
5976 (match_dup 3) 5983 "fcpsgn %0,%2,%1"
5977 (match_dup 4)))] 5984 [(set_attr "type" "fp")])
5978 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
5979 && ((TARGET_PPC_GFXOPT
5980 && !HONOR_NANS (DFmode)
5981 && !HONOR_SIGNED_ZEROS (DFmode))
5982 || VECTOR_UNIT_VSX_P (DFmode))"
5983 {
5984 if (VECTOR_UNIT_VSX_P (DFmode))
5985 {
5986 emit_insn (gen_vsx_copysigndf3 (operands[0], operands[1],
5987 operands[2], CONST0_RTX (DFmode)));
5988 DONE;
5989 }
5990 operands[3] = gen_reg_rtx (DFmode);
5991 operands[4] = gen_reg_rtx (DFmode);
5992 operands[5] = CONST0_RTX (DFmode);
5993 })
5994 5985
5995 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a 5986 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
5996 ;; fsel instruction and some auxiliary computations. Then we just have a 5987 ;; fsel instruction and some auxiliary computations. Then we just have a
5997 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by 5988 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
5998 ;; combine. 5989 ;; combine.
6051 ;; We need 2 patterns: an unsigned and a signed pattern. We could 6042 ;; We need 2 patterns: an unsigned and a signed pattern. We could
6052 ;; leave out the mode in operand 4 and use one pattern, but reload can 6043 ;; leave out the mode in operand 4 and use one pattern, but reload can
6053 ;; change the mode underneath our feet and then gets confused trying 6044 ;; change the mode underneath our feet and then gets confused trying
6054 ;; to reload the value. 6045 ;; to reload the value.
6055 (define_insn "isel_signed_<mode>" 6046 (define_insn "isel_signed_<mode>"
6047 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
6048 (if_then_else:GPR
6049 (match_operator 1 "scc_comparison_operator"
6050 [(match_operand:CC 4 "cc_reg_operand" "y,y")
6051 (const_int 0)])
6052 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
6053 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
6054 "TARGET_ISEL<sel>"
6055 "*
6056 { return output_isel (operands); }"
6057 [(set_attr "type" "isel")
6058 (set_attr "length" "4")])
6059
6060 (define_insn "isel_unsigned_<mode>"
6061 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
6062 (if_then_else:GPR
6063 (match_operator 1 "scc_comparison_operator"
6064 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
6065 (const_int 0)])
6066 (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
6067 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
6068 "TARGET_ISEL<sel>"
6069 "*
6070 { return output_isel (operands); }"
6071 [(set_attr "type" "isel")
6072 (set_attr "length" "4")])
6073
6074 ;; These patterns can be useful for combine; they let combine know that
6075 ;; isel can handle reversed comparisons so long as the operands are
6076 ;; registers.
6077
6078 (define_insn "*isel_reversed_signed_<mode>"
6056 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 6079 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
6057 (if_then_else:GPR 6080 (if_then_else:GPR
6058 (match_operator 1 "comparison_operator" 6081 (match_operator 1 "scc_rev_comparison_operator"
6059 [(match_operand:CC 4 "cc_reg_operand" "y") 6082 [(match_operand:CC 4 "cc_reg_operand" "y")
6060 (const_int 0)]) 6083 (const_int 0)])
6061 (match_operand:GPR 2 "gpc_reg_operand" "b") 6084 (match_operand:GPR 2 "gpc_reg_operand" "b")
6062 (match_operand:GPR 3 "gpc_reg_operand" "b")))] 6085 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
6063 "TARGET_ISEL<sel>" 6086 "TARGET_ISEL<sel>"
6064 "* 6087 "*
6065 { return output_isel (operands); }" 6088 { return output_isel (operands); }"
6066 [(set_attr "type" "isel") 6089 [(set_attr "type" "isel")
6067 (set_attr "length" "4")]) 6090 (set_attr "length" "4")])
6068 6091
6069 (define_insn "isel_unsigned_<mode>" 6092 (define_insn "*isel_reversed_unsigned_<mode>"
6070 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 6093 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
6071 (if_then_else:GPR 6094 (if_then_else:GPR
6072 (match_operator 1 "comparison_operator" 6095 (match_operator 1 "scc_rev_comparison_operator"
6073 [(match_operand:CCUNS 4 "cc_reg_operand" "y") 6096 [(match_operand:CCUNS 4 "cc_reg_operand" "y")
6074 (const_int 0)]) 6097 (const_int 0)])
6075 (match_operand:GPR 2 "gpc_reg_operand" "b") 6098 (match_operand:GPR 2 "gpc_reg_operand" "b")
6076 (match_operand:GPR 3 "gpc_reg_operand" "b")))] 6099 (match_operand:GPR 3 "gpc_reg_operand" "b")))]
6077 "TARGET_ISEL<sel>" 6100 "TARGET_ISEL<sel>"
6217 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !TARGET_SIMPLE_FPU 6240 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !TARGET_SIMPLE_FPU
6218 && !VECTOR_UNIT_VSX_P (DFmode)" 6241 && !VECTOR_UNIT_VSX_P (DFmode)"
6219 "{fd|fdiv} %0,%1,%2" 6242 "{fd|fdiv} %0,%1,%2"
6220 [(set_attr "type" "ddiv")]) 6243 [(set_attr "type" "ddiv")])
6221 6244
6222 (define_expand "recipdf3"
6223 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6224 (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")
6225 (match_operand:DF 2 "gpc_reg_operand" "d")]
6226 UNSPEC_FRES))]
6227 "TARGET_RECIP && TARGET_HARD_FLOAT && TARGET_POPCNTB && !optimize_size
6228 && flag_finite_math_only && !flag_trapping_math"
6229 {
6230 rs6000_emit_swdivdf (operands[0], operands[1], operands[2]);
6231 DONE;
6232 })
6233
6234 (define_expand "fred"
6235 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6236 (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRES))]
6237 "(TARGET_POPCNTB || VECTOR_UNIT_VSX_P (DFmode)) && flag_finite_math_only"
6238 "")
6239
6240 (define_insn "*fred_fpr" 6245 (define_insn "*fred_fpr"
6241 [(set (match_operand:DF 0 "gpc_reg_operand" "=f") 6246 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
6242 (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))] 6247 (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))]
6243 "TARGET_POPCNTB && flag_finite_math_only && !VECTOR_UNIT_VSX_P (DFmode)" 6248 "TARGET_FRE && !VECTOR_UNIT_VSX_P (DFmode)"
6244 "fre %0,%1" 6249 "fre %0,%1"
6245 [(set_attr "type" "fp")]) 6250 [(set_attr "type" "fp")])
6246 6251
6247 (define_insn "*fmadddf4_fpr" 6252 (define_insn "*rsqrtdf_internal1"
6248 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 6253 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6249 (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d") 6254 (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
6250 (match_operand:DF 2 "gpc_reg_operand" "d")) 6255 UNSPEC_RSQRT))]
6251 (match_operand:DF 3 "gpc_reg_operand" "d")))] 6256 "TARGET_FRSQRTE && !VECTOR_UNIT_VSX_P (DFmode)"
6252 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT 6257 "frsqrte %0,%1"
6258 [(set_attr "type" "fp")])
6259
6260 ; builtin fma support
6261 (define_insn "*fmadf4_fpr"
6262 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
6263 (fma:DF (match_operand:DF 1 "gpc_reg_operand" "f")
6264 (match_operand:DF 2 "gpc_reg_operand" "f")
6265 (match_operand:DF 3 "gpc_reg_operand" "f")))]
6266 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6253 && VECTOR_UNIT_NONE_P (DFmode)" 6267 && VECTOR_UNIT_NONE_P (DFmode)"
6254 "{fma|fmadd} %0,%1,%2,%3" 6268 "{fma|fmadd} %0,%1,%2,%3"
6255 [(set_attr "type" "dmul") 6269 [(set_attr "type" "fp")
6256 (set_attr "fp_type" "fp_maddsub_d")]) 6270 (set_attr "fp_type" "fp_maddsub_s")])
6257 6271
6258 (define_insn "*fmsubdf4_fpr" 6272 (define_insn "*fmsdf4_fpr"
6259 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 6273 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
6260 (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d") 6274 (fma:DF (match_operand:DF 1 "gpc_reg_operand" "f")
6261 (match_operand:DF 2 "gpc_reg_operand" "d")) 6275 (match_operand:DF 2 "gpc_reg_operand" "f")
6262 (match_operand:DF 3 "gpc_reg_operand" "d")))] 6276 (neg:DF (match_operand:DF 3 "gpc_reg_operand" "f"))))]
6263 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT 6277 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6264 && VECTOR_UNIT_NONE_P (DFmode)" 6278 && VECTOR_UNIT_NONE_P (DFmode)"
6265 "{fms|fmsub} %0,%1,%2,%3" 6279 "{fms|fmsub} %0,%1,%2,%3"
6266 [(set_attr "type" "dmul") 6280 [(set_attr "type" "fp")
6267 (set_attr "fp_type" "fp_maddsub_d")]) 6281 (set_attr "fp_type" "fp_maddsub_s")])
6268 6282
6269 (define_insn "*fnmadddf4_fpr_1" 6283 (define_insn "*nfmadf4_fpr"
6270 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 6284 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
6271 (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d") 6285 (neg:DF (fma:DF (match_operand:DF 1 "gpc_reg_operand" "f")
6272 (match_operand:DF 2 "gpc_reg_operand" "d")) 6286 (match_operand:DF 2 "gpc_reg_operand" "f")
6273 (match_operand:DF 3 "gpc_reg_operand" "d"))))] 6287 (match_operand:DF 3 "gpc_reg_operand" "f"))))]
6274 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT 6288 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6275 && VECTOR_UNIT_NONE_P (DFmode)" 6289 && VECTOR_UNIT_NONE_P (DFmode)"
6276 "{fnma|fnmadd} %0,%1,%2,%3" 6290 "{fnma|fnmadd} %0,%1,%2,%3"
6277 [(set_attr "type" "dmul") 6291 [(set_attr "type" "fp")
6278 (set_attr "fp_type" "fp_maddsub_d")]) 6292 (set_attr "fp_type" "fp_maddsub_s")])
6279 6293
6280 (define_insn "*fnmadddf4_fpr_2" 6294 (define_insn "*nfmsdf4_fpr"
6281 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 6295 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
6282 (minus:DF (mult:DF (neg:DF (match_operand:DF 1 "gpc_reg_operand" "d")) 6296 (neg:DF (fma:DF (match_operand:DF 1 "gpc_reg_operand" "f")
6283 (match_operand:DF 2 "gpc_reg_operand" "d")) 6297 (match_operand:DF 2 "gpc_reg_operand" "f")
6284 (match_operand:DF 3 "gpc_reg_operand" "d")))] 6298 (neg:DF (match_operand:DF 3 "gpc_reg_operand" "f")))))]
6285 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT 6299 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6286 && ! HONOR_SIGNED_ZEROS (DFmode) && VECTOR_UNIT_NONE_P (DFmode)"
6287 "{fnma|fnmadd} %0,%1,%2,%3"
6288 [(set_attr "type" "dmul")
6289 (set_attr "fp_type" "fp_maddsub_d")])
6290
6291 (define_insn "*fnmsubdf4_fpr_1"
6292 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6293 (neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
6294 (match_operand:DF 2 "gpc_reg_operand" "d"))
6295 (match_operand:DF 3 "gpc_reg_operand" "d"))))]
6296 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
6297 && VECTOR_UNIT_NONE_P (DFmode)" 6300 && VECTOR_UNIT_NONE_P (DFmode)"
6298 "{fnms|fnmsub} %0,%1,%2,%3" 6301 "{fnms|fnmsub} %0,%1,%2,%3"
6299 [(set_attr "type" "dmul") 6302 [(set_attr "type" "fp")
6300 (set_attr "fp_type" "fp_maddsub_d")]) 6303 (set_attr "fp_type" "fp_maddsub_s")])
6301 6304
6302 (define_insn "*fnmsubdf4_fpr_2" 6305 (define_expand "sqrtdf2"
6303 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 6306 [(set (match_operand:DF 0 "gpc_reg_operand" "")
6304 (minus:DF (match_operand:DF 3 "gpc_reg_operand" "d") 6307 (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
6305 (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d") 6308 "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS
6306 (match_operand:DF 2 "gpc_reg_operand" "d"))))] 6309 && TARGET_DOUBLE_FLOAT"
6307 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT 6310 "")
6308 && ! HONOR_SIGNED_ZEROS (DFmode) && VECTOR_UNIT_NONE_P (DFmode)" 6311
6309 "{fnms|fnmsub} %0,%1,%2,%3" 6312 (define_insn "*sqrtdf2_fpr"
6310 [(set_attr "type" "dmul")
6311 (set_attr "fp_type" "fp_maddsub_d")])
6312
6313 (define_insn "sqrtdf2"
6314 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 6313 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6315 (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "d")))] 6314 (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "d")))]
6316 "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS 6315 "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS
6317 && TARGET_DOUBLE_FLOAT 6316 && TARGET_DOUBLE_FLOAT
6318 && !VECTOR_UNIT_VSX_P (DFmode)" 6317 && !VECTOR_UNIT_VSX_P (DFmode)"
6390 "fsel %0,%1,%2,%3" 6389 "fsel %0,%1,%2,%3"
6391 [(set_attr "type" "fp")]) 6390 [(set_attr "type" "fp")])
6392 6391
6393 ;; Conversions to and from floating-point. 6392 ;; Conversions to and from floating-point.
6394 6393
6395 (define_expand "fixuns_truncsfsi2" 6394 ; We don't define lfiwax/lfiwzx with the normal definition, because we
6396 [(set (match_operand:SI 0 "gpc_reg_operand" "") 6395 ; don't want to support putting SImode in FPR registers.
6397 (unsigned_fix:SI (match_operand:SF 1 "gpc_reg_operand" "")))] 6396 (define_insn "lfiwax"
6398 "TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT" 6397 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6399 "") 6398 (unspec:DI [(match_operand:SI 1 "indexed_or_indirect_operand" "Z")]
6400 6399 UNSPEC_LFIWAX))]
6401 (define_expand "fix_truncsfsi2" 6400 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
6402 [(set (match_operand:SI 0 "gpc_reg_operand" "") 6401 "lfiwax %0,%y1"
6403 (fix:SI (match_operand:SF 1 "gpc_reg_operand" "")))] 6402 [(set_attr "type" "fpload")])
6404 "TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT" 6403
6405 "") 6404 ; This split must be run before register allocation because it allocates the
6406 6405 ; memory slot that is needed to move values to/from the FPR. We don't allocate
6407 (define_expand "fixuns_truncdfsi2" 6406 ; it earlier to allow for the combiner to merge insns together where it might
6408 [(set (match_operand:SI 0 "gpc_reg_operand" "") 6407 ; not be needed and also in case the insns are deleted as dead code.
6409 (unsigned_fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))] 6408
6410 "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE" 6409 (define_insn_and_split "floatsi<mode>2_lfiwax"
6411 "") 6410 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6412 6411 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
6413 (define_expand "fixuns_truncdfdi2" 6412 (clobber (match_scratch:DI 2 "=d"))]
6414 [(set (match_operand:DI 0 "register_operand" "") 6413 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
6415 (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))] 6414 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
6416 "TARGET_HARD_FLOAT && TARGET_VSX" 6415 "#"
6417 "") 6416 ""
6417 [(pc)]
6418 "
6419 {
6420 rtx dest = operands[0];
6421 rtx src = operands[1];
6422 rtx tmp;
6423
6424 if (!MEM_P (src) && TARGET_MFPGPR && TARGET_POWERPC64)
6425 tmp = convert_to_mode (DImode, src, false);
6426 else
6427 {
6428 tmp = operands[2];
6429 if (GET_CODE (tmp) == SCRATCH)
6430 tmp = gen_reg_rtx (DImode);
6431 if (MEM_P (src))
6432 {
6433 src = rs6000_address_for_fpconvert (src);
6434 emit_insn (gen_lfiwax (tmp, src));
6435 }
6436 else
6437 {
6438 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6439 emit_move_insn (stack, src);
6440 emit_insn (gen_lfiwax (tmp, stack));
6441 }
6442 }
6443 emit_insn (gen_floatdi<mode>2 (dest, tmp));
6444 DONE;
6445 }"
6446 [(set_attr "length" "12")
6447 (set_attr "type" "fpload")])
6448
6449 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
6450 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<rreg2>")
6451 (float:SFDF
6452 (sign_extend:DI
6453 (match_operand:SI 1 "memory_operand" "Z,Z"))))
6454 (clobber (match_scratch:DI 2 "=0,d"))]
6455 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
6456 && <SI_CONVERT_FP>"
6457 "#"
6458 ""
6459 [(pc)]
6460 "
6461 {
6462 operands[1] = rs6000_address_for_fpconvert (operands[1]);
6463 if (GET_CODE (operands[2]) == SCRATCH)
6464 operands[2] = gen_reg_rtx (DImode);
6465 emit_insn (gen_lfiwax (operands[2], operands[1]));
6466 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
6467 DONE;
6468 }"
6469 [(set_attr "length" "8")
6470 (set_attr "type" "fpload")])
6471
6472 (define_insn "lfiwzx"
6473 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6474 (unspec:DI [(match_operand:SI 1 "indexed_or_indirect_operand" "Z")]
6475 UNSPEC_LFIWZX))]
6476 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
6477 "lfiwzx %0,%y1"
6478 [(set_attr "type" "fpload")])
6479
6480 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
6481 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6482 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
6483 (clobber (match_scratch:DI 2 "=d"))]
6484 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
6485 && <SI_CONVERT_FP>"
6486 "#"
6487 ""
6488 [(pc)]
6489 "
6490 {
6491 rtx dest = operands[0];
6492 rtx src = operands[1];
6493 rtx tmp;
6494
6495 if (!MEM_P (src) && TARGET_MFPGPR && TARGET_POWERPC64)
6496 tmp = convert_to_mode (DImode, src, true);
6497 else
6498 {
6499 tmp = operands[2];
6500 if (GET_CODE (tmp) == SCRATCH)
6501 tmp = gen_reg_rtx (DImode);
6502 if (MEM_P (src))
6503 {
6504 src = rs6000_address_for_fpconvert (src);
6505 emit_insn (gen_lfiwzx (tmp, src));
6506 }
6507 else
6508 {
6509 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6510 emit_move_insn (stack, src);
6511 emit_insn (gen_lfiwzx (tmp, stack));
6512 }
6513 }
6514 emit_insn (gen_floatdi<mode>2 (dest, tmp));
6515 DONE;
6516 }"
6517 [(set_attr "length" "12")
6518 (set_attr "type" "fpload")])
6519
6520 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
6521 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<rreg2>")
6522 (unsigned_float:SFDF
6523 (zero_extend:DI
6524 (match_operand:SI 1 "memory_operand" "Z,Z"))))
6525 (clobber (match_scratch:DI 2 "=0,d"))]
6526 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX
6527 && <SI_CONVERT_FP>"
6528 "#"
6529 ""
6530 [(pc)]
6531 "
6532 {
6533 operands[1] = rs6000_address_for_fpconvert (operands[1]);
6534 if (GET_CODE (operands[2]) == SCRATCH)
6535 operands[2] = gen_reg_rtx (DImode);
6536 emit_insn (gen_lfiwzx (operands[2], operands[1]));
6537 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
6538 DONE;
6539 }"
6540 [(set_attr "length" "8")
6541 (set_attr "type" "fpload")])
6418 6542
6419 ; For each of these conversions, there is a define_expand, a define_insn 6543 ; For each of these conversions, there is a define_expand, a define_insn
6420 ; with a '#' template, and a define_split (with C code). The idea is 6544 ; with a '#' template, and a define_split (with C code). The idea is
6421 ; to allow constant folding with the template of the define_insn, 6545 ; to allow constant folding with the template of the define_insn,
6422 ; then to have the insns split later (between sched1 and final). 6546 ; then to have the insns split later (between sched1 and final).
6423 6547
6424 (define_expand "floatsidf2" 6548 (define_expand "floatsidf2"
6425 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "") 6549 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
6426 (float:DF (match_operand:SI 1 "gpc_reg_operand" ""))) 6550 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
6427 (use (match_dup 2)) 6551 (use (match_dup 2))
6428 (use (match_dup 3)) 6552 (use (match_dup 3))
6429 (clobber (match_dup 4)) 6553 (clobber (match_dup 4))
6430 (clobber (match_dup 5)) 6554 (clobber (match_dup 5))
6431 (clobber (match_dup 6))])] 6555 (clobber (match_dup 6))])]
6433 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" 6557 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
6434 " 6558 "
6435 { 6559 {
6436 if (TARGET_E500_DOUBLE) 6560 if (TARGET_E500_DOUBLE)
6437 { 6561 {
6562 if (!REG_P (operands[1]))
6563 operands[1] = force_reg (SImode, operands[1]);
6438 emit_insn (gen_spe_floatsidf2 (operands[0], operands[1])); 6564 emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
6439 DONE; 6565 DONE;
6440 } 6566 }
6441 if (TARGET_POWERPC64) 6567 else if (TARGET_LFIWAX && TARGET_FCFID)
6442 { 6568 {
6443 rtx x = convert_to_mode (DImode, operands[1], 0); 6569 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
6444 emit_insn (gen_floatdidf2 (operands[0], x));
6445 DONE; 6570 DONE;
6446 } 6571 }
6447 6572 else if (TARGET_FCFID)
6573 {
6574 rtx dreg = operands[1];
6575 if (!REG_P (dreg))
6576 dreg = force_reg (SImode, dreg);
6577 dreg = convert_to_mode (DImode, dreg, false);
6578 emit_insn (gen_floatdidf2 (operands[0], dreg));
6579 DONE;
6580 }
6581
6582 if (!REG_P (operands[1]))
6583 operands[1] = force_reg (SImode, operands[1]);
6448 operands[2] = force_reg (SImode, GEN_INT (0x43300000)); 6584 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
6449 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode)); 6585 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
6450 operands[4] = assign_stack_temp (DFmode, GET_MODE_SIZE (DFmode), 0); 6586 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
6451 operands[5] = gen_reg_rtx (DFmode); 6587 operands[5] = gen_reg_rtx (DFmode);
6452 operands[6] = gen_reg_rtx (SImode); 6588 operands[6] = gen_reg_rtx (SImode);
6453 }") 6589 }")
6454 6590
6455 (define_insn_and_split "*floatsidf2_internal" 6591 (define_insn_and_split "*floatsidf2_internal"
6458 (use (match_operand:SI 2 "gpc_reg_operand" "r")) 6594 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
6459 (use (match_operand:DF 3 "gpc_reg_operand" "d")) 6595 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
6460 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) 6596 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
6461 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d")) 6597 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
6462 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))] 6598 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
6463 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" 6599 "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
6464 "#" 6600 "#"
6465 "" 6601 ""
6466 [(pc)] 6602 [(pc)]
6467 " 6603 "
6468 { 6604 {
6482 emit_move_insn (highword, operands[2]); 6618 emit_move_insn (highword, operands[2]);
6483 emit_move_insn (operands[5], operands[4]); 6619 emit_move_insn (operands[5], operands[4]);
6484 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3])); 6620 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
6485 DONE; 6621 DONE;
6486 }" 6622 }"
6487 [(set_attr "length" "24")]) 6623 [(set_attr "length" "24")
6488 6624 (set_attr "type" "fp")])
6625
6626 ;; If we don't have a direct conversion to single precision, don't enable this
6627 ;; conversion for 32-bit without fast math, because we don't have the insn to
6628 ;; generate the fixup swizzle to avoid double rounding problems.
6489 (define_expand "floatunssisf2" 6629 (define_expand "floatunssisf2"
6490 [(set (match_operand:SF 0 "gpc_reg_operand" "") 6630 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6491 (unsigned_float:SF (match_operand:SI 1 "gpc_reg_operand" "")))] 6631 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
6492 "TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT" 6632 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6493 "") 6633 && (!TARGET_FPRS
6634 || (TARGET_FPRS
6635 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
6636 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
6637 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
6638 "
6639 {
6640 if (!TARGET_FPRS)
6641 {
6642 if (!REG_P (operands[1]))
6643 operands[1] = force_reg (SImode, operands[1]);
6644 }
6645 else if (TARGET_LFIWZX && TARGET_FCFIDUS)
6646 {
6647 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
6648 DONE;
6649 }
6650 else
6651 {
6652 rtx dreg = operands[1];
6653 if (!REG_P (dreg))
6654 dreg = force_reg (SImode, dreg);
6655 dreg = convert_to_mode (DImode, dreg, true);
6656 emit_insn (gen_floatdisf2 (operands[0], dreg));
6657 DONE;
6658 }
6659 }")
6494 6660
6495 (define_expand "floatunssidf2" 6661 (define_expand "floatunssidf2"
6496 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "") 6662 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
6497 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" ""))) 6663 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
6498 (use (match_dup 2)) 6664 (use (match_dup 2))
6499 (use (match_dup 3)) 6665 (use (match_dup 3))
6500 (clobber (match_dup 4)) 6666 (clobber (match_dup 4))
6501 (clobber (match_dup 5))])] 6667 (clobber (match_dup 5))])]
6502 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" 6668 "TARGET_HARD_FLOAT
6669 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
6503 " 6670 "
6504 { 6671 {
6505 if (TARGET_E500_DOUBLE) 6672 if (TARGET_E500_DOUBLE)
6506 { 6673 {
6674 if (!REG_P (operands[1]))
6675 operands[1] = force_reg (SImode, operands[1]);
6507 emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1])); 6676 emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
6508 DONE; 6677 DONE;
6509 } 6678 }
6510 if (TARGET_POWERPC64) 6679 else if (TARGET_LFIWZX && TARGET_FCFID)
6511 { 6680 {
6512 rtx x = convert_to_mode (DImode, operands[1], 1); 6681 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
6513 emit_insn (gen_floatdidf2 (operands[0], x));
6514 DONE; 6682 DONE;
6515 } 6683 }
6516 6684 else if (TARGET_FCFID)
6685 {
6686 rtx dreg = operands[1];
6687 if (!REG_P (dreg))
6688 dreg = force_reg (SImode, dreg);
6689 dreg = convert_to_mode (DImode, dreg, true);
6690 emit_insn (gen_floatdidf2 (operands[0], dreg));
6691 DONE;
6692 }
6693
6694 if (!REG_P (operands[1]))
6695 operands[1] = force_reg (SImode, operands[1]);
6517 operands[2] = force_reg (SImode, GEN_INT (0x43300000)); 6696 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
6518 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode)); 6697 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
6519 operands[4] = assign_stack_temp (DFmode, GET_MODE_SIZE (DFmode), 0); 6698 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
6520 operands[5] = gen_reg_rtx (DFmode); 6699 operands[5] = gen_reg_rtx (DFmode);
6521 }") 6700 }")
6522 6701
6523 (define_insn_and_split "*floatunssidf2_internal" 6702 (define_insn_and_split "*floatunssidf2_internal"
6524 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d") 6703 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
6525 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) 6704 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
6526 (use (match_operand:SI 2 "gpc_reg_operand" "r")) 6705 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
6527 (use (match_operand:DF 3 "gpc_reg_operand" "d")) 6706 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
6528 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) 6707 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
6529 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))] 6708 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
6530 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" 6709 "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6710 && !(TARGET_FCFID && TARGET_POWERPC64)"
6531 "#" 6711 "#"
6532 "" 6712 ""
6533 [(pc)] 6713 [(pc)]
6534 " 6714 "
6535 { 6715 {
6547 emit_move_insn (highword, operands[2]); 6727 emit_move_insn (highword, operands[2]);
6548 emit_move_insn (operands[5], operands[4]); 6728 emit_move_insn (operands[5], operands[4]);
6549 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3])); 6729 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
6550 DONE; 6730 DONE;
6551 }" 6731 }"
6552 [(set_attr "length" "20")]) 6732 [(set_attr "length" "20")
6553 6733 (set_attr "type" "fp")])
6554 (define_expand "fix_truncdfsi2" 6734
6555 [(parallel [(set (match_operand:SI 0 "fix_trunc_dest_operand" "") 6735 (define_expand "fix_trunc<mode>si2"
6556 (fix:SI (match_operand:DF 1 "gpc_reg_operand" ""))) 6736 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6557 (clobber (match_dup 2)) 6737 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
6558 (clobber (match_dup 3))])] 6738 "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT
6559 "(TARGET_POWER2 || TARGET_POWERPC) 6739 && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)"
6560 && TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)"
6561 " 6740 "
6562 { 6741 {
6563 if (TARGET_E500_DOUBLE) 6742 if (!<E500_CONVERT>)
6564 { 6743 {
6565 emit_insn (gen_spe_fix_truncdfsi2 (operands[0], operands[1])); 6744 rtx tmp, stack;
6566 DONE; 6745
6567 } 6746 if (TARGET_STFIWX)
6568 operands[2] = gen_reg_rtx (DImode); 6747 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], operands[1]));
6569 if (TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS 6748 else
6570 && gpc_reg_operand(operands[0], GET_MODE (operands[0]))) 6749 {
6571 { 6750 tmp = gen_reg_rtx (DImode);
6572 operands[3] = gen_reg_rtx (DImode); 6751 stack = rs6000_allocate_stack_temp (DImode, true, false);
6573 emit_insn (gen_fix_truncdfsi2_mfpgpr (operands[0], operands[1], 6752 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], operands[1],
6574 operands[2], operands[3])); 6753 tmp, stack));
6754 }
6575 DONE; 6755 DONE;
6576 } 6756 }
6577 if (TARGET_PPC_GFXOPT) 6757 }")
6758
6759 ; Like the convert to float patterns, this insn must be split before
6760 ; register allocation so that it can allocate the memory slot if it
6761 ; needed
6762 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
6763 [(set (match_operand:SI 0 "general_operand" "=rm")
6764 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
6765 (clobber (match_scratch:DI 2 "=d"))]
6766 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6767 && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
6768 && TARGET_STFIWX && can_create_pseudo_p ()"
6769 "#"
6770 ""
6771 [(pc)]
6772 {
6773 rtx dest = operands[0];
6774 rtx src = operands[1];
6775 rtx tmp = operands[2];
6776
6777 if (GET_CODE (tmp) == SCRATCH)
6778 tmp = gen_reg_rtx (DImode);
6779
6780 emit_insn (gen_fctiwz_<mode> (tmp, src));
6781 if (MEM_P (dest))
6578 { 6782 {
6579 rtx orig_dest = operands[0]; 6783 dest = rs6000_address_for_fpconvert (dest);
6580 if (! memory_operand (orig_dest, GET_MODE (orig_dest))) 6784 emit_insn (gen_stfiwx (dest, tmp));
6581 operands[0] = assign_stack_temp (SImode, GET_MODE_SIZE (SImode), 0);
6582 emit_insn (gen_fix_truncdfsi2_internal_gfxopt (operands[0], operands[1],
6583 operands[2]));
6584 if (operands[0] != orig_dest)
6585 emit_move_insn (orig_dest, operands[0]);
6586 DONE; 6785 DONE;
6587 } 6786 }
6588 operands[3] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0); 6787 else if (TARGET_MFPGPR && TARGET_POWERPC64)
6589 }") 6788 {
6590 6789 dest = gen_lowpart (DImode, dest);
6591 (define_insn_and_split "*fix_truncdfsi2_internal" 6790 emit_move_insn (dest, tmp);
6592 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 6791 DONE;
6593 (fix:SI (match_operand:DF 1 "gpc_reg_operand" "d"))) 6792 }
6594 (clobber (match_operand:DI 2 "gpc_reg_operand" "=d")) 6793 else
6595 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o"))] 6794 {
6795 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6796 emit_insn (gen_stfiwx (stack, tmp));
6797 emit_move_insn (dest, stack);
6798 DONE;
6799 }
6800 }
6801 [(set_attr "length" "12")
6802 (set_attr "type" "fp")])
6803
6804 (define_insn_and_split "fix_trunc<mode>si2_internal"
6805 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
6806 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
6807 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
6808 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
6596 "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS 6809 "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS
6597 && TARGET_DOUBLE_FLOAT" 6810 && TARGET_DOUBLE_FLOAT"
6598 "#" 6811 "#"
6599 "" 6812 ""
6600 [(pc)] 6813 [(pc)]
6602 { 6815 {
6603 rtx lowword; 6816 rtx lowword;
6604 gcc_assert (MEM_P (operands[3])); 6817 gcc_assert (MEM_P (operands[3]));
6605 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0); 6818 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
6606 6819
6607 emit_insn (gen_fctiwz (operands[2], operands[1])); 6820 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
6608 emit_move_insn (operands[3], operands[2]); 6821 emit_move_insn (operands[3], operands[2]);
6609 emit_move_insn (operands[0], lowword); 6822 emit_move_insn (operands[0], lowword);
6610 DONE; 6823 DONE;
6611 }" 6824 }"
6612 [(set_attr "length" "16")]) 6825 [(set_attr "length" "16")
6613 6826 (set_attr "type" "fp")])
6614 (define_insn_and_split "fix_truncdfsi2_internal_gfxopt" 6827
6615 [(set (match_operand:SI 0 "memory_operand" "=Z") 6828 (define_expand "fix_trunc<mode>di2"
6616 (fix:SI (match_operand:DF 1 "gpc_reg_operand" "d"))) 6829 [(set (match_operand:DI 0 "gpc_reg_operand" "")
6617 (clobber (match_operand:DI 2 "gpc_reg_operand" "=d"))] 6830 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
6618 "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS 6831 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
6619 && TARGET_DOUBLE_FLOAT 6832 && TARGET_FCFID"
6620 && TARGET_PPC_GFXOPT" 6833 "")
6834
6835 (define_insn "*fix_trunc<mode>di2_fctidz"
6836 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6837 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "d")))]
6838 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
6839 && TARGET_FCFID && !VECTOR_UNIT_VSX_P (<MODE>mode)"
6840 "fctidz %0,%1"
6841 [(set_attr "type" "fp")])
6842
6843 (define_expand "fixuns_trunc<mode>si2"
6844 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6845 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
6846 "TARGET_HARD_FLOAT
6847 && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX)
6848 || <E500_CONVERT>)"
6849 "
6850 {
6851 if (!<E500_CONVERT>)
6852 {
6853 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
6854 DONE;
6855 }
6856 }")
6857
6858 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
6859 [(set (match_operand:SI 0 "general_operand" "=rm")
6860 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
6861 (clobber (match_scratch:DI 2 "=d"))]
6862 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ
6863 && TARGET_STFIWX && can_create_pseudo_p ()"
6621 "#" 6864 "#"
6622 "&& 1" 6865 ""
6623 [(pc)] 6866 [(pc)]
6624 " 6867 {
6625 { 6868 rtx dest = operands[0];
6626 emit_insn (gen_fctiwz (operands[2], operands[1])); 6869 rtx src = operands[1];
6627 emit_insn (gen_stfiwx (operands[0], operands[2])); 6870 rtx tmp = operands[2];
6628 DONE; 6871
6629 }" 6872 if (GET_CODE (tmp) == SCRATCH)
6630 [(set_attr "length" "16")]) 6873 tmp = gen_reg_rtx (DImode);
6631 6874
6632 (define_insn_and_split "fix_truncdfsi2_mfpgpr" 6875 emit_insn (gen_fctiwuz_<mode> (tmp, src));
6633 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 6876 if (MEM_P (dest))
6634 (fix:SI (match_operand:DF 1 "gpc_reg_operand" "d"))) 6877 {
6635 (clobber (match_operand:DI 2 "gpc_reg_operand" "=d")) 6878 dest = rs6000_address_for_fpconvert (dest);
6636 (clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))] 6879 emit_insn (gen_stfiwx (dest, tmp));
6637 "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS 6880 DONE;
6638 && TARGET_DOUBLE_FLOAT" 6881 }
6639 "#" 6882 else if (TARGET_MFPGPR && TARGET_POWERPC64)
6640 "&& 1" 6883 {
6641 [(set (match_dup 2) (unspec:DI [(fix:SI (match_dup 1))] UNSPEC_FCTIWZ)) 6884 dest = gen_lowpart (DImode, dest);
6642 (set (match_dup 3) (match_dup 2)) 6885 emit_move_insn (dest, tmp);
6643 (set (match_dup 0) (subreg:SI (match_dup 3) 4))] 6886 DONE;
6644 "" 6887 }
6645 [(set_attr "length" "12")]) 6888 else
6889 {
6890 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6891 emit_insn (gen_stfiwx (stack, tmp));
6892 emit_move_insn (dest, stack);
6893 DONE;
6894 }
6895 }
6896 [(set_attr "length" "12")
6897 (set_attr "type" "fp")])
6898
6899 (define_expand "fixuns_trunc<mode>di2"
6900 [(set (match_operand:DI 0 "register_operand" "")
6901 (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
6902 "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
6903 "")
6904
6905 (define_insn "*fixuns_trunc<mode>di2_fctiduz"
6906 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6907 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "d")))]
6908 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
6909 && TARGET_FCTIDUZ && !VECTOR_UNIT_VSX_P (<MODE>mode)"
6910 "fctiduz %0,%1"
6911 [(set_attr "type" "fp")])
6646 6912
6647 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ)) 6913 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
6648 ; rather than (set (subreg:SI (reg)) (fix:SI ...)) 6914 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
6649 ; because the first makes it clear that operand 0 is not live 6915 ; because the first makes it clear that operand 0 is not live
6650 ; before the instruction. 6916 ; before the instruction.
6651 (define_insn "fctiwz" 6917 (define_insn "fctiwz_<mode>"
6652 [(set (match_operand:DI 0 "gpc_reg_operand" "=d") 6918 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6653 (unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "d"))] 6919 (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))]
6654 UNSPEC_FCTIWZ))] 6920 UNSPEC_FCTIWZ))]
6655 "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS 6921 "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS
6656 && TARGET_DOUBLE_FLOAT" 6922 && TARGET_DOUBLE_FLOAT"
6657 "{fcirz|fctiwz} %0,%1" 6923 "{fcirz|fctiwz} %0,%1"
6658 [(set_attr "type" "fp")]) 6924 [(set_attr "type" "fp")])
6659 6925
6660 (define_expand "btruncdf2" 6926 (define_insn "fctiwuz_<mode>"
6927 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6928 (unspec:DI [(unsigned_fix:SI
6929 (match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>"))]
6930 UNSPEC_FCTIWUZ))]
6931 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ"
6932 "fctiwuz %0,%1"
6933 [(set_attr "type" "fp")])
6934
6935 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
6936 ;; since the friz instruction does not truncate the value if the floating
6937 ;; point value is < LONG_MIN or > LONG_MAX.
6938 (define_insn "*friz"
6661 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 6939 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6662 (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIZ))] 6940 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d"))))]
6663 "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" 6941 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND
6664 "") 6942 && !VECTOR_UNIT_VSX_P (DFmode) && flag_unsafe_math_optimizations
6665 6943 && !flag_trapping_math && TARGET_FRIZ"
6666 (define_insn "*btruncdf2_fpr"
6667 [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
6668 (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIZ))]
6669 "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6670 && !VECTOR_UNIT_VSX_P (DFmode)"
6671 "friz %0,%1" 6944 "friz %0,%1"
6672 [(set_attr "type" "fp")]) 6945 [(set_attr "type" "fp")])
6673 6946
6674 (define_insn "btruncsf2" 6947 ;; Since FCTIWZ doesn't sign extend the upper bits, we have to do a store and a
6675 [(set (match_operand:SF 0 "gpc_reg_operand" "=f") 6948 ;; load to properly sign extend the value, but at least doing a store, load
6676 (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIZ))] 6949 ;; into a GPR to sign extend, a store from the GPR and a load back into the FPR
6677 "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" 6950 ;; if we have 32-bit memory ops
6951 (define_insn_and_split "*round32<mode>2_fprs"
6952 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6953 (float:SFDF
6954 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6955 (clobber (match_scratch:DI 2 "=d"))
6956 (clobber (match_scratch:DI 3 "=d"))]
6957 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6958 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
6959 && can_create_pseudo_p ()"
6960 "#"
6961 ""
6962 [(pc)]
6963 {
6964 rtx dest = operands[0];
6965 rtx src = operands[1];
6966 rtx tmp1 = operands[2];
6967 rtx tmp2 = operands[3];
6968 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6969
6970 if (GET_CODE (tmp1) == SCRATCH)
6971 tmp1 = gen_reg_rtx (DImode);
6972 if (GET_CODE (tmp2) == SCRATCH)
6973 tmp2 = gen_reg_rtx (DImode);
6974
6975 emit_insn (gen_fctiwz_<mode> (tmp1, src));
6976 emit_insn (gen_stfiwx (stack, tmp1));
6977 emit_insn (gen_lfiwax (tmp2, stack));
6978 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6979 DONE;
6980 }
6981 [(set_attr "type" "fpload")
6982 (set_attr "length" "16")])
6983
6984 (define_insn_and_split "*roundu32<mode>2_fprs"
6985 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6986 (unsigned_float:SFDF
6987 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6988 (clobber (match_scratch:DI 2 "=d"))
6989 (clobber (match_scratch:DI 3 "=d"))]
6990 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6991 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU
6992 && can_create_pseudo_p ()"
6993 "#"
6994 ""
6995 [(pc)]
6996 {
6997 rtx dest = operands[0];
6998 rtx src = operands[1];
6999 rtx tmp1 = operands[2];
7000 rtx tmp2 = operands[3];
7001 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
7002
7003 if (GET_CODE (tmp1) == SCRATCH)
7004 tmp1 = gen_reg_rtx (DImode);
7005 if (GET_CODE (tmp2) == SCRATCH)
7006 tmp2 = gen_reg_rtx (DImode);
7007
7008 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
7009 emit_insn (gen_stfiwx (stack, tmp1));
7010 emit_insn (gen_lfiwzx (tmp2, stack));
7011 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
7012 DONE;
7013 }
7014 [(set_attr "type" "fpload")
7015 (set_attr "length" "16")])
7016
7017 ;; No VSX equivalent to fctid
7018 (define_insn "lrint<mode>di2"
7019 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
7020 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
7021 UNSPEC_FCTID))]
7022 "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>"
7023 "fctid %0,%1"
7024 [(set_attr "type" "fp")])
7025
7026 (define_expand "btrunc<mode>2"
7027 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
7028 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
7029 UNSPEC_FRIZ))]
7030 "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>"
7031 "")
7032
7033 (define_insn "*btrunc<mode>2_fpr"
7034 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
7035 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
7036 UNSPEC_FRIZ))]
7037 "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
7038 && !VECTOR_UNIT_VSX_P (<MODE>mode)"
6678 "friz %0,%1" 7039 "friz %0,%1"
6679 [(set_attr "type" "fp")]) 7040 [(set_attr "type" "fp")])
6680 7041
6681 (define_expand "ceildf2" 7042 (define_expand "ceil<mode>2"
6682 [(set (match_operand:DF 0 "gpc_reg_operand" "") 7043 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
6683 (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "")] UNSPEC_FRIP))] 7044 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
6684 "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" 7045 UNSPEC_FRIP))]
6685 "") 7046 "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>"
6686 7047 "")
6687 (define_insn "*ceildf2_fpr" 7048
6688 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 7049 (define_insn "*ceil<mode>2_fpr"
6689 (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIP))] 7050 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6690 "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 7051 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6691 && !VECTOR_UNIT_VSX_P (DFmode)" 7052 UNSPEC_FRIP))]
7053 "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
7054 && !VECTOR_UNIT_VSX_P (<MODE>mode)"
6692 "frip %0,%1" 7055 "frip %0,%1"
6693 [(set_attr "type" "fp")]) 7056 [(set_attr "type" "fp")])
6694 7057
6695 (define_insn "ceilsf2" 7058 (define_expand "floor<mode>2"
6696 [(set (match_operand:SF 0 "gpc_reg_operand" "=f") 7059 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
6697 (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIP))] 7060 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
6698 "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT " 7061 UNSPEC_FRIM))]
6699 "frip %0,%1" 7062 "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>"
6700 [(set_attr "type" "fp")]) 7063 "")
6701 7064
6702 (define_expand "floordf2" 7065 (define_insn "*floor<mode>2_fpr"
6703 [(set (match_operand:DF 0 "gpc_reg_operand" "") 7066 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6704 (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "")] UNSPEC_FRIM))] 7067 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6705 "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" 7068 UNSPEC_FRIM))]
6706 "") 7069 "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>
6707 7070 && !VECTOR_UNIT_VSX_P (<MODE>mode)"
6708 (define_insn "*floordf2_fpr"
6709 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6710 (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIM))]
6711 "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
6712 && !VECTOR_UNIT_VSX_P (DFmode)"
6713 "frim %0,%1" 7071 "frim %0,%1"
6714 [(set_attr "type" "fp")]) 7072 [(set_attr "type" "fp")])
6715 7073
6716 (define_insn "floorsf2"
6717 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6718 (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIM))]
6719 "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
6720 "frim %0,%1"
6721 [(set_attr "type" "fp")])
6722
6723 ;; No VSX equivalent to frin 7074 ;; No VSX equivalent to frin
6724 (define_insn "rounddf2" 7075 (define_insn "round<mode>2"
6725 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 7076 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6726 (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIN))] 7077 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6727 "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" 7078 UNSPEC_FRIN))]
7079 "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT>"
6728 "frin %0,%1" 7080 "frin %0,%1"
6729 [(set_attr "type" "fp")]) 7081 [(set_attr "type" "fp")])
6730
6731 (define_insn "roundsf2"
6732 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6733 (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIN))]
6734 "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
6735 "frin %0,%1"
6736 [(set_attr "type" "fp")])
6737
6738 (define_expand "ftruncdf2"
6739 [(set (match_operand:DF 0 "gpc_reg_operand" "")
6740 (fix:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
6741 "VECTOR_UNIT_VSX_P (DFmode)"
6742 "")
6743 7082
6744 ; An UNSPEC is used so we don't have to support SImode in FP registers. 7083 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6745 (define_insn "stfiwx" 7084 (define_insn "stfiwx"
6746 [(set (match_operand:SI 0 "memory_operand" "=Z") 7085 [(set (match_operand:SI 0 "memory_operand" "=Z")
6747 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d")] 7086 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d")]
6748 UNSPEC_STFIWX))] 7087 UNSPEC_STFIWX))]
6749 "TARGET_PPC_GFXOPT" 7088 "TARGET_PPC_GFXOPT"
6750 "stfiwx %1,%y0" 7089 "stfiwx %1,%y0"
6751 [(set_attr "type" "fpstore")]) 7090 [(set_attr "type" "fpstore")])
6752 7091
7092 ;; If we don't have a direct conversion to single precision, don't enable this
7093 ;; conversion for 32-bit without fast math, because we don't have the insn to
7094 ;; generate the fixup swizzle to avoid double rounding problems.
6753 (define_expand "floatsisf2" 7095 (define_expand "floatsisf2"
6754 [(set (match_operand:SF 0 "gpc_reg_operand" "") 7096 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6755 (float:SF (match_operand:SI 1 "gpc_reg_operand" "")))] 7097 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
6756 "TARGET_HARD_FLOAT && !TARGET_FPRS" 7098 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6757 "") 7099 && (!TARGET_FPRS
7100 || (TARGET_FPRS
7101 && ((TARGET_FCFIDS && TARGET_LFIWAX)
7102 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
7103 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))"
7104 "
7105 {
7106 if (!TARGET_FPRS)
7107 {
7108 if (!REG_P (operands[1]))
7109 operands[1] = force_reg (SImode, operands[1]);
7110 }
7111 else if (TARGET_FCFIDS && TARGET_LFIWAX)
7112 {
7113 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
7114 DONE;
7115 }
7116 else if (TARGET_FCFID && TARGET_LFIWAX)
7117 {
7118 rtx dfreg = gen_reg_rtx (DFmode);
7119 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
7120 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
7121 DONE;
7122 }
7123 else
7124 {
7125 rtx dreg = operands[1];
7126 if (!REG_P (dreg))
7127 dreg = force_reg (SImode, dreg);
7128 dreg = convert_to_mode (DImode, dreg, false);
7129 emit_insn (gen_floatdisf2 (operands[0], dreg));
7130 DONE;
7131 }
7132 }")
6758 7133
6759 (define_expand "floatdidf2" 7134 (define_expand "floatdidf2"
6760 [(set (match_operand:DF 0 "gpc_reg_operand" "") 7135 [(set (match_operand:DF 0 "gpc_reg_operand" "")
6761 (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))] 7136 (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
6762 "(TARGET_POWERPC64 || TARGET_XILINX_FPU || VECTOR_UNIT_VSX_P (DFmode)) 7137 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
6763 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
6764 "") 7138 "")
6765 7139
6766 (define_insn "*floatdidf2_fpr" 7140 (define_insn "*floatdidf2_fpr"
6767 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 7141 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6768 (float:DF (match_operand:DI 1 "gpc_reg_operand" "!d#r")))] 7142 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d")))]
6769 "(TARGET_POWERPC64 || TARGET_XILINX_FPU) 7143 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
6770 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
6771 && !VECTOR_UNIT_VSX_P (DFmode)" 7144 && !VECTOR_UNIT_VSX_P (DFmode)"
6772 "fcfid %0,%1" 7145 "fcfid %0,%1"
6773 [(set_attr "type" "fp")]) 7146 [(set_attr "type" "fp")])
6774 7147
7148 ; Allow the combiner to merge source memory operands to the conversion so that
7149 ; the optimizer/register allocator doesn't try to load the value too early in a
7150 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
7151 ; hit. We will split after reload to avoid the trip through the GPRs
7152
7153 (define_insn_and_split "*floatdidf2_mem"
7154 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7155 (float:DF (match_operand:DI 1 "memory_operand" "m")))
7156 (clobber (match_scratch:DI 2 "=d"))]
7157 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID"
7158 "#"
7159 "&& reload_completed"
7160 [(set (match_dup 2) (match_dup 1))
7161 (set (match_dup 0) (float:DF (match_dup 2)))]
7162 ""
7163 [(set_attr "length" "8")
7164 (set_attr "type" "fpload")])
7165
6775 (define_expand "floatunsdidf2" 7166 (define_expand "floatunsdidf2"
6776 [(set (match_operand:DF 0 "gpc_reg_operand" "") 7167 [(set (match_operand:DF 0 "gpc_reg_operand" "")
6777 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "")))] 7168 (unsigned_float:DF
6778 "TARGET_VSX" 7169 (match_operand:DI 1 "gpc_reg_operand" "")))]
6779 "") 7170 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6780 7171 "")
6781 (define_expand "fix_truncdfdi2" 7172
6782 [(set (match_operand:DI 0 "gpc_reg_operand" "") 7173 (define_insn "*floatunsdidf2_fcfidu"
6783 (fix:DI (match_operand:DF 1 "gpc_reg_operand" "")))] 7174 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6784 "(TARGET_POWERPC64 || TARGET_XILINX_FPU || VECTOR_UNIT_VSX_P (DFmode)) 7175 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d")))]
6785 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS" 7176 "TARGET_HARD_FLOAT && TARGET_FCFIDU && !VECTOR_UNIT_VSX_P (DFmode)"
6786 "") 7177 "fcfidu %0,%1"
6787 7178 [(set_attr "type" "fp")
6788 (define_insn "*fix_truncdfdi2_fpr" 7179 (set_attr "length" "4")])
6789 [(set (match_operand:DI 0 "gpc_reg_operand" "=!d#r") 7180
6790 (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d")))] 7181 (define_insn_and_split "*floatunsdidf2_mem"
6791 "(TARGET_POWERPC64 || TARGET_XILINX_FPU) 7182 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6792 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS 7183 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m")))
6793 && !VECTOR_UNIT_VSX_P (DFmode)" 7184 (clobber (match_scratch:DI 2 "=d"))]
6794 "fctidz %0,%1" 7185 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6795 [(set_attr "type" "fp")]) 7186 "#"
7187 "&& reload_completed"
7188 [(set (match_dup 2) (match_dup 1))
7189 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
7190 ""
7191 [(set_attr "length" "8")
7192 (set_attr "type" "fpload")])
6796 7193
6797 (define_expand "floatdisf2" 7194 (define_expand "floatdisf2"
6798 [(set (match_operand:SF 0 "gpc_reg_operand" "") 7195 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6799 (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))] 7196 (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6800 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT " 7197 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7198 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6801 " 7199 "
6802 { 7200 {
6803 rtx val = operands[1]; 7201 if (!TARGET_FCFIDS)
6804 if (!flag_unsafe_math_optimizations)
6805 { 7202 {
6806 rtx label = gen_label_rtx (); 7203 rtx val = operands[1];
6807 val = gen_reg_rtx (DImode); 7204 if (!flag_unsafe_math_optimizations)
6808 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label)); 7205 {
6809 emit_label (label); 7206 rtx label = gen_label_rtx ();
7207 val = gen_reg_rtx (DImode);
7208 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
7209 emit_label (label);
7210 }
7211 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
7212 DONE;
6810 } 7213 }
6811 emit_insn (gen_floatdisf2_internal1 (operands[0], val)); 7214 }")
7215
7216 (define_insn "floatdisf2_fcfids"
7217 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7218 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))]
7219 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7220 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
7221 "fcfids %0,%1"
7222 [(set_attr "type" "fp")])
7223
7224 (define_insn_and_split "*floatdisf2_mem"
7225 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7226 (float:SF (match_operand:DI 1 "memory_operand" "m")))
7227 (clobber (match_scratch:DI 2 "=f"))]
7228 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7229 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
7230 "#"
7231 "&& reload_completed"
7232 [(pc)]
7233 "
7234 {
7235 emit_move_insn (operands[2], operands[1]);
7236 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6812 DONE; 7237 DONE;
6813 }") 7238 }"
7239 [(set_attr "length" "8")])
6814 7240
6815 ;; This is not IEEE compliant if rounding mode is "round to nearest". 7241 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6816 ;; If the DI->DF conversion is inexact, then it's possible to suffer 7242 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6817 ;; from double rounding. 7243 ;; from double rounding.
7244 ;; Instead of creating a new cpu type for two FP operations, just use fp
6818 (define_insn_and_split "floatdisf2_internal1" 7245 (define_insn_and_split "floatdisf2_internal1"
6819 [(set (match_operand:SF 0 "gpc_reg_operand" "=f") 7246 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6820 (float:SF (match_operand:DI 1 "gpc_reg_operand" "!d#r"))) 7247 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6821 (clobber (match_scratch:DF 2 "=d"))] 7248 (clobber (match_scratch:DF 2 "=d"))]
6822 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" 7249 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
6823 "#" 7250 "#"
6824 "&& reload_completed" 7251 "&& reload_completed"
6825 [(set (match_dup 2) 7252 [(set (match_dup 2)
6826 (float:DF (match_dup 1))) 7253 (float:DF (match_dup 1)))
6827 (set (match_dup 0) 7254 (set (match_dup 0)
6828 (float_truncate:SF (match_dup 2)))] 7255 (float_truncate:SF (match_dup 2)))]
6829 "") 7256 ""
7257 [(set_attr "length" "8")
7258 (set_attr "type" "fp")])
6830 7259
6831 ;; Twiddles bits to avoid double rounding. 7260 ;; Twiddles bits to avoid double rounding.
6832 ;; Bits that might be truncated when converting to DFmode are replaced 7261 ;; Bits that might be truncated when converting to DFmode are replaced
6833 ;; by a bit that won't be lost at that stage, but is below the SFmode 7262 ;; by a bit that won't be lost at that stage, but is below the SFmode
6834 ;; rounding position. 7263 ;; rounding position.
6857 " 7286 "
6858 { 7287 {
6859 operands[3] = gen_reg_rtx (DImode); 7288 operands[3] = gen_reg_rtx (DImode);
6860 operands[4] = gen_reg_rtx (CCUNSmode); 7289 operands[4] = gen_reg_rtx (CCUNSmode);
6861 }") 7290 }")
7291
7292 (define_expand "floatunsdisf2"
7293 [(set (match_operand:SF 0 "gpc_reg_operand" "")
7294 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
7295 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7296 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
7297 "")
7298
7299 (define_insn "floatunsdisf2_fcfidus"
7300 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7301 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))]
7302 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7303 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
7304 "fcfidus %0,%1"
7305 [(set_attr "type" "fp")])
7306
7307 (define_insn_and_split "*floatunsdisf2_mem"
7308 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7309 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m")))
7310 (clobber (match_scratch:DI 2 "=f"))]
7311 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
7312 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
7313 "#"
7314 "&& reload_completed"
7315 [(pc)]
7316 "
7317 {
7318 emit_move_insn (operands[2], operands[1]);
7319 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
7320 DONE;
7321 }"
7322 [(set_attr "length" "8")
7323 (set_attr "type" "fpload")])
6862 7324
6863 ;; Define the DImode operations that can be done in a small number 7325 ;; Define the DImode operations that can be done in a small number
6864 ;; of instructions. The & constraints are to prevent the register 7326 ;; of instructions. The & constraints are to prevent the register
6865 ;; allocator from allocating registers that overlap with the inputs 7327 ;; allocator from allocating registers that overlap with the inputs
6866 ;; (for example, having an input in 7,8 and an output in 6,7). We 7328 ;; (for example, having an input in 7,8 and an output in 6,7). We
9139 switch (which_alternative) 9601 switch (which_alternative)
9140 { 9602 {
9141 default: 9603 default:
9142 gcc_unreachable (); 9604 gcc_unreachable ();
9143 case 0: 9605 case 0:
9144 /* We normally copy the low-numbered register first. However, if
9145 the first register operand 0 is the same as the second register
9146 of operand 1, we must copy in the opposite order. */
9147 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
9148 return \"mr %L0,%L1\;mr %0,%1\";
9149 else
9150 return \"mr %0,%1\;mr %L0,%L1\";
9151 case 1: 9606 case 1:
9152 if (rs6000_offsettable_memref_p (operands[1])
9153 || (GET_CODE (operands[1]) == MEM
9154 && (GET_CODE (XEXP (operands[1], 0)) == LO_SUM
9155 || GET_CODE (XEXP (operands[1], 0)) == PRE_INC
9156 || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC
9157 || GET_CODE (XEXP (operands[1], 0)) == PRE_MODIFY)))
9158 {
9159 /* If the low-address word is used in the address, we must load
9160 it last. Otherwise, load it first. Note that we cannot have
9161 auto-increment in that case since the address register is
9162 known to be dead. */
9163 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
9164 operands[1], 0))
9165 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
9166 else
9167 return \"{l%U1%X1|lwz%U1%X1} %0,%1\;{l|lwz} %L0,%L1\";
9168 }
9169 else
9170 {
9171 rtx addreg;
9172
9173 addreg = find_addr_reg (XEXP (operands[1], 0));
9174 if (refers_to_regno_p (REGNO (operands[0]),
9175 REGNO (operands[0]) + 1,
9176 operands[1], 0))
9177 {
9178 output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg);
9179 output_asm_insn (\"{l%X1|lwz%X1} %L0,%1\", operands);
9180 output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg);
9181 return \"{l%X1|lwz%X1} %0,%1\";
9182 }
9183 else
9184 {
9185 output_asm_insn (\"{l%X1|lwz%X1} %0,%1\", operands);
9186 output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg);
9187 output_asm_insn (\"{l%X1|lwz%X1} %L0,%1\", operands);
9188 output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg);
9189 return \"\";
9190 }
9191 }
9192 case 2: 9607 case 2:
9193 if (rs6000_offsettable_memref_p (operands[0]) 9608 return \"#\";
9194 || (GET_CODE (operands[0]) == MEM
9195 && (GET_CODE (XEXP (operands[0], 0)) == LO_SUM
9196 || GET_CODE (XEXP (operands[0], 0)) == PRE_INC
9197 || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
9198 || GET_CODE (XEXP (operands[0], 0)) == PRE_MODIFY)))
9199 return \"{st%U0%X0|stw%U0%X0} %1,%0\;{st|stw} %L1,%L0\";
9200 else
9201 {
9202 rtx addreg;
9203
9204 addreg = find_addr_reg (XEXP (operands[0], 0));
9205 output_asm_insn (\"{st%X0|stw%X0} %1,%0\", operands);
9206 output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg);
9207 output_asm_insn (\"{st%X0|stw%X0} %L1,%0\", operands);
9208 output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg);
9209 return \"\";
9210 }
9211 case 3: 9609 case 3:
9212 case 4: 9610 case 4:
9213 return \"xxlor %x0,%x1,%x1\"; 9611 return \"xxlor %x0,%x1,%x1\";
9214 case 5: 9612 case 5:
9215 case 6: 9613 case 6:
9240 "! TARGET_POWERPC64 9638 "! TARGET_POWERPC64
9241 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) 9639 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT)
9242 || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE) 9640 || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE)
9243 && (gpc_reg_operand (operands[0], DFmode) 9641 && (gpc_reg_operand (operands[0], DFmode)
9244 || gpc_reg_operand (operands[1], DFmode))" 9642 || gpc_reg_operand (operands[1], DFmode))"
9245 "* 9643 "#"
9246 {
9247 switch (which_alternative)
9248 {
9249 default:
9250 gcc_unreachable ();
9251 case 0:
9252 /* We normally copy the low-numbered register first. However, if
9253 the first register operand 0 is the same as the second register of
9254 operand 1, we must copy in the opposite order. */
9255 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
9256 return \"mr %L0,%L1\;mr %0,%1\";
9257 else
9258 return \"mr %0,%1\;mr %L0,%L1\";
9259 case 1:
9260 /* If the low-address word is used in the address, we must load
9261 it last. Otherwise, load it first. Note that we cannot have
9262 auto-increment in that case since the address register is
9263 known to be dead. */
9264 if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
9265 operands[1], 0))
9266 return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
9267 else
9268 return \"{l%U1%X1|lwz%U1%X1} %0,%1\;{l|lwz} %L0,%L1\";
9269 case 2:
9270 return \"{st%U0%X0|stw%U0%X0} %1,%0\;{st|stw} %L1,%L0\";
9271 case 3:
9272 case 4:
9273 case 5:
9274 return \"#\";
9275 }
9276 }"
9277 [(set_attr "type" "two,load,store,*,*,*") 9644 [(set_attr "type" "two,load,store,*,*,*")
9278 (set_attr "length" "8,8,8,8,12,16")]) 9645 (set_attr "length" "8,8,8,8,12,16")])
9279 9646
9280 ; ld/std require word-aligned displacements -> 'Y' constraint. 9647 ; ld/std require word-aligned displacements -> 'Y' constraint.
9281 ; List Y->r and r->Y before r->r for reload. 9648 ; List Y->r and r->Y before r->r for reload.
9601 emit_insn (gen_fix_trunc_helper (operands[2], operands[1], operands[3])); 9968 emit_insn (gen_fix_trunc_helper (operands[2], operands[1], operands[3]));
9602 9969
9603 gcc_assert (MEM_P (operands[5])); 9970 gcc_assert (MEM_P (operands[5]));
9604 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0); 9971 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
9605 9972
9606 emit_insn (gen_fctiwz (operands[4], operands[2])); 9973 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
9607 emit_move_insn (operands[5], operands[4]); 9974 emit_move_insn (operands[5], operands[4]);
9608 emit_move_insn (operands[0], lowword); 9975 emit_move_insn (operands[0], lowword);
9609 DONE; 9976 DONE;
9610 }) 9977 })
9611 9978
9683 ;; multiple insns. 10050 ;; multiple insns.
9684 10051
9685 ; List r->r after r->"o<>", otherwise reload will try to reload a 10052 ; List r->r after r->"o<>", otherwise reload will try to reload a
9686 ; non-offsettable address by using r->r which won't make progress. 10053 ; non-offsettable address by using r->r which won't make progress.
9687 (define_insn "*movdi_internal32" 10054 (define_insn "*movdi_internal32"
9688 [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=o<>,r,r,*d,*d,m,r") 10055 [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=o<>,r,r,*d,*d,m,r,?wa")
9689 (match_operand:DI 1 "input_operand" "r,r,m,d,m,d,IJKnGHF"))] 10056 (match_operand:DI 1 "input_operand" "r,r,m,d,m,d,IJKnGHF,O"))]
9690 "! TARGET_POWERPC64 10057 "! TARGET_POWERPC64
9691 && (gpc_reg_operand (operands[0], DImode) 10058 && (gpc_reg_operand (operands[0], DImode)
9692 || gpc_reg_operand (operands[1], DImode))" 10059 || gpc_reg_operand (operands[1], DImode))"
9693 "@ 10060 "@
9694 # 10061 #
9695 # 10062 #
9696 # 10063 #
9697 fmr %0,%1 10064 fmr %0,%1
9698 lfd%U1%X1 %0,%1 10065 lfd%U1%X1 %0,%1
9699 stfd%U0%X0 %1,%0 10066 stfd%U0%X0 %1,%0
9700 #" 10067 #
9701 [(set_attr "type" "load,*,store,fp,fpload,fpstore,*")]) 10068 xxlxor %x0,%x0,%x0"
10069 [(set_attr "type" "load,*,store,fp,fpload,fpstore,*,vecsimple")])
9702 10070
9703 (define_split 10071 (define_split
9704 [(set (match_operand:DI 0 "gpc_reg_operand" "") 10072 [(set (match_operand:DI 0 "gpc_reg_operand" "")
9705 (match_operand:DI 1 "const_int_operand" ""))] 10073 (match_operand:DI 1 "const_int_operand" ""))]
9706 "! TARGET_POWERPC64 && reload_completed" 10074 "! TARGET_POWERPC64 && reload_completed
10075 && gpr_or_gpr_p (operands[0], operands[1])"
9707 [(set (match_dup 2) (match_dup 4)) 10076 [(set (match_dup 2) (match_dup 4))
9708 (set (match_dup 3) (match_dup 1))] 10077 (set (match_dup 3) (match_dup 1))]
9709 " 10078 "
9710 { 10079 {
9711 HOST_WIDE_INT value = INTVAL (operands[1]); 10080 HOST_WIDE_INT value = INTVAL (operands[1]);
9720 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); 10089 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
9721 #endif 10090 #endif
9722 }") 10091 }")
9723 10092
9724 (define_split 10093 (define_split
9725 [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "") 10094 [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
9726 (match_operand:DI 1 "input_operand" ""))] 10095 (match_operand:DIFD 1 "input_operand" ""))]
9727 "reload_completed && !TARGET_POWERPC64 10096 "reload_completed && !TARGET_POWERPC64
9728 && gpr_or_gpr_p (operands[0], operands[1])" 10097 && gpr_or_gpr_p (operands[0], operands[1])"
9729 [(pc)] 10098 [(pc)]
9730 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) 10099 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
9731 10100
9753 mffgpr %0,%1" 10122 mffgpr %0,%1"
9754 [(set_attr "type" "*,load,store,*,*,*,*,fp,fpload,fpstore,mfjmpr,mtjmpr,*,mftgpr,mffgpr") 10123 [(set_attr "type" "*,load,store,*,*,*,*,fp,fpload,fpstore,mfjmpr,mtjmpr,*,mftgpr,mffgpr")
9755 (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4")]) 10124 (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4")])
9756 10125
9757 (define_insn "*movdi_internal64" 10126 (define_insn "*movdi_internal64"
9758 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,*d,*d,m,r,*h,*h") 10127 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,*d,*d,m,r,*h,*h,?wa")
9759 (match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,d,m,d,*h,r,0"))] 10128 (match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,d,m,d,*h,r,0,O"))]
9760 "TARGET_POWERPC64 && (!TARGET_MFPGPR || !TARGET_HARD_FLOAT || !TARGET_FPRS) 10129 "TARGET_POWERPC64 && (!TARGET_MFPGPR || !TARGET_HARD_FLOAT || !TARGET_FPRS)
9761 && (gpc_reg_operand (operands[0], DImode) 10130 && (gpc_reg_operand (operands[0], DImode)
9762 || gpc_reg_operand (operands[1], DImode))" 10131 || gpc_reg_operand (operands[1], DImode))"
9763 "@ 10132 "@
9764 mr %0,%1 10133 mr %0,%1
9771 fmr %0,%1 10140 fmr %0,%1
9772 lfd%U1%X1 %0,%1 10141 lfd%U1%X1 %0,%1
9773 stfd%U0%X0 %1,%0 10142 stfd%U0%X0 %1,%0
9774 mf%1 %0 10143 mf%1 %0
9775 mt%0 %1 10144 mt%0 %1
9776 {cror 0,0,0|nop}" 10145 {cror 0,0,0|nop}
9777 [(set_attr "type" "*,load,store,*,*,*,*,fp,fpload,fpstore,mfjmpr,mtjmpr,*") 10146 xxlxor %x0,%x0,%x0"
9778 (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4")]) 10147 [(set_attr "type" "*,load,store,*,*,*,*,fp,fpload,fpstore,mfjmpr,mtjmpr,*,vecsimple")
10148 (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4")])
9779 10149
9780 ;; immediate value valid for a single instruction hiding in a const_double 10150 ;; immediate value valid for a single instruction hiding in a const_double
9781 (define_insn "" 10151 (define_insn ""
9782 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 10152 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9783 (match_operand:DI 1 "const_double_operand" "F"))] 10153 (match_operand:DI 1 "const_double_operand" "F"))]
11063 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 11433 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
11064 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 11434 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
11065 UNSPEC_TLSGD) 11435 UNSPEC_TLSGD)
11066 (clobber (reg:SI LR_REGNO))] 11436 (clobber (reg:SI LR_REGNO))]
11067 "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX" 11437 "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX"
11068 "addi %0,%1,%2@got@tlsgd\;bl %z3\;%." 11438 {
11439 if (TARGET_CMODEL != CMODEL_SMALL)
11440 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;bl %z3\;%.";
11441 else
11442 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;%.";
11443 }
11069 "&& TARGET_TLS_MARKERS" 11444 "&& TARGET_TLS_MARKERS"
11070 [(set (match_dup 0) 11445 [(set (match_dup 0)
11071 (unspec:TLSmode [(match_dup 1) 11446 (unspec:TLSmode [(match_dup 1)
11072 (match_dup 2)] 11447 (match_dup 2)]
11073 UNSPEC_TLSGD)) 11448 UNSPEC_TLSGD))
11076 (match_dup 4))) 11451 (match_dup 4)))
11077 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD) 11452 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
11078 (clobber (reg:SI LR_REGNO))])] 11453 (clobber (reg:SI LR_REGNO))])]
11079 "" 11454 ""
11080 [(set_attr "type" "two") 11455 [(set_attr "type" "two")
11081 (set_attr "length" "12")]) 11456 (set (attr "length")
11457 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
11458 (const_int 16)
11459 (const_int 12)))])
11082 11460
11083 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>" 11461 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
11084 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 11462 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
11085 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s")) 11463 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
11086 (match_operand 4 "" "g"))) 11464 (match_operand 4 "" "g")))
11112 (clobber (reg:SI LR_REGNO))])] 11490 (clobber (reg:SI LR_REGNO))])]
11113 "" 11491 ""
11114 [(set_attr "type" "two") 11492 [(set_attr "type" "two")
11115 (set_attr "length" "8")]) 11493 (set_attr "length" "8")])
11116 11494
11117 (define_insn "*tls_gd<TLSmode:tls_abi_suffix>" 11495 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
11118 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 11496 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
11119 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 11497 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
11120 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 11498 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
11121 UNSPEC_TLSGD))] 11499 UNSPEC_TLSGD))]
11122 "HAVE_AS_TLS && TARGET_TLS_MARKERS" 11500 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
11123 "addi %0,%1,%2@got@tlsgd" 11501 "addi %0,%1,%2@got@tlsgd"
11502 "&& TARGET_CMODEL != CMODEL_SMALL"
11503 [(set (match_dup 3)
11504 (plus:TLSmode (match_dup 1)
11505 (high:TLSmode
11506 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD))))
11507 (set (match_dup 0)
11508 (lo_sum:TLSmode (match_dup 3)
11509 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)))]
11510 "
11511 {
11512 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
11513 }"
11514 [(set (attr "length")
11515 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
11516 (const_int 8)
11517 (const_int 4)))])
11518
11519 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
11520 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
11521 (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
11522 (high:TLSmode
11523 (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
11524 UNSPEC_TLSGD))))]
11525 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
11526 "addis %0,%1,%2@got@tlsgd@ha"
11527 [(set_attr "length" "4")])
11528
11529 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
11530 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
11531 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
11532 (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
11533 UNSPEC_TLSGD)))]
11534 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
11535 "addi %0,%1,%2@got@tlsgd@l"
11124 [(set_attr "length" "4")]) 11536 [(set_attr "length" "4")])
11125 11537
11126 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>" 11538 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
11127 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 11539 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
11128 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) 11540 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
11161 (match_operand 3 "" "g"))) 11573 (match_operand 3 "" "g")))
11162 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")] 11574 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
11163 UNSPEC_TLSLD) 11575 UNSPEC_TLSLD)
11164 (clobber (reg:SI LR_REGNO))] 11576 (clobber (reg:SI LR_REGNO))]
11165 "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX" 11577 "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX"
11166 "addi %0,%1,%&@got@tlsld\;bl %z2\;%." 11578 {
11579 if (TARGET_CMODEL != CMODEL_SMALL)
11580 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;bl %z2\;%.";
11581 else
11582 return "addi %0,%1,%&@got@tlsld\;bl %z2\;%.";
11583 }
11167 "&& TARGET_TLS_MARKERS" 11584 "&& TARGET_TLS_MARKERS"
11168 [(set (match_dup 0) 11585 [(set (match_dup 0)
11169 (unspec:TLSmode [(match_dup 1)] 11586 (unspec:TLSmode [(match_dup 1)]
11170 UNSPEC_TLSLD)) 11587 UNSPEC_TLSLD))
11171 (parallel [(set (match_dup 0) 11588 (parallel [(set (match_dup 0)
11172 (call (mem:TLSmode (match_dup 2)) 11589 (call (mem:TLSmode (match_dup 2))
11173 (match_dup 3))) 11590 (match_dup 3)))
11174 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) 11591 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
11175 (clobber (reg:SI LR_REGNO))])] 11592 (clobber (reg:SI LR_REGNO))])]
11176 "" 11593 ""
11177 [(set_attr "length" "12")]) 11594 [(set_attr "type" "two")
11595 (set (attr "length")
11596 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
11597 (const_int 16)
11598 (const_int 12)))])
11178 11599
11179 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>" 11600 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
11180 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 11601 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
11181 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s")) 11602 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
11182 (match_operand 3 "" "g"))) 11603 (match_operand 3 "" "g")))
11205 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) 11626 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
11206 (clobber (reg:SI LR_REGNO))])] 11627 (clobber (reg:SI LR_REGNO))])]
11207 "" 11628 ""
11208 [(set_attr "length" "8")]) 11629 [(set_attr "length" "8")])
11209 11630
11210 (define_insn "*tls_ld<TLSmode:tls_abi_suffix>" 11631 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
11211 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 11632 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
11212 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")] 11633 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
11213 UNSPEC_TLSLD))] 11634 UNSPEC_TLSLD))]
11214 "HAVE_AS_TLS && TARGET_TLS_MARKERS" 11635 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
11215 "addi %0,%1,%&@got@tlsld" 11636 "addi %0,%1,%&@got@tlsld"
11637 "&& TARGET_CMODEL != CMODEL_SMALL"
11638 [(set (match_dup 2)
11639 (plus:TLSmode (match_dup 1)
11640 (high:TLSmode
11641 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD))))
11642 (set (match_dup 0)
11643 (lo_sum:TLSmode (match_dup 2)
11644 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)))]
11645 "
11646 {
11647 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
11648 }"
11649 [(set (attr "length")
11650 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
11651 (const_int 8)
11652 (const_int 4)))])
11653
11654 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
11655 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
11656 (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
11657 (high:TLSmode
11658 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD))))]
11659 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
11660 "addis %0,%1,%&@got@tlsld@ha"
11661 [(set_attr "length" "4")])
11662
11663 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
11664 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
11665 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
11666 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)))]
11667 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
11668 "addi %0,%1,%&@got@tlsld@l"
11216 [(set_attr "length" "4")]) 11669 [(set_attr "length" "4")])
11217 11670
11218 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>" 11671 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
11219 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 11672 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
11220 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) 11673 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
11267 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 11720 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
11268 UNSPEC_TLSDTPRELLO))] 11721 UNSPEC_TLSDTPRELLO))]
11269 "HAVE_AS_TLS" 11722 "HAVE_AS_TLS"
11270 "addi %0,%1,%2@dtprel@l") 11723 "addi %0,%1,%2@dtprel@l")
11271 11724
11272 (define_insn "tls_got_dtprel_<TLSmode:tls_abi_suffix>" 11725 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
11273 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 11726 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
11274 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 11727 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
11275 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 11728 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
11276 UNSPEC_TLSGOTDTPREL))] 11729 UNSPEC_TLSGOTDTPREL))]
11277 "HAVE_AS_TLS" 11730 "HAVE_AS_TLS"
11278 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)") 11731 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
11732 "&& TARGET_CMODEL != CMODEL_SMALL"
11733 [(set (match_dup 3)
11734 (plus:TLSmode (match_dup 1)
11735 (high:TLSmode
11736 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTDTPREL))))
11737 (set (match_dup 0)
11738 (lo_sum:TLSmode (match_dup 3)
11739 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
11740 "
11741 {
11742 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
11743 }"
11744 [(set (attr "length")
11745 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
11746 (const_int 8)
11747 (const_int 4)))])
11748
11749 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
11750 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
11751 (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
11752 (high:TLSmode
11753 (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
11754 UNSPEC_TLSGOTDTPREL))))]
11755 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
11756 "addis %0,%1,%2@got@dtprel@ha"
11757 [(set_attr "length" "4")])
11758
11759 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
11760 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
11761 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
11762 (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
11763 UNSPEC_TLSGOTDTPREL)))]
11764 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
11765 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
11766 [(set_attr "length" "4")])
11279 11767
11280 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>" 11768 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
11281 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 11769 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
11282 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 11770 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
11283 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 11771 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
11302 "addi %0,%1,%2@tprel@l") 11790 "addi %0,%1,%2@tprel@l")
11303 11791
11304 ;; "b" output constraint here and on tls_tls input to support linker tls 11792 ;; "b" output constraint here and on tls_tls input to support linker tls
11305 ;; optimization. The linker may edit the instructions emitted by a 11793 ;; optimization. The linker may edit the instructions emitted by a
11306 ;; tls_got_tprel/tls_tls pair to addis,addi. 11794 ;; tls_got_tprel/tls_tls pair to addis,addi.
11307 (define_insn "tls_got_tprel_<TLSmode:tls_abi_suffix>" 11795 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
11308 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 11796 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
11309 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 11797 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
11310 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 11798 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
11311 UNSPEC_TLSGOTTPREL))] 11799 UNSPEC_TLSGOTTPREL))]
11312 "HAVE_AS_TLS" 11800 "HAVE_AS_TLS"
11313 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)") 11801 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
11802 "&& TARGET_CMODEL != CMODEL_SMALL"
11803 [(set (match_dup 3)
11804 (plus:TLSmode (match_dup 1)
11805 (high:TLSmode
11806 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTTPREL))))
11807 (set (match_dup 0)
11808 (lo_sum:TLSmode (match_dup 3)
11809 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGOTTPREL)))]
11810 "
11811 {
11812 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
11813 }"
11814 [(set (attr "length")
11815 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
11816 (const_int 8)
11817 (const_int 4)))])
11818
11819 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
11820 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
11821 (plus:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
11822 (high:TLSmode
11823 (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
11824 UNSPEC_TLSGOTTPREL))))]
11825 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
11826 "addis %0,%1,%2@got@tprel@ha"
11827 [(set_attr "length" "4")])
11828
11829 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
11830 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
11831 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
11832 (unspec:TLSmode [(match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
11833 UNSPEC_TLSGOTTPREL)))]
11834 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
11835 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
11836 [(set_attr "length" "4")])
11314 11837
11315 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>" 11838 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
11316 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 11839 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
11317 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 11840 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
11318 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 11841 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
11319 UNSPEC_TLSTLS))] 11842 UNSPEC_TLSTLS))]
11320 "HAVE_AS_TLS" 11843 "HAVE_AS_TLS"
11321 "add %0,%1,%2@tls") 11844 "add %0,%1,%2@tls")
11322
11323 11845
11324 ;; Next come insns related to the calling sequence. 11846 ;; Next come insns related to the calling sequence.
11325 ;; 11847 ;;
11326 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca). 11848 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
11327 ;; We move the back-chain and decrement the stack pointer. 11849 ;; We move the back-chain and decrement the stack pointer.
11519 [(set_attr "type" "branch") 12041 [(set_attr "type" "branch")
11520 (set_attr "length" "4")]) 12042 (set_attr "length" "4")])
11521 12043
11522 (define_insn "load_toc_v4_PIC_1b" 12044 (define_insn "load_toc_v4_PIC_1b"
11523 [(set (reg:SI LR_REGNO) 12045 [(set (reg:SI LR_REGNO)
11524 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")] 12046 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
11525 UNSPEC_TOCPTR))] 12047 (label_ref (match_operand 1 "" ""))]
12048 UNSPEC_TOCPTR))
12049 (match_dup 1)]
11526 "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2" 12050 "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"
11527 "bcl 20,31,$+8\\n\\t.long %0-$" 12051 "bcl 20,31,$+8\;.long %0-$"
11528 [(set_attr "type" "branch") 12052 [(set_attr "type" "branch")
11529 (set_attr "length" "8")]) 12053 (set_attr "length" "8")])
11530 12054
11531 (define_insn "load_toc_v4_PIC_2" 12055 (define_insn "load_toc_v4_PIC_2"
11532 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 12056 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11536 "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2" 12060 "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"
11537 "{l|lwz} %0,%2-%3(%1)" 12061 "{l|lwz} %0,%2-%3(%1)"
11538 [(set_attr "type" "load")]) 12062 [(set_attr "type" "load")])
11539 12063
11540 (define_insn "load_toc_v4_PIC_3b" 12064 (define_insn "load_toc_v4_PIC_3b"
11541 [(set (match_operand:SI 0 "gpc_reg_operand" "=b") 12065 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11542 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r") 12066 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
11543 (high:SI 12067 (high:SI
11544 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s") 12068 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
11545 (match_operand:SI 3 "symbol_ref_operand" "s")))))] 12069 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
11546 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic" 12070 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic"
11547 "{cau|addis} %0,%1,%2-%3@ha") 12071 "{cau|addis} %0,%1,%2-%3@ha")
11605 (match_operand 2 "" "")))] 12129 (match_operand 2 "" "")))]
11606 "TARGET_ELF && ! TARGET_64BIT" 12130 "TARGET_ELF && ! TARGET_64BIT"
11607 "@ 12131 "@
11608 {cal|la} %0,%2@l(%1) 12132 {cal|la} %0,%2@l(%1)
11609 {ai|addic} %0,%1,%K2") 12133 {ai|addic} %0,%1,%K2")
12134
12135 ;; Largetoc support
12136 (define_insn "largetoc_high"
12137 [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
12138 (plus:DI (match_operand:DI 1 "gpc_reg_operand" "b")
12139 (high:DI (match_operand:DI 2 "" ""))))]
12140 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
12141 "{cau|addis} %0,%1,%2@ha")
12142
12143 (define_insn "largetoc_low"
12144 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12145 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
12146 (match_operand:DI 2 "" "")))]
12147 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
12148 "{cal %0,%2@l(%1)|addi %0,%1,%2@l}")
11610 12149
11611 ;; A function pointer under AIX is a pointer to a data area whose first word 12150 ;; A function pointer under AIX is a pointer to a data area whose first word
11612 ;; contains the actual address of the function, whose second word contains a 12151 ;; contains the actual address of the function, whose second word contains a
11613 ;; pointer to its TOC, and whose third word contains a value to place in the 12152 ;; pointer to its TOC, and whose third word contains a value to place in the
11614 ;; static chain register (r11). Note that if we load the static chain, our 12153 ;; static chain register (r11). Note that if we load the static chain, our
12585 (unspec [(const_int 0)] UNSPEC_PROBE_STACK))] 13124 (unspec [(const_int 0)] UNSPEC_PROBE_STACK))]
12586 "" 13125 ""
12587 "{st%U0%X0|stw%U0%X0} 0,%0" 13126 "{st%U0%X0|stw%U0%X0} 0,%0"
12588 [(set_attr "type" "store") 13127 [(set_attr "type" "store")
12589 (set_attr "length" "4")]) 13128 (set_attr "length" "4")])
13129
13130 (define_insn "probe_stack_range<P:mode>"
13131 [(set (match_operand:P 0 "register_operand" "=r")
13132 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
13133 (match_operand:P 2 "register_operand" "r")]
13134 UNSPECV_PROBE_STACK_RANGE))]
13135 ""
13136 "* return output_probe_stack_range (operands[0], operands[2]);"
13137 [(set_attr "type" "three")])
12590 13138
12591 ;; Compare insns are next. Note that the RS/6000 has two types of compares, 13139 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
12592 ;; signed & unsigned, and one type of branch. 13140 ;; signed & unsigned, and one type of branch.
12593 ;; 13141 ;;
12594 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc 13142 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
12908 (clobber (match_scratch:DF 5 "=d")) 13456 (clobber (match_scratch:DF 5 "=d"))
12909 (clobber (match_scratch:DF 6 "=d")) 13457 (clobber (match_scratch:DF 6 "=d"))
12910 (clobber (match_scratch:DF 7 "=d")) 13458 (clobber (match_scratch:DF 7 "=d"))
12911 (clobber (match_scratch:DF 8 "=d")) 13459 (clobber (match_scratch:DF 8 "=d"))
12912 (clobber (match_scratch:DF 9 "=d")) 13460 (clobber (match_scratch:DF 9 "=d"))
12913 (clobber (match_scratch:DF 10 "=d"))] 13461 (clobber (match_scratch:DF 10 "=d"))
13462 (clobber (match_scratch:GPR 11 "=b"))]
12914 "!TARGET_IEEEQUAD && TARGET_XL_COMPAT 13463 "!TARGET_IEEEQUAD && TARGET_XL_COMPAT
12915 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" 13464 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
12916 "#" 13465 "#"
12917 "&& reload_completed" 13466 "&& reload_completed"
12918 [(set (match_dup 3) (match_dup 13)) 13467 [(set (match_dup 3) (match_dup 14))
12919 (set (match_dup 4) (match_dup 14)) 13468 (set (match_dup 4) (match_dup 15))
12920 (set (match_dup 9) (abs:DF (match_dup 5))) 13469 (set (match_dup 9) (abs:DF (match_dup 5)))
12921 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3))) 13470 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
12922 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0)) 13471 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
12923 (label_ref (match_dup 11)) 13472 (label_ref (match_dup 12))
12924 (pc))) 13473 (pc)))
12925 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7))) 13474 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
12926 (set (pc) (label_ref (match_dup 12))) 13475 (set (pc) (label_ref (match_dup 13)))
12927 (match_dup 11) 13476 (match_dup 12)
12928 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7))) 13477 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
12929 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8))) 13478 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
12930 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9))) 13479 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
12931 (set (match_dup 0) (compare:CCFP (match_dup 7) (match_dup 4))) 13480 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
12932 (match_dup 12)] 13481 (match_dup 13)]
12933 { 13482 {
12934 REAL_VALUE_TYPE rv; 13483 REAL_VALUE_TYPE rv;
12935 const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0; 13484 const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0;
12936 const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode); 13485 const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
12937 13486
12938 operands[5] = simplify_gen_subreg (DFmode, operands[1], TFmode, hi_word); 13487 operands[5] = simplify_gen_subreg (DFmode, operands[1], TFmode, hi_word);
12939 operands[6] = simplify_gen_subreg (DFmode, operands[1], TFmode, lo_word); 13488 operands[6] = simplify_gen_subreg (DFmode, operands[1], TFmode, lo_word);
12940 operands[7] = simplify_gen_subreg (DFmode, operands[2], TFmode, hi_word); 13489 operands[7] = simplify_gen_subreg (DFmode, operands[2], TFmode, hi_word);
12941 operands[8] = simplify_gen_subreg (DFmode, operands[2], TFmode, lo_word); 13490 operands[8] = simplify_gen_subreg (DFmode, operands[2], TFmode, lo_word);
12942 operands[11] = gen_label_rtx ();
12943 operands[12] = gen_label_rtx (); 13491 operands[12] = gen_label_rtx ();
13492 operands[13] = gen_label_rtx ();
12944 real_inf (&rv); 13493 real_inf (&rv);
12945 operands[13] = force_const_mem (DFmode, 13494 operands[14] = force_const_mem (DFmode,
12946 CONST_DOUBLE_FROM_REAL_VALUE (rv, DFmode)); 13495 CONST_DOUBLE_FROM_REAL_VALUE (rv, DFmode));
12947 operands[14] = force_const_mem (DFmode, 13496 operands[15] = force_const_mem (DFmode,
12948 CONST_DOUBLE_FROM_REAL_VALUE (dconst0, 13497 CONST_DOUBLE_FROM_REAL_VALUE (dconst0,
12949 DFmode)); 13498 DFmode));
12950 if (TARGET_TOC) 13499 if (TARGET_TOC)
12951 { 13500 {
12952 operands[13] = gen_const_mem (DFmode, 13501 rtx tocref;
12953 create_TOC_reference (XEXP (operands[13], 0))); 13502 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
12954 operands[14] = gen_const_mem (DFmode, 13503 operands[14] = gen_const_mem (DFmode, tocref);
12955 create_TOC_reference (XEXP (operands[14], 0))); 13504 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
12956 set_mem_alias_set (operands[13], get_TOC_alias_set ()); 13505 operands[15] = gen_const_mem (DFmode, tocref);
12957 set_mem_alias_set (operands[14], get_TOC_alias_set ()); 13506 set_mem_alias_set (operands[14], get_TOC_alias_set ());
13507 set_mem_alias_set (operands[15], get_TOC_alias_set ());
12958 } 13508 }
12959 }) 13509 })
12960 13510
12961 ;; Now we have the scc insns. We can do some combinations because of the 13511 ;; Now we have the scc insns. We can do some combinations because of the
12962 ;; way the machine works. 13512 ;; way the machine works.
15398 (unspec:BLK [(match_dup 0)] UNSPEC_TIE))] 15948 (unspec:BLK [(match_dup 0)] UNSPEC_TIE))]
15399 "" 15949 ""
15400 "" 15950 ""
15401 [(set_attr "length" "0")]) 15951 [(set_attr "length" "0")])
15402 15952
15953 ; Like stack_tie, but depend on both fp and sp based memory.
15954 (define_insn "frame_tie"
15955 [(set (match_operand:BLK 0 "memory_operand" "+m")
15956 (unspec:BLK [(match_dup 0)
15957 (match_operand:BLK 1 "memory_operand" "m")] UNSPEC_TIE))]
15958 ""
15959 ""
15960 [(set_attr "length" "0")])
15961
15403 15962
15404 (define_expand "epilogue" 15963 (define_expand "epilogue"
15405 [(use (const_int 0))] 15964 [(use (const_int 0))]
15406 "TARGET_SCHED_PROLOG" 15965 "TARGET_SCHED_PROLOG"
15407 " 15966 "
15577 "TARGET_POPCNTD" 16136 "TARGET_POPCNTD"
15578 "bpermd %0,%1,%2" 16137 "bpermd %0,%1,%2"
15579 [(set_attr "type" "integer")]) 16138 [(set_attr "type" "integer")])
15580 16139
15581 16140
16141 ;; Builtin fma support. Handle
16142 ;; Note that the conditions for expansion are in the FMA_F iterator.
16143
16144 (define_expand "fma<mode>4"
16145 [(set (match_operand:FMA_F 0 "register_operand" "")
16146 (fma:FMA_F
16147 (match_operand:FMA_F 1 "register_operand" "")
16148 (match_operand:FMA_F 2 "register_operand" "")
16149 (match_operand:FMA_F 3 "register_operand" "")))]
16150 ""
16151 "")
16152
16153 ; Altivec only has fma and nfms.
16154 (define_expand "fms<mode>4"
16155 [(set (match_operand:FMA_F 0 "register_operand" "")
16156 (fma:FMA_F
16157 (match_operand:FMA_F 1 "register_operand" "")
16158 (match_operand:FMA_F 2 "register_operand" "")
16159 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" ""))))]
16160 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
16161 "")
16162
16163 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
16164 (define_expand "fnma<mode>4"
16165 [(set (match_operand:FMA_F 0 "register_operand" "")
16166 (neg:FMA_F
16167 (fma:FMA_F
16168 (match_operand:FMA_F 1 "register_operand" "")
16169 (match_operand:FMA_F 2 "register_operand" "")
16170 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
16171 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
16172 "")
16173
16174 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
16175 (define_expand "fnms<mode>4"
16176 [(set (match_operand:FMA_F 0 "register_operand" "")
16177 (neg:FMA_F
16178 (fma:FMA_F
16179 (match_operand:FMA_F 1 "register_operand" "")
16180 (match_operand:FMA_F 2 "register_operand" "")
16181 (match_operand:FMA_F 3 "register_operand" ""))))]
16182 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
16183 "")
16184
16185 ; Not an official optab name, but used from builtins.
16186 (define_expand "nfma<mode>4"
16187 [(set (match_operand:FMA_F 0 "register_operand" "")
16188 (neg:FMA_F
16189 (fma:FMA_F
16190 (match_operand:FMA_F 1 "register_operand" "")
16191 (match_operand:FMA_F 2 "register_operand" "")
16192 (match_operand:FMA_F 3 "register_operand" ""))))]
16193 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
16194 "")
16195
16196 ; Not an official optab name, but used from builtins.
16197 (define_expand "nfms<mode>4"
16198 [(set (match_operand:FMA_F 0 "register_operand" "")
16199 (neg:FMA_F
16200 (fma:FMA_F
16201 (match_operand:FMA_F 1 "register_operand" "")
16202 (match_operand:FMA_F 2 "register_operand" "")
16203 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))]
16204 ""
16205 "")
16206
16207
15582 16208
15583 (include "sync.md") 16209 (include "sync.md")
15584 (include "vector.md") 16210 (include "vector.md")
15585 (include "vsx.md") 16211 (include "vsx.md")
15586 (include "altivec.md") 16212 (include "altivec.md")