Mercurial > hg > CbC > CbC_gcc
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") |