Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/rs6000/rs6000.md @ 132:d34655255c78
update gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 10:21:07 +0900 |
parents | ab0bcb71f44d 84e7813d76e9 |
children | 351920fa3827 |
comparison
equal
deleted
inserted
replaced
130:e108057fa461 | 132:d34655255c78 |
---|---|
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-2017 Free Software Foundation, Inc. | 2 ;; Copyright (C) 1990-2018 Free Software Foundation, Inc. |
3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) | 3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) |
4 | 4 |
5 ;; This file is part of GCC. | 5 ;; This file is part of GCC. |
6 | 6 |
7 ;; GCC is free software; you can redistribute it and/or modify it | 7 ;; GCC is free software; you can redistribute it and/or modify it |
128 UNSPEC_P8V_RELOAD_FROM_VSX | 128 UNSPEC_P8V_RELOAD_FROM_VSX |
129 UNSPEC_ADDG6S | 129 UNSPEC_ADDG6S |
130 UNSPEC_CDTBCD | 130 UNSPEC_CDTBCD |
131 UNSPEC_CBCDTD | 131 UNSPEC_CBCDTD |
132 UNSPEC_DIVE | 132 UNSPEC_DIVE |
133 UNSPEC_DIVEO | |
134 UNSPEC_DIVEU | 133 UNSPEC_DIVEU |
135 UNSPEC_DIVEUO | |
136 UNSPEC_UNPACK_128BIT | 134 UNSPEC_UNPACK_128BIT |
137 UNSPEC_PACK_128BIT | 135 UNSPEC_PACK_128BIT |
138 UNSPEC_LSQ | 136 UNSPEC_LSQ |
139 UNSPEC_FUSION_GPR | 137 UNSPEC_FUSION_GPR |
140 UNSPEC_STACK_CHECK | 138 UNSPEC_STACK_CHECK |
141 UNSPEC_FUSION_P9 | 139 UNSPEC_FUSION_P9 |
142 UNSPEC_FUSION_ADDIS | |
143 UNSPEC_ADD_ROUND_TO_ODD | 140 UNSPEC_ADD_ROUND_TO_ODD |
144 UNSPEC_SUB_ROUND_TO_ODD | 141 UNSPEC_SUB_ROUND_TO_ODD |
145 UNSPEC_MUL_ROUND_TO_ODD | 142 UNSPEC_MUL_ROUND_TO_ODD |
146 UNSPEC_DIV_ROUND_TO_ODD | 143 UNSPEC_DIV_ROUND_TO_ODD |
147 UNSPEC_FMA_ROUND_TO_ODD | 144 UNSPEC_FMA_ROUND_TO_ODD |
164 UNSPECV_EH_RR ; eh_reg_restore | 161 UNSPECV_EH_RR ; eh_reg_restore |
165 UNSPECV_ISYNC ; isync instruction | 162 UNSPECV_ISYNC ; isync instruction |
166 UNSPECV_MFTB ; move from time base | 163 UNSPECV_MFTB ; move from time base |
167 UNSPECV_NLGR ; non-local goto receiver | 164 UNSPECV_NLGR ; non-local goto receiver |
168 UNSPECV_MFFS ; Move from FPSCR | 165 UNSPECV_MFFS ; Move from FPSCR |
169 UNSPECV_MTFSF ; Move to FPSCR Fields | 166 UNSPECV_MFFSL ; Move from FPSCR light instruction version |
167 UNSPECV_MFFSCRN ; Move from FPSCR float rounding mode | |
168 UNSPECV_MFFSCDRN ; Move from FPSCR decimal float rounding mode | |
169 UNSPECV_MTFSF ; Move to FPSCR Fields 8 to 15 | |
170 UNSPECV_MTFSF_HI ; Move to FPSCR Fields 0 to 7 | |
171 UNSPECV_MTFSB0 ; Set FPSCR Field bit to 0 | |
172 UNSPECV_MTFSB1 ; Set FPSCR Field bit to 1 | |
170 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return | 173 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return |
174 UNSPECV_SPEC_BARRIER ; Speculation barrier | |
171 ]) | 175 ]) |
172 | 176 |
173 | 177 |
174 ;; Define an insn type attribute. This is used in function unit delay | 178 ;; Define an insn type attribute. This is used in function unit delay |
175 ;; computations. | 179 ;; computations. |
179 mul,halfmul,div, | 183 mul,halfmul,div, |
180 exts,cntlz,popcnt,isel, | 184 exts,cntlz,popcnt,isel, |
181 load,store,fpload,fpstore,vecload,vecstore, | 185 load,store,fpload,fpstore,vecload,vecstore, |
182 cmp, | 186 cmp, |
183 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c, | 187 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c, |
184 cr_logical,delayed_cr,mfcr,mfcrf,mtcr, | 188 cr_logical,mfcr,mfcrf,mtcr, |
185 fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt, | 189 fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt, |
186 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm, | 190 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm, |
187 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto, | 191 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto, |
188 veclogical,veccmpfx,vecexts,vecmove, | 192 veclogical,veccmpfx,vecexts,vecmove, |
189 htm,htmsimple,dfp" | 193 htm,htmsimple,dfp" |
190 (const_string "integer")) | 194 (const_string "integer")) |
202 (define_attr "dot" "no,yes" (const_string "no")) | 206 (define_attr "dot" "no,yes" (const_string "no")) |
203 | 207 |
204 ;; Does this instruction sign-extend its result? | 208 ;; Does this instruction sign-extend its result? |
205 ;; This is used for load insns. | 209 ;; This is used for load insns. |
206 (define_attr "sign_extend" "no,yes" (const_string "no")) | 210 (define_attr "sign_extend" "no,yes" (const_string "no")) |
211 | |
212 ;; Does this cr_logical instruction have three operands? That is, BT != BB. | |
213 (define_attr "cr_logical_3op" "no,yes" (const_string "no")) | |
207 | 214 |
208 ;; Does this instruction use indexed (that is, reg+reg) addressing? | 215 ;; Does this instruction use indexed (that is, reg+reg) addressing? |
209 ;; This is used for load and store insns. If operand 0 or 1 is a MEM | 216 ;; This is used for load and store insns. If operand 0 or 1 is a MEM |
210 ;; it is automatically set based on that. If a load or store instruction | 217 ;; it is automatically set based on that. If a load or store instruction |
211 ;; has fewer than two operands it needs to set this attribute manually | 218 ;; has fewer than two operands it needs to set this attribute manually |
240 (const_string "no"))) | 247 (const_string "no"))) |
241 | 248 |
242 ;; Is copying of this instruction disallowed? | 249 ;; Is copying of this instruction disallowed? |
243 (define_attr "cannot_copy" "no,yes" (const_string "no")) | 250 (define_attr "cannot_copy" "no,yes" (const_string "no")) |
244 | 251 |
245 ;; Define floating point instruction sub-types for use with Xfpu.md | 252 ;; Length of the instruction (in bytes). |
246 (define_attr "fp_type" "fp_default,fp_addsub_s,fp_addsub_d,fp_mul_s,fp_mul_d,fp_div_s,fp_div_d,fp_maddsub_s,fp_maddsub_d,fp_sqrt_s,fp_sqrt_d" (const_string "fp_default")) | 253 (define_attr "length" "" (const_int 4)) |
247 | |
248 ;; Length (in bytes). | |
249 ; '(pc)' in the following doesn't include the instruction itself; it is | |
250 ; calculated as if the instruction had zero size. | |
251 (define_attr "length" "" | |
252 (if_then_else (eq_attr "type" "branch") | |
253 (if_then_else (and (ge (minus (match_dup 0) (pc)) | |
254 (const_int -32768)) | |
255 (lt (minus (match_dup 0) (pc)) | |
256 (const_int 32764))) | |
257 (const_int 4) | |
258 (const_int 8)) | |
259 (const_int 4))) | |
260 | 254 |
261 ;; Processor type -- this attribute must exactly match the processor_type | 255 ;; Processor type -- this attribute must exactly match the processor_type |
262 ;; enumeration in rs6000-opts.h. | 256 ;; enumeration in rs6000-opts.h. |
263 (define_attr "cpu" | 257 (define_attr "cpu" |
264 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630, | 258 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630, |
265 ppc750,ppc7400,ppc7450, | 259 ppc750,ppc7400,ppc7450, |
266 ppc403,ppc405,ppc440,ppc476, | 260 ppc403,ppc405,ppc440,ppc476, |
267 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500, | 261 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500, |
268 power4,power5,power6,power7,power8,power9, | 262 power4,power5,power6,power7,power8,power9, |
269 rs64a,mpccore,cell,ppca2,titan" | 263 rs64a,mpccore,cell,ppca2,titan" |
270 (const (symbol_ref "rs6000_cpu_attr"))) | 264 (const (symbol_ref "(enum attr_cpu) rs6000_tune"))) |
271 | 265 |
272 | 266 |
273 ;; If this instruction is microcoded on the CELL processor | 267 ;; If this instruction is microcoded on the CELL processor |
274 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded | 268 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded |
275 (define_attr "cell_micro" "not,conditional,always" | 269 (define_attr "cell_micro" "not,conditional,always" |
305 (include "power6.md") | 299 (include "power6.md") |
306 (include "power7.md") | 300 (include "power7.md") |
307 (include "power8.md") | 301 (include "power8.md") |
308 (include "power9.md") | 302 (include "power9.md") |
309 (include "cell.md") | 303 (include "cell.md") |
310 (include "xfpu.md") | |
311 (include "a2.md") | 304 (include "a2.md") |
312 (include "titan.md") | 305 (include "titan.md") |
313 | 306 |
314 (include "predicates.md") | 307 (include "predicates.md") |
315 (include "constraints.md") | 308 (include "constraints.md") |
320 ;; Mode iterators | 313 ;; Mode iterators |
321 | 314 |
322 ; This mode iterator allows :GPR to be used to indicate the allowable size | 315 ; This mode iterator allows :GPR to be used to indicate the allowable size |
323 ; of whole values in GPRs. | 316 ; of whole values in GPRs. |
324 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")]) | 317 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")]) |
318 | |
319 ; And again, for patterns that need two (potentially) different integer modes. | |
320 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")]) | |
325 | 321 |
326 ; Any supported integer mode. | 322 ; Any supported integer mode. |
327 (define_mode_iterator INT [QI HI SI DI TI PTI]) | 323 (define_mode_iterator INT [QI HI SI DI TI PTI]) |
328 | 324 |
329 ; Any supported integer mode that fits in one register. | 325 ; Any supported integer mode that fits in one register. |
374 ; PTImode is GPR only) | 370 ; PTImode is GPR only) |
375 (define_mode_iterator TI2 [TI PTI]) | 371 (define_mode_iterator TI2 [TI PTI]) |
376 | 372 |
377 ; Any hardware-supported floating-point mode | 373 ; Any hardware-supported floating-point mode |
378 (define_mode_iterator FP [ | 374 (define_mode_iterator FP [ |
379 (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT") | 375 (SF "TARGET_HARD_FLOAT") |
380 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT") | 376 (DF "TARGET_HARD_FLOAT") |
381 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128") | 377 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128") |
382 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128") | 378 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128") |
383 (KF "TARGET_FLOAT128_TYPE") | 379 (KF "TARGET_FLOAT128_TYPE") |
384 (DD "TARGET_DFP") | 380 (DD "TARGET_DFP") |
385 (TD "TARGET_DFP")]) | 381 (TD "TARGET_DFP")]) |
386 | 382 |
387 ; Any fma capable floating-point mode. | 383 ; Any fma capable floating-point mode. |
388 (define_mode_iterator FMA_F [ | 384 (define_mode_iterator FMA_F [ |
389 (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT") | 385 (SF "TARGET_HARD_FLOAT") |
390 (DF "(TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) | 386 (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)") |
391 || VECTOR_UNIT_VSX_P (DFmode)") | |
392 (V2SF "TARGET_PAIRED_FLOAT") | |
393 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)") | 387 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)") |
394 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)") | 388 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)") |
395 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)") | 389 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)") |
396 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)") | 390 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)") |
397 ]) | 391 ]) |
421 (TF "FLOAT128_VECTOR_P (TFmode)")]) | 415 (TF "FLOAT128_VECTOR_P (TFmode)")]) |
422 | 416 |
423 ; Iterator for 128-bit VSX types for pack/unpack | 417 ; Iterator for 128-bit VSX types for pack/unpack |
424 (define_mode_iterator FMOVE128_VSX [V1TI KF]) | 418 (define_mode_iterator FMOVE128_VSX [V1TI KF]) |
425 | 419 |
420 ; Iterators for converting to/from TFmode | |
421 (define_mode_iterator IFKF [IF KF]) | |
422 | |
423 ; Constraints for moving IF/KFmode. | |
424 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")]) | |
425 | |
426 ; Whether a floating point move is ok, don't allow SD without hardware FP | 426 ; Whether a floating point move is ok, don't allow SD without hardware FP |
427 (define_mode_attr fmove_ok [(SF "") | 427 (define_mode_attr fmove_ok [(SF "") |
428 (DF "") | 428 (DF "") |
429 (SD "TARGET_HARD_FLOAT") | 429 (SD "TARGET_HARD_FLOAT") |
430 (DD "")]) | 430 (DD "")]) |
511 (define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")]) | 511 (define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")]) |
512 | 512 |
513 ; SF/DF constraint for arithmetic on altivec registers | 513 ; SF/DF constraint for arithmetic on altivec registers |
514 (define_mode_attr Fa [(SF "wu") (DF "wv")]) | 514 (define_mode_attr Fa [(SF "wu") (DF "wv")]) |
515 | 515 |
516 ; s/d suffix for things like fp_addsub_s/fp_addsub_d | 516 ; s/d suffix for things like sdiv/ddiv |
517 (define_mode_attr Fs [(SF "s") (DF "d")]) | 517 (define_mode_attr Fs [(SF "s") (DF "d")]) |
518 | 518 |
519 ; FRE/FRES support | 519 ; FRE/FRES support |
520 (define_mode_attr Ffre [(SF "fres") (DF "fre")]) | 520 (define_mode_attr Ffre [(SF "fres") (DF "fre")]) |
521 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")]) | 521 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")]) |
541 (unsigned_fix "u")]) | 541 (unsigned_fix "u")]) |
542 | 542 |
543 (define_code_attr su [(sign_extend "s") | 543 (define_code_attr su [(sign_extend "s") |
544 (zero_extend "u") | 544 (zero_extend "u") |
545 (fix "s") | 545 (fix "s") |
546 (unsigned_fix "s") | 546 (unsigned_fix "u") |
547 (float "s") | 547 (float "s") |
548 (unsigned_float "u")]) | 548 (unsigned_float "u")]) |
549 | 549 |
550 (define_code_attr az [(sign_extend "a") | 550 (define_code_attr az [(sign_extend "a") |
551 (zero_extend "z") | 551 (zero_extend "z") |
612 (DF "d")]) | 612 (DF "d")]) |
613 | 613 |
614 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS") | 614 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS") |
615 (DF "TARGET_FCFID")]) | 615 (DF "TARGET_FCFID")]) |
616 | 616 |
617 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT") | |
618 (DF "TARGET_DOUBLE_FLOAT")]) | |
619 | |
620 ;; Mode iterator for logical operations on 128-bit types | 617 ;; Mode iterator for logical operations on 128-bit types |
621 (define_mode_iterator BOOL_128 [TI | 618 (define_mode_iterator BOOL_128 [TI |
622 PTI | 619 PTI |
623 (V16QI "TARGET_ALTIVEC") | 620 (V16QI "TARGET_ALTIVEC") |
624 (V8HI "TARGET_ALTIVEC") | 621 (V8HI "TARGET_ALTIVEC") |
995 (define_insn "extendsi<mode>2" | 992 (define_insn "extendsi<mode>2" |
996 [(set (match_operand:EXTSI 0 "gpc_reg_operand" | 993 [(set (match_operand:EXTSI 0 "gpc_reg_operand" |
997 "=r, r, wl, wu, wj, wK, wH, wr") | 994 "=r, r, wl, wu, wj, wK, wH, wr") |
998 | 995 |
999 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" | 996 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" |
1000 "Y, r, Z, Z, r, wK, wH, ?wIwH")))] | 997 "YZ, r, Z, Z, r, wK, wH, ?wIwH")))] |
1001 "" | 998 "" |
1002 "@ | 999 "@ |
1003 lwa%U1%X1 %0,%1 | 1000 lwa%U1%X1 %0,%1 |
1004 extsw %0,%1 | 1001 extsw %0,%1 |
1005 lfiwax %0,%y1 | 1002 lfiwax %0,%y1 |
1035 int dest_regno = REGNO (dest); | 1032 int dest_regno = REGNO (dest); |
1036 int src_regno = REGNO (src); | 1033 int src_regno = REGNO (src); |
1037 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno); | 1034 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno); |
1038 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno); | 1035 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno); |
1039 | 1036 |
1040 if (VECTOR_ELT_ORDER_BIG) | 1037 if (BYTES_BIG_ENDIAN) |
1041 { | 1038 { |
1042 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si)); | 1039 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si)); |
1043 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx)); | 1040 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx)); |
1044 } | 1041 } |
1045 else | 1042 else |
1567 UNSPEC_DLMZB))] | 1564 UNSPEC_DLMZB))] |
1568 "TARGET_DLMZB" | 1565 "TARGET_DLMZB" |
1569 "dlmzb. %0,%1,%2") | 1566 "dlmzb. %0,%1,%2") |
1570 | 1567 |
1571 (define_expand "strlensi" | 1568 (define_expand "strlensi" |
1572 [(set (match_operand:SI 0 "gpc_reg_operand" "") | 1569 [(set (match_operand:SI 0 "gpc_reg_operand") |
1573 (unspec:SI [(match_operand:BLK 1 "general_operand" "") | 1570 (unspec:SI [(match_operand:BLK 1 "general_operand") |
1574 (match_operand:QI 2 "const_int_operand" "") | 1571 (match_operand:QI 2 "const_int_operand") |
1575 (match_operand 3 "const_int_operand" "")] | 1572 (match_operand 3 "const_int_operand")] |
1576 UNSPEC_DLMZB_STRLEN)) | 1573 UNSPEC_DLMZB_STRLEN)) |
1577 (clobber (match_scratch:CC 4 "=x"))] | 1574 (clobber (match_scratch:CC 4))] |
1578 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size" | 1575 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size" |
1579 { | 1576 { |
1580 rtx result = operands[0]; | 1577 rtx result = operands[0]; |
1581 rtx src = operands[1]; | 1578 rtx src = operands[1]; |
1582 rtx search_char = operands[2]; | 1579 rtx search_char = operands[2]; |
1621 }) | 1618 }) |
1622 | 1619 |
1623 ;; Fixed-point arithmetic insns. | 1620 ;; Fixed-point arithmetic insns. |
1624 | 1621 |
1625 (define_expand "add<mode>3" | 1622 (define_expand "add<mode>3" |
1626 [(set (match_operand:SDI 0 "gpc_reg_operand" "") | 1623 [(set (match_operand:SDI 0 "gpc_reg_operand") |
1627 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "") | 1624 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand") |
1628 (match_operand:SDI 2 "reg_or_add_cint_operand" "")))] | 1625 (match_operand:SDI 2 "reg_or_add_cint_operand")))] |
1629 "" | 1626 "" |
1630 { | 1627 { |
1631 if (<MODE>mode == DImode && !TARGET_POWERPC64) | 1628 if (<MODE>mode == DImode && !TARGET_POWERPC64) |
1632 { | 1629 { |
1633 rtx lo0 = gen_lowpart (SImode, operands[0]); | 1630 rtx lo0 = gen_lowpart (SImode, operands[0]); |
1796 ;; Split an add that we can't do in one insn into two insns, each of which | 1793 ;; Split an add that we can't do in one insn into two insns, each of which |
1797 ;; does one 16-bit part. This is used by combine. Note that the low-order | 1794 ;; does one 16-bit part. This is used by combine. Note that the low-order |
1798 ;; add should be last in case the result gets used in an address. | 1795 ;; add should be last in case the result gets used in an address. |
1799 | 1796 |
1800 (define_split | 1797 (define_split |
1801 [(set (match_operand:GPR 0 "gpc_reg_operand" "") | 1798 [(set (match_operand:GPR 0 "gpc_reg_operand") |
1802 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "") | 1799 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand") |
1803 (match_operand:GPR 2 "non_add_cint_operand" "")))] | 1800 (match_operand:GPR 2 "non_add_cint_operand")))] |
1804 "" | 1801 "" |
1805 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3))) | 1802 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3))) |
1806 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))] | 1803 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))] |
1807 { | 1804 { |
1808 HOST_WIDE_INT val = INTVAL (operands[2]); | 1805 HOST_WIDE_INT val = INTVAL (operands[2]); |
1910 (clobber (reg:GPR CA_REGNO))] | 1907 (clobber (reg:GPR CA_REGNO))] |
1911 "" | 1908 "" |
1912 "adde %0,%1,%2" | 1909 "adde %0,%1,%2" |
1913 [(set_attr "type" "add")]) | 1910 [(set_attr "type" "add")]) |
1914 | 1911 |
1912 (define_insn "*add<mode>3_carry_in_internal2" | |
1913 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") | |
1914 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") | |
1915 (reg:GPR CA_REGNO)) | |
1916 (match_operand:GPR 2 "gpc_reg_operand" "r"))) | |
1917 (clobber (reg:GPR CA_REGNO))] | |
1918 "" | |
1919 "adde %0,%1,%2" | |
1920 [(set_attr "type" "add")]) | |
1921 | |
1915 (define_insn "add<mode>3_carry_in_0" | 1922 (define_insn "add<mode>3_carry_in_0" |
1916 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") | 1923 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") |
1917 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") | 1924 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") |
1918 (reg:GPR CA_REGNO))) | 1925 (reg:GPR CA_REGNO))) |
1919 (clobber (reg:GPR CA_REGNO))] | 1926 (clobber (reg:GPR CA_REGNO))] |
1931 "addme %0,%1" | 1938 "addme %0,%1" |
1932 [(set_attr "type" "add")]) | 1939 [(set_attr "type" "add")]) |
1933 | 1940 |
1934 | 1941 |
1935 (define_expand "one_cmpl<mode>2" | 1942 (define_expand "one_cmpl<mode>2" |
1936 [(set (match_operand:SDI 0 "gpc_reg_operand" "") | 1943 [(set (match_operand:SDI 0 "gpc_reg_operand") |
1937 (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))] | 1944 (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))] |
1938 "" | 1945 "" |
1939 { | 1946 { |
1940 if (<MODE>mode == DImode && !TARGET_POWERPC64) | 1947 if (<MODE>mode == DImode && !TARGET_POWERPC64) |
1941 { | 1948 { |
1942 rs6000_split_logical (operands, NOT, false, false, false); | 1949 rs6000_split_logical (operands, NOT, false, false, false); |
1991 (set_attr "dot" "yes") | 1998 (set_attr "dot" "yes") |
1992 (set_attr "length" "4,8")]) | 1999 (set_attr "length" "4,8")]) |
1993 | 2000 |
1994 | 2001 |
1995 (define_expand "sub<mode>3" | 2002 (define_expand "sub<mode>3" |
1996 [(set (match_operand:SDI 0 "gpc_reg_operand" "") | 2003 [(set (match_operand:SDI 0 "gpc_reg_operand") |
1997 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "") | 2004 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand") |
1998 (match_operand:SDI 2 "gpc_reg_operand" "")))] | 2005 (match_operand:SDI 2 "gpc_reg_operand")))] |
1999 "" | 2006 "" |
2000 { | 2007 { |
2001 if (<MODE>mode == DImode && !TARGET_POWERPC64) | 2008 if (<MODE>mode == DImode && !TARGET_POWERPC64) |
2002 { | 2009 { |
2003 rtx lo0 = gen_lowpart (SImode, operands[0]); | 2010 rtx lo0 = gen_lowpart (SImode, operands[0]); |
2319 DONE; | 2326 DONE; |
2320 }) | 2327 }) |
2321 | 2328 |
2322 | 2329 |
2323 (define_expand "popcount<mode>2" | 2330 (define_expand "popcount<mode>2" |
2324 [(set (match_operand:GPR 0 "gpc_reg_operand" "") | 2331 [(set (match_operand:GPR 0 "gpc_reg_operand") |
2325 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))] | 2332 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))] |
2326 "TARGET_POPCNTB || TARGET_POPCNTD" | 2333 "TARGET_POPCNTB || TARGET_POPCNTD" |
2327 { | 2334 { |
2328 rs6000_emit_popcount (operands[0], operands[1]); | 2335 rs6000_emit_popcount (operands[0], operands[1]); |
2329 DONE; | 2336 DONE; |
2330 }) | 2337 }) |
2344 "popcnt<wd> %0,%1" | 2351 "popcnt<wd> %0,%1" |
2345 [(set_attr "type" "popcnt")]) | 2352 [(set_attr "type" "popcnt")]) |
2346 | 2353 |
2347 | 2354 |
2348 (define_expand "parity<mode>2" | 2355 (define_expand "parity<mode>2" |
2349 [(set (match_operand:GPR 0 "gpc_reg_operand" "") | 2356 [(set (match_operand:GPR 0 "gpc_reg_operand") |
2350 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))] | 2357 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))] |
2351 "TARGET_POPCNTB" | 2358 "TARGET_POPCNTB" |
2352 { | 2359 { |
2353 rs6000_emit_parity (operands[0], operands[1]); | 2360 rs6000_emit_parity (operands[0], operands[1]); |
2354 DONE; | 2361 DONE; |
2355 }) | 2362 }) |
2375 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") | 2382 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") |
2376 (zero_extend:DI | 2383 (zero_extend:DI |
2377 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))] | 2384 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))] |
2378 "TARGET_POWERPC64" | 2385 "TARGET_POWERPC64" |
2379 "l<wd>brx %0,%y1" | 2386 "l<wd>brx %0,%y1" |
2380 [(set_attr "length" "4") | 2387 [(set_attr "type" "load")]) |
2381 (set_attr "type" "load")]) | |
2382 | 2388 |
2383 (define_insn "*bswaphi2_extendsi" | 2389 (define_insn "*bswaphi2_extendsi" |
2384 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") | 2390 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") |
2385 (zero_extend:SI | 2391 (zero_extend:SI |
2386 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))] | 2392 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))] |
2387 "" | 2393 "" |
2388 "lhbrx %0,%y1" | 2394 "lhbrx %0,%y1" |
2389 [(set_attr "length" "4") | 2395 [(set_attr "type" "load")]) |
2390 (set_attr "type" "load")]) | |
2391 | 2396 |
2392 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents | 2397 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents |
2393 ;; the register allocator from converting a gpr<-gpr swap into a store and then | 2398 ;; the register allocator from converting a gpr<-gpr swap into a store and then |
2394 ;; load with byte swap, which can be slower than doing it in the registers. It | 2399 ;; load with byte swap, which can be slower than doing it in the registers. It |
2395 ;; also prevents certain failures with the RELOAD register allocator. | 2400 ;; also prevents certain failures with the RELOAD register allocator. |
2427 "" | 2432 "" |
2428 "st<wd>brx %1,%y0" | 2433 "st<wd>brx %1,%y0" |
2429 [(set_attr "type" "store")]) | 2434 [(set_attr "type" "store")]) |
2430 | 2435 |
2431 (define_insn_and_split "bswaphi2_reg" | 2436 (define_insn_and_split "bswaphi2_reg" |
2432 [(set (match_operand:HI 0 "gpc_reg_operand" "=&r") | 2437 [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wo") |
2433 (bswap:HI | 2438 (bswap:HI |
2434 (match_operand:HI 1 "gpc_reg_operand" "r"))) | 2439 (match_operand:HI 1 "gpc_reg_operand" "r,wo"))) |
2435 (clobber (match_scratch:SI 2 "=&r"))] | 2440 (clobber (match_scratch:SI 2 "=&r,X"))] |
2436 "" | 2441 "" |
2437 "#" | 2442 "@ |
2438 "reload_completed" | 2443 # |
2444 xxbrh %x0,%x1" | |
2445 "reload_completed && int_reg_operand (operands[0], HImode)" | |
2439 [(set (match_dup 3) | 2446 [(set (match_dup 3) |
2440 (and:SI (lshiftrt:SI (match_dup 4) | 2447 (and:SI (lshiftrt:SI (match_dup 4) |
2441 (const_int 8)) | 2448 (const_int 8)) |
2442 (const_int 255))) | 2449 (const_int 255))) |
2443 (set (match_dup 2) | 2450 (set (match_dup 2) |
2449 (match_dup 2)))] | 2456 (match_dup 2)))] |
2450 { | 2457 { |
2451 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0); | 2458 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0); |
2452 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0); | 2459 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0); |
2453 } | 2460 } |
2454 [(set_attr "length" "12") | 2461 [(set_attr "length" "12,4") |
2455 (set_attr "type" "*")]) | 2462 (set_attr "type" "*,vecperm")]) |
2456 | 2463 |
2457 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in | 2464 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in |
2458 ;; zero_extract insns do not change for -mlittle. | 2465 ;; zero_extract insns do not change for -mlittle. |
2459 (define_insn_and_split "bswapsi2_reg" | 2466 (define_insn_and_split "bswapsi2_reg" |
2460 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r") | 2467 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wo") |
2461 (bswap:SI | 2468 (bswap:SI |
2462 (match_operand:SI 1 "gpc_reg_operand" "r")))] | 2469 (match_operand:SI 1 "gpc_reg_operand" "r,wo")))] |
2463 "" | 2470 "" |
2464 "#" | 2471 "@ |
2465 "reload_completed" | 2472 # |
2473 xxbrw %x0,%x1" | |
2474 "reload_completed && int_reg_operand (operands[0], SImode)" | |
2466 [(set (match_dup 0) ; DABC | 2475 [(set (match_dup 0) ; DABC |
2467 (rotate:SI (match_dup 1) | 2476 (rotate:SI (match_dup 1) |
2468 (const_int 24))) | 2477 (const_int 24))) |
2469 (set (match_dup 0) ; DCBC | 2478 (set (match_dup 0) ; DCBC |
2470 (ior:SI (and:SI (ashift:SI (match_dup 1) | 2479 (ior:SI (and:SI (ashift:SI (match_dup 1) |
2476 (ior:SI (and:SI (lshiftrt:SI (match_dup 1) | 2485 (ior:SI (and:SI (lshiftrt:SI (match_dup 1) |
2477 (const_int 24)) | 2486 (const_int 24)) |
2478 (const_int 255)) | 2487 (const_int 255)) |
2479 (and:SI (match_dup 0) | 2488 (and:SI (match_dup 0) |
2480 (const_int -256))))] | 2489 (const_int -256))))] |
2481 "") | 2490 "" |
2491 [(set_attr "length" "12,4") | |
2492 (set_attr "type" "*,vecperm")]) | |
2482 | 2493 |
2483 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like | 2494 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like |
2484 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more | 2495 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more |
2485 ;; complex code. | 2496 ;; complex code. |
2486 | 2497 |
2487 (define_expand "bswapdi2" | 2498 (define_expand "bswapdi2" |
2488 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "") | 2499 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand") |
2489 (bswap:DI | 2500 (bswap:DI |
2490 (match_operand:DI 1 "reg_or_mem_operand" ""))) | 2501 (match_operand:DI 1 "reg_or_mem_operand"))) |
2491 (clobber (match_scratch:DI 2 "")) | 2502 (clobber (match_scratch:DI 2)) |
2492 (clobber (match_scratch:DI 3 ""))])] | 2503 (clobber (match_scratch:DI 3))])] |
2493 "" | 2504 "" |
2494 { | 2505 { |
2495 rtx dest = operands[0]; | 2506 rtx dest = operands[0]; |
2496 rtx src = operands[1]; | 2507 rtx src = operands[1]; |
2497 | 2508 |
2502 { | 2513 { |
2503 if (MEM_P (src)) | 2514 if (MEM_P (src)) |
2504 emit_insn (gen_bswapdi2_load (dest, src)); | 2515 emit_insn (gen_bswapdi2_load (dest, src)); |
2505 else if (MEM_P (dest)) | 2516 else if (MEM_P (dest)) |
2506 emit_insn (gen_bswapdi2_store (dest, src)); | 2517 emit_insn (gen_bswapdi2_store (dest, src)); |
2518 else if (TARGET_P9_VECTOR) | |
2519 emit_insn (gen_bswapdi2_xxbrd (dest, src)); | |
2507 else | 2520 else |
2508 emit_insn (gen_bswapdi2_reg (dest, src)); | 2521 emit_insn (gen_bswapdi2_reg (dest, src)); |
2509 DONE; | 2522 DONE; |
2510 } | 2523 } |
2511 | 2524 |
2532 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))] | 2545 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))] |
2533 "TARGET_POWERPC64 && TARGET_LDBRX" | 2546 "TARGET_POWERPC64 && TARGET_LDBRX" |
2534 "stdbrx %1,%y0" | 2547 "stdbrx %1,%y0" |
2535 [(set_attr "type" "store")]) | 2548 [(set_attr "type" "store")]) |
2536 | 2549 |
2550 (define_insn "bswapdi2_xxbrd" | |
2551 [(set (match_operand:DI 0 "gpc_reg_operand" "=wo") | |
2552 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wo")))] | |
2553 "TARGET_P9_VECTOR" | |
2554 "xxbrd %x0,%x1" | |
2555 [(set_attr "type" "vecperm")]) | |
2556 | |
2537 (define_insn "bswapdi2_reg" | 2557 (define_insn "bswapdi2_reg" |
2538 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r") | 2558 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r") |
2539 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r"))) | 2559 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r"))) |
2540 (clobber (match_scratch:DI 2 "=&r")) | 2560 (clobber (match_scratch:DI 2 "=&r")) |
2541 (clobber (match_scratch:DI 3 "=&r"))] | 2561 (clobber (match_scratch:DI 3 "=&r"))] |
2542 "TARGET_POWERPC64 && TARGET_LDBRX" | 2562 "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR" |
2543 "#" | 2563 "#" |
2544 [(set_attr "length" "36")]) | 2564 [(set_attr "length" "36")]) |
2545 | 2565 |
2546 ;; Non-power7/cell, fall back to use lwbrx/stwbrx | 2566 ;; Non-power7/cell, fall back to use lwbrx/stwbrx |
2547 (define_insn "*bswapdi2_64bit" | 2567 (define_insn "*bswapdi2_64bit" |
2555 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))" | 2575 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))" |
2556 "#" | 2576 "#" |
2557 [(set_attr "length" "16,12,36")]) | 2577 [(set_attr "length" "16,12,36")]) |
2558 | 2578 |
2559 (define_split | 2579 (define_split |
2560 [(set (match_operand:DI 0 "gpc_reg_operand" "") | 2580 [(set (match_operand:DI 0 "gpc_reg_operand") |
2561 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" ""))) | 2581 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand"))) |
2562 (clobber (match_operand:DI 2 "gpc_reg_operand" "")) | 2582 (clobber (match_operand:DI 2 "gpc_reg_operand")) |
2563 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))] | 2583 (clobber (match_operand:DI 3 "gpc_reg_operand"))] |
2564 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed" | 2584 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed" |
2565 [(const_int 0)] | 2585 [(const_int 0)] |
2566 " | |
2567 { | 2586 { |
2568 rtx dest = operands[0]; | 2587 rtx dest = operands[0]; |
2569 rtx src = operands[1]; | 2588 rtx src = operands[1]; |
2570 rtx op2 = operands[2]; | 2589 rtx op2 = operands[2]; |
2571 rtx op3 = operands[3]; | 2590 rtx op3 = operands[3]; |
2616 } | 2635 } |
2617 | 2636 |
2618 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32))); | 2637 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32))); |
2619 emit_insn (gen_iordi3 (dest, dest, op3)); | 2638 emit_insn (gen_iordi3 (dest, dest, op3)); |
2620 DONE; | 2639 DONE; |
2621 }") | 2640 }) |
2622 | 2641 |
2623 (define_split | 2642 (define_split |
2624 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "") | 2643 [(set (match_operand:DI 0 "indexed_or_indirect_operand") |
2625 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" ""))) | 2644 (bswap:DI (match_operand:DI 1 "gpc_reg_operand"))) |
2626 (clobber (match_operand:DI 2 "gpc_reg_operand" "")) | 2645 (clobber (match_operand:DI 2 "gpc_reg_operand")) |
2627 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))] | 2646 (clobber (match_operand:DI 3 "gpc_reg_operand"))] |
2628 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed" | 2647 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed" |
2629 [(const_int 0)] | 2648 [(const_int 0)] |
2630 " | |
2631 { | 2649 { |
2632 rtx dest = operands[0]; | 2650 rtx dest = operands[0]; |
2633 rtx src = operands[1]; | 2651 rtx src = operands[1]; |
2634 rtx op2 = operands[2]; | 2652 rtx op2 = operands[2]; |
2635 rtx op3 = operands[3]; | 2653 rtx op3 = operands[3]; |
2679 { | 2697 { |
2680 emit_insn (gen_bswapsi2 (word2, src_si)); | 2698 emit_insn (gen_bswapsi2 (word2, src_si)); |
2681 emit_insn (gen_bswapsi2 (word1, op3_si)); | 2699 emit_insn (gen_bswapsi2 (word1, op3_si)); |
2682 } | 2700 } |
2683 DONE; | 2701 DONE; |
2684 }") | 2702 }) |
2685 | 2703 |
2686 (define_split | 2704 (define_split |
2687 [(set (match_operand:DI 0 "gpc_reg_operand" "") | 2705 [(set (match_operand:DI 0 "gpc_reg_operand") |
2688 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" ""))) | 2706 (bswap:DI (match_operand:DI 1 "gpc_reg_operand"))) |
2689 (clobber (match_operand:DI 2 "gpc_reg_operand" "")) | 2707 (clobber (match_operand:DI 2 "gpc_reg_operand")) |
2690 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))] | 2708 (clobber (match_operand:DI 3 "gpc_reg_operand"))] |
2691 "TARGET_POWERPC64 && reload_completed" | 2709 "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed" |
2692 [(const_int 0)] | 2710 [(const_int 0)] |
2693 " | |
2694 { | 2711 { |
2695 rtx dest = operands[0]; | 2712 rtx dest = operands[0]; |
2696 rtx src = operands[1]; | 2713 rtx src = operands[1]; |
2697 rtx op2 = operands[2]; | 2714 rtx op2 = operands[2]; |
2698 rtx op3 = operands[3]; | 2715 rtx op3 = operands[3]; |
2706 emit_insn (gen_bswapsi2 (dest_si, src_si)); | 2723 emit_insn (gen_bswapsi2 (dest_si, src_si)); |
2707 emit_insn (gen_bswapsi2 (op3_si, op2_si)); | 2724 emit_insn (gen_bswapsi2 (op3_si, op2_si)); |
2708 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32))); | 2725 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32))); |
2709 emit_insn (gen_iordi3 (dest, dest, op3)); | 2726 emit_insn (gen_iordi3 (dest, dest, op3)); |
2710 DONE; | 2727 DONE; |
2711 }") | 2728 }) |
2712 | 2729 |
2713 (define_insn "bswapdi2_32bit" | 2730 (define_insn "bswapdi2_32bit" |
2714 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r") | 2731 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r") |
2715 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r"))) | 2732 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r"))) |
2716 (clobber (match_scratch:SI 2 "=&b,&b,X"))] | 2733 (clobber (match_scratch:SI 2 "=&b,&b,X"))] |
2717 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))" | 2734 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))" |
2718 "#" | 2735 "#" |
2719 [(set_attr "length" "16,12,36")]) | 2736 [(set_attr "length" "16,12,36")]) |
2720 | 2737 |
2721 (define_split | 2738 (define_split |
2722 [(set (match_operand:DI 0 "gpc_reg_operand" "") | 2739 [(set (match_operand:DI 0 "gpc_reg_operand") |
2723 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" ""))) | 2740 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand"))) |
2724 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))] | 2741 (clobber (match_operand:SI 2 "gpc_reg_operand"))] |
2725 "!TARGET_POWERPC64 && reload_completed" | 2742 "!TARGET_POWERPC64 && reload_completed" |
2726 [(const_int 0)] | 2743 [(const_int 0)] |
2727 " | |
2728 { | 2744 { |
2729 rtx dest = operands[0]; | 2745 rtx dest = operands[0]; |
2730 rtx src = operands[1]; | 2746 rtx src = operands[1]; |
2731 rtx op2 = operands[2]; | 2747 rtx op2 = operands[2]; |
2732 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0); | 2748 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0); |
2767 emit_insn (gen_bswapsi2 (dest2, word1)); | 2783 emit_insn (gen_bswapsi2 (dest2, word1)); |
2768 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed, | 2784 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed, |
2769 thus allowing us to omit an early clobber on the output. */ | 2785 thus allowing us to omit an early clobber on the output. */ |
2770 emit_insn (gen_bswapsi2 (dest1, word2)); | 2786 emit_insn (gen_bswapsi2 (dest1, word2)); |
2771 DONE; | 2787 DONE; |
2772 }") | 2788 }) |
2773 | 2789 |
2774 (define_split | 2790 (define_split |
2775 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "") | 2791 [(set (match_operand:DI 0 "indexed_or_indirect_operand") |
2776 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" ""))) | 2792 (bswap:DI (match_operand:DI 1 "gpc_reg_operand"))) |
2777 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))] | 2793 (clobber (match_operand:SI 2 "gpc_reg_operand"))] |
2778 "!TARGET_POWERPC64 && reload_completed" | 2794 "!TARGET_POWERPC64 && reload_completed" |
2779 [(const_int 0)] | 2795 [(const_int 0)] |
2780 " | |
2781 { | 2796 { |
2782 rtx dest = operands[0]; | 2797 rtx dest = operands[0]; |
2783 rtx src = operands[1]; | 2798 rtx src = operands[1]; |
2784 rtx op2 = operands[2]; | 2799 rtx op2 = operands[2]; |
2785 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0); | 2800 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0); |
2816 word2 = change_address (dest, SImode, addr2); | 2831 word2 = change_address (dest, SImode, addr2); |
2817 | 2832 |
2818 emit_insn (gen_bswapsi2 (word2, src1)); | 2833 emit_insn (gen_bswapsi2 (word2, src1)); |
2819 emit_insn (gen_bswapsi2 (word1, src2)); | 2834 emit_insn (gen_bswapsi2 (word1, src2)); |
2820 DONE; | 2835 DONE; |
2821 }") | 2836 }) |
2822 | 2837 |
2823 (define_split | 2838 (define_split |
2824 [(set (match_operand:DI 0 "gpc_reg_operand" "") | 2839 [(set (match_operand:DI 0 "gpc_reg_operand") |
2825 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" ""))) | 2840 (bswap:DI (match_operand:DI 1 "gpc_reg_operand"))) |
2826 (clobber (match_operand:SI 2 "" ""))] | 2841 (clobber (match_operand:SI 2 ""))] |
2827 "!TARGET_POWERPC64 && reload_completed" | 2842 "!TARGET_POWERPC64 && reload_completed" |
2828 [(const_int 0)] | 2843 [(const_int 0)] |
2829 " | |
2830 { | 2844 { |
2831 rtx dest = operands[0]; | 2845 rtx dest = operands[0]; |
2832 rtx src = operands[1]; | 2846 rtx src = operands[1]; |
2833 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0); | 2847 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0); |
2834 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4); | 2848 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4); |
2836 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4); | 2850 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4); |
2837 | 2851 |
2838 emit_insn (gen_bswapsi2 (dest1, src2)); | 2852 emit_insn (gen_bswapsi2 (dest1, src2)); |
2839 emit_insn (gen_bswapsi2 (dest2, src1)); | 2853 emit_insn (gen_bswapsi2 (dest2, src1)); |
2840 DONE; | 2854 DONE; |
2841 }") | 2855 }) |
2842 | 2856 |
2843 | 2857 |
2844 (define_insn "mul<mode>3" | 2858 (define_insn "mul<mode>3" |
2845 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") | 2859 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") |
2846 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") | 2860 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") |
2849 "@ | 2863 "@ |
2850 mull<wd> %0,%1,%2 | 2864 mull<wd> %0,%1,%2 |
2851 mulli %0,%1,%2" | 2865 mulli %0,%1,%2" |
2852 [(set_attr "type" "mul") | 2866 [(set_attr "type" "mul") |
2853 (set (attr "size") | 2867 (set (attr "size") |
2854 (cond [(match_operand:GPR 2 "s8bit_cint_operand" "") | 2868 (cond [(match_operand:GPR 2 "s8bit_cint_operand") |
2855 (const_string "8") | 2869 (const_string "8") |
2856 (match_operand:GPR 2 "short_cint_operand" "") | 2870 (match_operand:GPR 2 "short_cint_operand") |
2857 (const_string "16")] | 2871 (const_string "16")] |
2858 (const_string "<bits>")))]) | 2872 (const_string "<bits>")))]) |
2859 | 2873 |
2860 (define_insn_and_split "*mul<mode>3_dot" | 2874 (define_insn_and_split "*mul<mode>3_dot" |
2861 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") | 2875 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") |
3020 | 3034 |
3021 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for | 3035 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for |
3022 ;; modulus. If it isn't a power of two, force operands into register and do | 3036 ;; modulus. If it isn't a power of two, force operands into register and do |
3023 ;; a normal divide. | 3037 ;; a normal divide. |
3024 (define_expand "div<mode>3" | 3038 (define_expand "div<mode>3" |
3025 [(set (match_operand:GPR 0 "gpc_reg_operand" "") | 3039 [(set (match_operand:GPR 0 "gpc_reg_operand") |
3026 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "") | 3040 (div:GPR (match_operand:GPR 1 "gpc_reg_operand") |
3027 (match_operand:GPR 2 "reg_or_cint_operand" "")))] | 3041 (match_operand:GPR 2 "reg_or_cint_operand")))] |
3028 "" | 3042 "" |
3029 { | 3043 { |
3030 if (CONST_INT_P (operands[2]) | 3044 if (CONST_INT_P (operands[2]) |
3031 && INTVAL (operands[2]) > 0 | 3045 && INTVAL (operands[2]) > 0 |
3032 && exact_log2 (INTVAL (operands[2])) >= 0) | 3046 && exact_log2 (INTVAL (operands[2])) >= 0) |
3162 ;; On machines with modulo support, do a combined div/mod the old fashioned | 3176 ;; On machines with modulo support, do a combined div/mod the old fashioned |
3163 ;; method, since the multiply/subtract is faster than doing the mod instruction | 3177 ;; method, since the multiply/subtract is faster than doing the mod instruction |
3164 ;; after a divide. | 3178 ;; after a divide. |
3165 | 3179 |
3166 (define_peephole2 | 3180 (define_peephole2 |
3167 [(set (match_operand:GPR 0 "gpc_reg_operand" "") | 3181 [(set (match_operand:GPR 0 "gpc_reg_operand") |
3168 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "") | 3182 (div:GPR (match_operand:GPR 1 "gpc_reg_operand") |
3169 (match_operand:GPR 2 "gpc_reg_operand" ""))) | 3183 (match_operand:GPR 2 "gpc_reg_operand"))) |
3170 (set (match_operand:GPR 3 "gpc_reg_operand" "") | 3184 (set (match_operand:GPR 3 "gpc_reg_operand") |
3171 (mod:GPR (match_dup 1) | 3185 (mod:GPR (match_dup 1) |
3172 (match_dup 2)))] | 3186 (match_dup 2)))] |
3173 "TARGET_MODULO | 3187 "TARGET_MODULO |
3174 && ! reg_mentioned_p (operands[0], operands[1]) | 3188 && ! reg_mentioned_p (operands[0], operands[1]) |
3175 && ! reg_mentioned_p (operands[0], operands[2]) | 3189 && ! reg_mentioned_p (operands[0], operands[2]) |
3184 (set (match_dup 3) | 3198 (set (match_dup 3) |
3185 (minus:GPR (match_dup 1) | 3199 (minus:GPR (match_dup 1) |
3186 (match_dup 3)))]) | 3200 (match_dup 3)))]) |
3187 | 3201 |
3188 (define_peephole2 | 3202 (define_peephole2 |
3189 [(set (match_operand:GPR 0 "gpc_reg_operand" "") | 3203 [(set (match_operand:GPR 0 "gpc_reg_operand") |
3190 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "") | 3204 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand") |
3191 (match_operand:GPR 2 "gpc_reg_operand" ""))) | 3205 (match_operand:GPR 2 "gpc_reg_operand"))) |
3192 (set (match_operand:GPR 3 "gpc_reg_operand" "") | 3206 (set (match_operand:GPR 3 "gpc_reg_operand") |
3193 (umod:GPR (match_dup 1) | 3207 (umod:GPR (match_dup 1) |
3194 (match_dup 2)))] | 3208 (match_dup 2)))] |
3195 "TARGET_MODULO | 3209 "TARGET_MODULO |
3196 && ! reg_mentioned_p (operands[0], operands[1]) | 3210 && ! reg_mentioned_p (operands[0], operands[1]) |
3197 && ! reg_mentioned_p (operands[0], operands[2]) | 3211 && ! reg_mentioned_p (operands[0], operands[2]) |
3213 ;; but the plain AND insns are somewhat different because there is no | 3227 ;; but the plain AND insns are somewhat different because there is no |
3214 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all | 3228 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all |
3215 ;; those rotate-and-mask operations. Thus, the AND insns come first. | 3229 ;; those rotate-and-mask operations. Thus, the AND insns come first. |
3216 | 3230 |
3217 (define_expand "and<mode>3" | 3231 (define_expand "and<mode>3" |
3218 [(set (match_operand:SDI 0 "gpc_reg_operand" "") | 3232 [(set (match_operand:SDI 0 "gpc_reg_operand") |
3219 (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "") | 3233 (and:SDI (match_operand:SDI 1 "gpc_reg_operand") |
3220 (match_operand:SDI 2 "reg_or_cint_operand" "")))] | 3234 (match_operand:SDI 2 "reg_or_cint_operand")))] |
3221 "" | 3235 "" |
3222 { | 3236 { |
3223 if (<MODE>mode == DImode && !TARGET_POWERPC64) | 3237 if (<MODE>mode == DImode && !TARGET_POWERPC64) |
3224 { | 3238 { |
3225 rs6000_split_logical (operands, AND, false, false, false); | 3239 rs6000_split_logical (operands, AND, false, false, false); |
3511 (set_attr "dot" "yes") | 3525 (set_attr "dot" "yes") |
3512 (set_attr "length" "8,12")]) | 3526 (set_attr "length" "8,12")]) |
3513 | 3527 |
3514 | 3528 |
3515 (define_expand "<code><mode>3" | 3529 (define_expand "<code><mode>3" |
3516 [(set (match_operand:SDI 0 "gpc_reg_operand" "") | 3530 [(set (match_operand:SDI 0 "gpc_reg_operand") |
3517 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "") | 3531 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand") |
3518 (match_operand:SDI 2 "reg_or_cint_operand" "")))] | 3532 (match_operand:SDI 2 "reg_or_cint_operand")))] |
3519 "" | 3533 "" |
3520 { | 3534 { |
3521 if (<MODE>mode == DImode && !TARGET_POWERPC64) | 3535 if (<MODE>mode == DImode && !TARGET_POWERPC64) |
3522 { | 3536 { |
3523 rs6000_split_logical (operands, <CODE>, false, false, false); | 3537 rs6000_split_logical (operands, <CODE>, false, false, false); |
3542 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode)) | 3556 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode)) |
3543 operands[2] = force_reg (<MODE>mode, operands[2]); | 3557 operands[2] = force_reg (<MODE>mode, operands[2]); |
3544 }) | 3558 }) |
3545 | 3559 |
3546 (define_split | 3560 (define_split |
3547 [(set (match_operand:GPR 0 "gpc_reg_operand" "") | 3561 [(set (match_operand:GPR 0 "gpc_reg_operand") |
3548 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "") | 3562 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand") |
3549 (match_operand:GPR 2 "non_logical_cint_operand" "")))] | 3563 (match_operand:GPR 2 "non_logical_cint_operand")))] |
3550 "" | 3564 "" |
3551 [(set (match_dup 3) | 3565 [(set (match_dup 3) |
3552 (iorxor:GPR (match_dup 1) | 3566 (iorxor:GPR (match_dup 1) |
3553 (match_dup 4))) | 3567 (match_dup 4))) |
3554 (set (match_dup 0) | 3568 (set (match_dup 0) |
3827 (set_attr "dot" "yes") | 3841 (set_attr "dot" "yes") |
3828 (set_attr "length" "4,8")]) | 3842 (set_attr "length" "4,8")]) |
3829 | 3843 |
3830 ; Special case for less-than-0. We can do it with just one machine | 3844 ; Special case for less-than-0. We can do it with just one machine |
3831 ; instruction, but the generic optimizers do not realise it is cheap. | 3845 ; instruction, but the generic optimizers do not realise it is cheap. |
3832 (define_insn "*lt0_disi" | 3846 (define_insn "*lt0_<mode>di" |
3833 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") | 3847 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") |
3834 (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r") | 3848 (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r") |
3835 (const_int 0)))] | 3849 (const_int 0)))] |
3836 "TARGET_POWERPC64" | 3850 "TARGET_POWERPC64" |
3851 "srdi %0,%1,63" | |
3852 [(set_attr "type" "shift")]) | |
3853 | |
3854 (define_insn "*lt0_<mode>si" | |
3855 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") | |
3856 (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r") | |
3857 (const_int 0)))] | |
3858 "" | |
3837 "rlwinm %0,%1,1,31,31" | 3859 "rlwinm %0,%1,1,31,31" |
3838 [(set_attr "type" "shift")]) | 3860 [(set_attr "type" "shift")]) |
3839 | 3861 |
3840 | 3862 |
3841 | 3863 |
4032 operands[4] = GEN_INT (ne); | 4054 operands[4] = GEN_INT (ne); |
4033 operands[5] = GEN_INT (~UINTVAL (operands[2])); | 4055 operands[5] = GEN_INT (~UINTVAL (operands[2])); |
4034 } | 4056 } |
4035 [(set_attr "type" "two") | 4057 [(set_attr "type" "two") |
4036 (set_attr "length" "8")]) | 4058 (set_attr "length" "8")]) |
4059 | |
4060 | |
4061 ; Yet another case is an rldimi with the second value coming from memory. | |
4062 ; The zero_extend that should become part of the rldimi is merged into the | |
4063 ; load from memory instead. Split things properly again. | |
4064 (define_split | |
4065 [(set (match_operand:DI 0 "gpc_reg_operand") | |
4066 (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand") | |
4067 (match_operand:SI 2 "const_int_operand")) | |
4068 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))] | |
4069 "INTVAL (operands[2]) == <bits>" | |
4070 [(set (match_dup 4) | |
4071 (zero_extend:DI (match_dup 3))) | |
4072 (set (match_dup 0) | |
4073 (ior:DI (and:DI (match_dup 4) | |
4074 (match_dup 5)) | |
4075 (ashift:DI (match_dup 1) | |
4076 (match_dup 2))))] | |
4077 { | |
4078 operands[4] = gen_reg_rtx (DImode); | |
4079 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1); | |
4080 }) | |
4081 | |
4082 ; rlwimi, too. | |
4083 (define_split | |
4084 [(set (match_operand:SI 0 "gpc_reg_operand") | |
4085 (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand") | |
4086 (match_operand:SI 2 "const_int_operand")) | |
4087 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))] | |
4088 "INTVAL (operands[2]) == <bits>" | |
4089 [(set (match_dup 4) | |
4090 (zero_extend:SI (match_dup 3))) | |
4091 (set (match_dup 0) | |
4092 (ior:SI (and:SI (match_dup 4) | |
4093 (match_dup 5)) | |
4094 (ashift:SI (match_dup 1) | |
4095 (match_dup 2))))] | |
4096 { | |
4097 operands[4] = gen_reg_rtx (SImode); | |
4098 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1); | |
4099 }) | |
4037 | 4100 |
4038 | 4101 |
4039 ;; Now the simple shifts. | 4102 ;; Now the simple shifts. |
4040 | 4103 |
4041 (define_insn "rotl<mode>3" | 4104 (define_insn "rotl<mode>3" |
4437 (set_attr "length" "4,8")]) | 4500 (set_attr "length" "4,8")]) |
4438 | 4501 |
4439 ;; Builtins to replace a division to generate FRE reciprocal estimate | 4502 ;; Builtins to replace a division to generate FRE reciprocal estimate |
4440 ;; instructions and the necessary fixup instructions | 4503 ;; instructions and the necessary fixup instructions |
4441 (define_expand "recip<mode>3" | 4504 (define_expand "recip<mode>3" |
4442 [(match_operand:RECIPF 0 "gpc_reg_operand" "") | 4505 [(match_operand:RECIPF 0 "gpc_reg_operand") |
4443 (match_operand:RECIPF 1 "gpc_reg_operand" "") | 4506 (match_operand:RECIPF 1 "gpc_reg_operand") |
4444 (match_operand:RECIPF 2 "gpc_reg_operand" "")] | 4507 (match_operand:RECIPF 2 "gpc_reg_operand")] |
4445 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)" | 4508 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)" |
4446 { | 4509 { |
4447 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false); | 4510 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false); |
4448 DONE; | 4511 DONE; |
4449 }) | 4512 }) |
4452 ;; hardware division. This is only done before register allocation and with | 4515 ;; hardware division. This is only done before register allocation and with |
4453 ;; -ffast-math. This must appear before the divsf3/divdf3 insns. | 4516 ;; -ffast-math. This must appear before the divsf3/divdf3 insns. |
4454 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed | 4517 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed |
4455 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed. | 4518 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed. |
4456 (define_split | 4519 (define_split |
4457 [(set (match_operand:RECIPF 0 "gpc_reg_operand" "") | 4520 [(set (match_operand:RECIPF 0 "gpc_reg_operand") |
4458 (div:RECIPF (match_operand 1 "gpc_reg_operand" "") | 4521 (div:RECIPF (match_operand 1 "gpc_reg_operand") |
4459 (match_operand 2 "gpc_reg_operand" "")))] | 4522 (match_operand 2 "gpc_reg_operand")))] |
4460 "RS6000_RECIP_AUTO_RE_P (<MODE>mode) | 4523 "RS6000_RECIP_AUTO_RE_P (<MODE>mode) |
4461 && can_create_pseudo_p () && flag_finite_math_only | 4524 && can_create_pseudo_p () && flag_finite_math_only |
4462 && !flag_trapping_math && flag_reciprocal_math" | 4525 && !flag_trapping_math && flag_reciprocal_math" |
4463 [(const_int 0)] | 4526 [(const_int 0)] |
4464 { | 4527 { |
4467 }) | 4530 }) |
4468 | 4531 |
4469 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the | 4532 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the |
4470 ;; appropriate fixup. | 4533 ;; appropriate fixup. |
4471 (define_expand "rsqrt<mode>2" | 4534 (define_expand "rsqrt<mode>2" |
4472 [(match_operand:RECIPF 0 "gpc_reg_operand" "") | 4535 [(match_operand:RECIPF 0 "gpc_reg_operand") |
4473 (match_operand:RECIPF 1 "gpc_reg_operand" "")] | 4536 (match_operand:RECIPF 1 "gpc_reg_operand")] |
4474 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)" | 4537 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)" |
4475 { | 4538 { |
4476 rs6000_emit_swsqrt (operands[0], operands[1], 1); | 4539 rs6000_emit_swsqrt (operands[0], operands[1], 1); |
4477 DONE; | 4540 DONE; |
4478 }) | 4541 }) |
4481 ;; modes here, and also add in conditional vsx/power8-vector support to access | 4544 ;; modes here, and also add in conditional vsx/power8-vector support to access |
4482 ;; values in the traditional Altivec registers if the appropriate | 4545 ;; values in the traditional Altivec registers if the appropriate |
4483 ;; -mupper-regs-{df,sf} option is enabled. | 4546 ;; -mupper-regs-{df,sf} option is enabled. |
4484 | 4547 |
4485 (define_expand "abs<mode>2" | 4548 (define_expand "abs<mode>2" |
4486 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") | 4549 [(set (match_operand:SFDF 0 "gpc_reg_operand") |
4487 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))] | 4550 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))] |
4488 "TARGET_<MODE>_INSN" | 4551 "TARGET_HARD_FLOAT" |
4489 "") | 4552 "") |
4490 | 4553 |
4491 (define_insn "*abs<mode>2_fpr" | 4554 (define_insn "*abs<mode>2_fpr" |
4492 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") | 4555 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") |
4493 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] | 4556 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] |
4494 "TARGET_<MODE>_FPR" | 4557 "TARGET_HARD_FLOAT" |
4495 "@ | 4558 "@ |
4496 fabs %0,%1 | 4559 fabs %0,%1 |
4497 xsabsdp %x0,%x1" | 4560 xsabsdp %x0,%x1" |
4498 [(set_attr "type" "fpsimple") | 4561 [(set_attr "type" "fpsimple")]) |
4499 (set_attr "fp_type" "fp_addsub_<Fs>")]) | |
4500 | 4562 |
4501 (define_insn "*nabs<mode>2_fpr" | 4563 (define_insn "*nabs<mode>2_fpr" |
4502 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") | 4564 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") |
4503 (neg:SFDF | 4565 (neg:SFDF |
4504 (abs:SFDF | 4566 (abs:SFDF |
4505 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))] | 4567 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))] |
4506 "TARGET_<MODE>_FPR" | 4568 "TARGET_HARD_FLOAT" |
4507 "@ | 4569 "@ |
4508 fnabs %0,%1 | 4570 fnabs %0,%1 |
4509 xsnabsdp %x0,%x1" | 4571 xsnabsdp %x0,%x1" |
4510 [(set_attr "type" "fpsimple") | 4572 [(set_attr "type" "fpsimple")]) |
4511 (set_attr "fp_type" "fp_addsub_<Fs>")]) | |
4512 | 4573 |
4513 (define_expand "neg<mode>2" | 4574 (define_expand "neg<mode>2" |
4514 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") | 4575 [(set (match_operand:SFDF 0 "gpc_reg_operand") |
4515 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))] | 4576 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))] |
4516 "TARGET_<MODE>_INSN" | 4577 "TARGET_HARD_FLOAT" |
4517 "") | 4578 "") |
4518 | 4579 |
4519 (define_insn "*neg<mode>2_fpr" | 4580 (define_insn "*neg<mode>2_fpr" |
4520 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") | 4581 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") |
4521 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] | 4582 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] |
4522 "TARGET_<MODE>_FPR" | 4583 "TARGET_HARD_FLOAT" |
4523 "@ | 4584 "@ |
4524 fneg %0,%1 | 4585 fneg %0,%1 |
4525 xsnegdp %x0,%x1" | 4586 xsnegdp %x0,%x1" |
4526 [(set_attr "type" "fpsimple") | 4587 [(set_attr "type" "fpsimple")]) |
4527 (set_attr "fp_type" "fp_addsub_<Fs>")]) | |
4528 | 4588 |
4529 (define_expand "add<mode>3" | 4589 (define_expand "add<mode>3" |
4530 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") | 4590 [(set (match_operand:SFDF 0 "gpc_reg_operand") |
4531 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "") | 4591 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand") |
4532 (match_operand:SFDF 2 "gpc_reg_operand" "")))] | 4592 (match_operand:SFDF 2 "gpc_reg_operand")))] |
4533 "TARGET_<MODE>_INSN" | 4593 "TARGET_HARD_FLOAT" |
4534 "") | 4594 "") |
4535 | 4595 |
4536 (define_insn "*add<mode>3_fpr" | 4596 (define_insn "*add<mode>3_fpr" |
4537 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") | 4597 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") |
4538 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>") | 4598 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>") |
4539 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] | 4599 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] |
4540 "TARGET_<MODE>_FPR" | 4600 "TARGET_HARD_FLOAT" |
4541 "@ | 4601 "@ |
4542 fadd<Ftrad> %0,%1,%2 | 4602 fadd<Ftrad> %0,%1,%2 |
4543 xsadd<Fvsx> %x0,%x1,%x2" | 4603 xsadd<Fvsx> %x0,%x1,%x2" |
4544 [(set_attr "type" "fp") | 4604 [(set_attr "type" "fp")]) |
4545 (set_attr "fp_type" "fp_addsub_<Fs>")]) | |
4546 | 4605 |
4547 (define_expand "sub<mode>3" | 4606 (define_expand "sub<mode>3" |
4548 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") | 4607 [(set (match_operand:SFDF 0 "gpc_reg_operand") |
4549 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "") | 4608 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand") |
4550 (match_operand:SFDF 2 "gpc_reg_operand" "")))] | 4609 (match_operand:SFDF 2 "gpc_reg_operand")))] |
4551 "TARGET_<MODE>_INSN" | 4610 "TARGET_HARD_FLOAT" |
4552 "") | 4611 "") |
4553 | 4612 |
4554 (define_insn "*sub<mode>3_fpr" | 4613 (define_insn "*sub<mode>3_fpr" |
4555 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") | 4614 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") |
4556 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>") | 4615 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>") |
4557 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] | 4616 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] |
4558 "TARGET_<MODE>_FPR" | 4617 "TARGET_HARD_FLOAT" |
4559 "@ | 4618 "@ |
4560 fsub<Ftrad> %0,%1,%2 | 4619 fsub<Ftrad> %0,%1,%2 |
4561 xssub<Fvsx> %x0,%x1,%x2" | 4620 xssub<Fvsx> %x0,%x1,%x2" |
4562 [(set_attr "type" "fp") | 4621 [(set_attr "type" "fp")]) |
4563 (set_attr "fp_type" "fp_addsub_<Fs>")]) | |
4564 | 4622 |
4565 (define_expand "mul<mode>3" | 4623 (define_expand "mul<mode>3" |
4566 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") | 4624 [(set (match_operand:SFDF 0 "gpc_reg_operand") |
4567 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "") | 4625 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand") |
4568 (match_operand:SFDF 2 "gpc_reg_operand" "")))] | 4626 (match_operand:SFDF 2 "gpc_reg_operand")))] |
4569 "TARGET_<MODE>_INSN" | 4627 "TARGET_HARD_FLOAT" |
4570 "") | 4628 "") |
4571 | 4629 |
4572 (define_insn "*mul<mode>3_fpr" | 4630 (define_insn "*mul<mode>3_fpr" |
4573 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") | 4631 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") |
4574 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>") | 4632 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>") |
4575 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] | 4633 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] |
4576 "TARGET_<MODE>_FPR" | 4634 "TARGET_HARD_FLOAT" |
4577 "@ | 4635 "@ |
4578 fmul<Ftrad> %0,%1,%2 | 4636 fmul<Ftrad> %0,%1,%2 |
4579 xsmul<Fvsx> %x0,%x1,%x2" | 4637 xsmul<Fvsx> %x0,%x1,%x2" |
4580 [(set_attr "type" "dmul") | 4638 [(set_attr "type" "dmul")]) |
4581 (set_attr "fp_type" "fp_mul_<Fs>")]) | |
4582 | 4639 |
4583 (define_expand "div<mode>3" | 4640 (define_expand "div<mode>3" |
4584 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") | 4641 [(set (match_operand:SFDF 0 "gpc_reg_operand") |
4585 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "") | 4642 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand") |
4586 (match_operand:SFDF 2 "gpc_reg_operand" "")))] | 4643 (match_operand:SFDF 2 "gpc_reg_operand")))] |
4587 "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU" | 4644 "TARGET_HARD_FLOAT" |
4588 { | 4645 { |
4589 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode) | 4646 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode) |
4590 && can_create_pseudo_p () && flag_finite_math_only | 4647 && can_create_pseudo_p () && flag_finite_math_only |
4591 && !flag_trapping_math && flag_reciprocal_math) | 4648 && !flag_trapping_math && flag_reciprocal_math) |
4592 { | 4649 { |
4597 | 4654 |
4598 (define_insn "*div<mode>3_fpr" | 4655 (define_insn "*div<mode>3_fpr" |
4599 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") | 4656 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") |
4600 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>") | 4657 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>") |
4601 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] | 4658 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] |
4602 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU" | 4659 "TARGET_HARD_FLOAT" |
4603 "@ | 4660 "@ |
4604 fdiv<Ftrad> %0,%1,%2 | 4661 fdiv<Ftrad> %0,%1,%2 |
4605 xsdiv<Fvsx> %x0,%x1,%x2" | 4662 xsdiv<Fvsx> %x0,%x1,%x2" |
4606 [(set_attr "type" "<Fs>div") | 4663 [(set_attr "type" "<Fs>div")]) |
4607 (set_attr "fp_type" "fp_div_<Fs>")]) | |
4608 | 4664 |
4609 (define_insn "*sqrt<mode>2_internal" | 4665 (define_insn "*sqrt<mode>2_internal" |
4610 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") | 4666 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") |
4611 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))] | 4667 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))] |
4612 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU | 4668 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT" |
4613 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))" | |
4614 "@ | 4669 "@ |
4615 fsqrt<Ftrad> %0,%1 | 4670 fsqrt<Ftrad> %0,%1 |
4616 xssqrt<Fvsx> %x0,%x1" | 4671 xssqrt<Fvsx> %x0,%x1" |
4617 [(set_attr "type" "<Fs>sqrt") | 4672 [(set_attr "type" "<Fs>sqrt")]) |
4618 (set_attr "fp_type" "fp_sqrt_<Fs>")]) | |
4619 | 4673 |
4620 (define_expand "sqrt<mode>2" | 4674 (define_expand "sqrt<mode>2" |
4621 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") | 4675 [(set (match_operand:SFDF 0 "gpc_reg_operand") |
4622 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))] | 4676 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))] |
4623 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU | 4677 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT" |
4624 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))" | |
4625 { | 4678 { |
4626 if (<MODE>mode == SFmode | 4679 if (<MODE>mode == SFmode |
4627 && TARGET_RECIP_PRECISION | 4680 && TARGET_RECIP_PRECISION |
4628 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode) | 4681 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode) |
4629 && !optimize_function_for_size_p (cfun) | 4682 && !optimize_function_for_size_p (cfun) |
4659 ;; Floating point comparisons | 4712 ;; Floating point comparisons |
4660 (define_insn "*cmp<mode>_fpr" | 4713 (define_insn "*cmp<mode>_fpr" |
4661 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y") | 4714 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y") |
4662 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>") | 4715 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>") |
4663 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] | 4716 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] |
4664 "TARGET_<MODE>_FPR" | 4717 "TARGET_HARD_FLOAT" |
4665 "@ | 4718 "@ |
4666 fcmpu %0,%1,%2 | 4719 fcmpu %0,%1,%2 |
4667 xscmpudp %0,%x1,%x2" | 4720 xscmpudp %0,%x1,%x2" |
4668 [(set_attr "type" "fpcompare")]) | 4721 [(set_attr "type" "fpcompare")]) |
4669 | 4722 |
4670 ;; Floating point conversions | 4723 ;; Floating point conversions |
4671 (define_expand "extendsfdf2" | 4724 (define_expand "extendsfdf2" |
4672 [(set (match_operand:DF 0 "gpc_reg_operand") | 4725 [(set (match_operand:DF 0 "gpc_reg_operand") |
4673 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))] | 4726 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))] |
4674 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" | 4727 "TARGET_HARD_FLOAT" |
4675 { | 4728 { |
4676 if (HONOR_SNANS (SFmode)) | 4729 if (HONOR_SNANS (SFmode)) |
4677 operands[1] = force_reg (SFmode, operands[1]); | 4730 operands[1] = force_reg (SFmode, operands[1]); |
4678 }) | 4731 }) |
4679 | 4732 |
4680 (define_insn_and_split "*extendsfdf2_fpr" | 4733 (define_insn_and_split "*extendsfdf2_fpr" |
4681 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb") | 4734 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb") |
4682 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))] | 4735 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))] |
4683 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !HONOR_SNANS (SFmode)" | 4736 "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)" |
4684 "@ | 4737 "@ |
4685 # | 4738 # |
4686 fmr %0,%1 | 4739 fmr %0,%1 |
4687 lfs%U1%X1 %0,%1 | 4740 lfs%U1%X1 %0,%1 |
4688 # | 4741 # |
4698 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")]) | 4751 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")]) |
4699 | 4752 |
4700 (define_insn "*extendsfdf2_snan" | 4753 (define_insn "*extendsfdf2_snan" |
4701 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") | 4754 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") |
4702 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))] | 4755 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))] |
4703 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && HONOR_SNANS (SFmode)" | 4756 "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)" |
4704 "@ | 4757 "@ |
4705 frsp %0,%1 | 4758 frsp %0,%1 |
4706 xsrsp %x0,%x1" | 4759 xsrsp %x0,%x1" |
4707 [(set_attr "type" "fp")]) | 4760 [(set_attr "type" "fp")]) |
4708 | 4761 |
4709 (define_expand "truncdfsf2" | 4762 (define_expand "truncdfsf2" |
4710 [(set (match_operand:SF 0 "gpc_reg_operand" "") | 4763 [(set (match_operand:SF 0 "gpc_reg_operand") |
4711 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))] | 4764 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))] |
4712 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" | 4765 "TARGET_HARD_FLOAT" |
4713 "") | 4766 "") |
4714 | 4767 |
4715 (define_insn "*truncdfsf2_fpr" | 4768 (define_insn "*truncdfsf2_fpr" |
4716 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy") | 4769 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy") |
4717 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))] | 4770 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))] |
4718 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" | 4771 "TARGET_HARD_FLOAT" |
4719 "@ | 4772 "@ |
4720 frsp %0,%1 | 4773 frsp %0,%1 |
4721 xsrsp %x0,%x1" | 4774 xsrsp %x0,%x1" |
4722 [(set_attr "type" "fp")]) | 4775 [(set_attr "type" "fp")]) |
4723 | 4776 |
4724 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in | 4777 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in |
4725 ;; builtins.c and optabs.c that are not correct for IBM long double | 4778 ;; builtins.c and optabs.c that are not correct for IBM long double |
4726 ;; when little-endian. | 4779 ;; when little-endian. |
4727 (define_expand "signbit<mode>2" | 4780 (define_expand "signbit<mode>2" |
4728 [(set (match_dup 2) | 4781 [(set (match_dup 2) |
4729 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" ""))) | 4782 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand"))) |
4730 (set (match_dup 3) | 4783 (set (match_dup 3) |
4731 (subreg:DI (match_dup 2) 0)) | 4784 (subreg:DI (match_dup 2) 0)) |
4732 (set (match_dup 4) | 4785 (set (match_dup 4) |
4733 (match_dup 5)) | 4786 (match_dup 5)) |
4734 (set (match_operand:SI 0 "gpc_reg_operand" "") | 4787 (set (match_operand:SI 0 "gpc_reg_operand") |
4735 (match_dup 6))] | 4788 (match_dup 6))] |
4736 "TARGET_HARD_FLOAT | 4789 "TARGET_HARD_FLOAT |
4737 && (!FLOAT128_IEEE_P (<MODE>mode) | 4790 && (!FLOAT128_IEEE_P (<MODE>mode) |
4738 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))" | 4791 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))" |
4739 { | 4792 { |
4740 if (FLOAT128_IEEE_P (<MODE>mode)) | 4793 if (FLOAT128_IEEE_P (<MODE>mode)) |
4741 { | 4794 { |
4795 rtx dest = operands[0]; | |
4796 rtx src = operands[1]; | |
4797 rtx tmp = gen_reg_rtx (DImode); | |
4798 rtx dest_di = gen_lowpart (DImode, dest); | |
4799 | |
4742 if (<MODE>mode == KFmode) | 4800 if (<MODE>mode == KFmode) |
4743 emit_insn (gen_signbitkf2_dm (operands[0], operands[1])); | 4801 emit_insn (gen_signbitkf2_dm (tmp, src)); |
4744 else if (<MODE>mode == TFmode) | 4802 else if (<MODE>mode == TFmode) |
4745 emit_insn (gen_signbittf2_dm (operands[0], operands[1])); | 4803 emit_insn (gen_signbittf2_dm (tmp, src)); |
4746 else | 4804 else |
4747 gcc_unreachable (); | 4805 gcc_unreachable (); |
4806 | |
4807 emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63))); | |
4748 DONE; | 4808 DONE; |
4749 } | 4809 } |
4750 operands[2] = gen_reg_rtx (DFmode); | 4810 operands[2] = gen_reg_rtx (DFmode); |
4751 operands[3] = gen_reg_rtx (DImode); | 4811 operands[3] = gen_reg_rtx (DImode); |
4752 if (TARGET_POWERPC64) | 4812 if (TARGET_POWERPC64) |
4763 WORDS_BIG_ENDIAN ? 0 : 4); | 4823 WORDS_BIG_ENDIAN ? 0 : 4); |
4764 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31)); | 4824 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31)); |
4765 } | 4825 } |
4766 }) | 4826 }) |
4767 | 4827 |
4828 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid | |
4829 ;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the | |
4830 ;; register allocator would typically move the entire _Float128 item to GPRs (2 | |
4831 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07). | |
4832 ;; | |
4833 ;; After register allocation, if the _Float128 had originally been in GPRs, the | |
4834 ;; split allows the post reload phases to eliminate the move, and do the shift | |
4835 ;; directly with the register that contains the signbit. | |
4836 (define_insn_and_split "signbit<mode>2_dm" | |
4837 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") | |
4838 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")] | |
4839 UNSPEC_SIGNBIT))] | |
4840 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" | |
4841 "@ | |
4842 mfvsrd %0,%x1 | |
4843 #" | |
4844 "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)" | |
4845 [(set (match_dup 0) | |
4846 (match_dup 2))] | |
4847 { | |
4848 operands[2] = gen_highpart (DImode, operands[1]); | |
4849 } | |
4850 [(set_attr "type" "mftgpr,*")]) | |
4851 | |
4852 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector | |
4853 ;; register and then doing a direct move if the value comes from memory. On | |
4854 ;; little endian, we have to load the 2nd double-word to get the sign bit. | |
4855 (define_insn_and_split "*signbit<mode>2_dm_mem" | |
4856 [(set (match_operand:DI 0 "gpc_reg_operand" "=b") | |
4857 (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")] | |
4858 UNSPEC_SIGNBIT))] | |
4859 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" | |
4860 "#" | |
4861 "&& 1" | |
4862 [(set (match_dup 0) | |
4863 (match_dup 2))] | |
4864 { | |
4865 rtx dest = operands[0]; | |
4866 rtx src = operands[1]; | |
4867 rtx addr = XEXP (src, 0); | |
4868 | |
4869 if (WORDS_BIG_ENDIAN) | |
4870 operands[2] = adjust_address (src, DImode, 0); | |
4871 | |
4872 else if (REG_P (addr) || SUBREG_P (addr)) | |
4873 operands[2] = adjust_address (src, DImode, 8); | |
4874 | |
4875 else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0)) | |
4876 && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode)) | |
4877 operands[2] = adjust_address (src, DImode, 8); | |
4878 | |
4879 else | |
4880 { | |
4881 rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest; | |
4882 emit_insn (gen_rtx_SET (tmp, addr)); | |
4883 operands[2] = change_address (src, DImode, | |
4884 gen_rtx_PLUS (DImode, tmp, GEN_INT (8))); | |
4885 } | |
4886 }) | |
4887 | |
4768 (define_expand "copysign<mode>3" | 4888 (define_expand "copysign<mode>3" |
4769 [(set (match_dup 3) | 4889 [(set (match_dup 3) |
4770 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" ""))) | 4890 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand"))) |
4771 (set (match_dup 4) | 4891 (set (match_dup 4) |
4772 (neg:SFDF (abs:SFDF (match_dup 1)))) | 4892 (neg:SFDF (abs:SFDF (match_dup 1)))) |
4773 (set (match_operand:SFDF 0 "gpc_reg_operand" "") | 4893 (set (match_operand:SFDF 0 "gpc_reg_operand") |
4774 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "") | 4894 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand") |
4775 (match_dup 5)) | 4895 (match_dup 5)) |
4776 (match_dup 3) | 4896 (match_dup 3) |
4777 (match_dup 4)))] | 4897 (match_dup 4)))] |
4778 "TARGET_HARD_FLOAT && <TARGET_FLOAT> | 4898 "TARGET_HARD_FLOAT |
4779 && ((TARGET_PPC_GFXOPT | 4899 && ((TARGET_PPC_GFXOPT |
4780 && !HONOR_NANS (<MODE>mode) | 4900 && !HONOR_NANS (<MODE>mode) |
4781 && !HONOR_SIGNED_ZEROS (<MODE>mode)) | 4901 && !HONOR_SIGNED_ZEROS (<MODE>mode)) |
4782 || TARGET_CMPB | 4902 || TARGET_CMPB |
4783 || VECTOR_UNIT_VSX_P (<MODE>mode))" | 4903 || VECTOR_UNIT_VSX_P (<MODE>mode))" |
4791 | 4911 |
4792 operands[3] = gen_reg_rtx (<MODE>mode); | 4912 operands[3] = gen_reg_rtx (<MODE>mode); |
4793 operands[4] = gen_reg_rtx (<MODE>mode); | 4913 operands[4] = gen_reg_rtx (<MODE>mode); |
4794 operands[5] = CONST0_RTX (<MODE>mode); | 4914 operands[5] = CONST0_RTX (<MODE>mode); |
4795 }) | 4915 }) |
4796 | |
4797 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store | |
4798 ;; and load. | |
4799 (define_insn_and_split "signbit<mode>2_dm" | |
4800 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r") | |
4801 (unspec:SI | |
4802 [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")] | |
4803 UNSPEC_SIGNBIT))] | |
4804 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" | |
4805 "#" | |
4806 "&& reload_completed" | |
4807 [(const_int 0)] | |
4808 { | |
4809 rs6000_split_signbit (operands[0], operands[1]); | |
4810 DONE; | |
4811 } | |
4812 [(set_attr "length" "8,8,4") | |
4813 (set_attr "type" "mftgpr,load,integer")]) | |
4814 | |
4815 (define_insn_and_split "*signbit<mode>2_dm_<su>ext" | |
4816 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r") | |
4817 (any_extend:DI | |
4818 (unspec:SI | |
4819 [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")] | |
4820 UNSPEC_SIGNBIT)))] | |
4821 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" | |
4822 "#" | |
4823 "&& reload_completed" | |
4824 [(const_int 0)] | |
4825 { | |
4826 rs6000_split_signbit (operands[0], operands[1]); | |
4827 DONE; | |
4828 } | |
4829 [(set_attr "length" "8,8,4") | |
4830 (set_attr "type" "mftgpr,load,integer")]) | |
4831 | |
4832 ;; TARGET_MODES_TIEABLE_P doesn't allow DImode to be tied with the various | |
4833 ;; floating point types, which makes normal SUBREG's problematical. Instead | |
4834 ;; use a special pattern to avoid using a normal movdi. | |
4835 (define_insn "signbit<mode>2_dm2" | |
4836 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") | |
4837 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa") | |
4838 (const_int 0)] | |
4839 UNSPEC_SIGNBIT))] | |
4840 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" | |
4841 "mfvsrd %0,%x1" | |
4842 [(set_attr "type" "mftgpr")]) | |
4843 | |
4844 | 4916 |
4845 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the | 4917 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the |
4846 ;; compiler from optimizing -0.0 | 4918 ;; compiler from optimizing -0.0 |
4847 (define_insn "copysign<mode>3_fcpsgn" | 4919 (define_insn "copysign<mode>3_fcpsgn" |
4848 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") | 4920 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") |
4849 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>") | 4921 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>") |
4850 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")] | 4922 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")] |
4851 UNSPEC_COPYSIGN))] | 4923 UNSPEC_COPYSIGN))] |
4852 "TARGET_<MODE>_FPR && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))" | 4924 "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))" |
4853 "@ | 4925 "@ |
4854 fcpsgn %0,%2,%1 | 4926 fcpsgn %0,%2,%1 |
4855 xscpsgndp %x0,%x2,%x1" | 4927 xscpsgndp %x0,%x2,%x1" |
4856 [(set_attr "type" "fpsimple")]) | 4928 [(set_attr "type" "fpsimple")]) |
4857 | 4929 |
4867 ;; | 4939 ;; |
4868 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector | 4940 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector |
4869 ;; to allow either DF/SF to use only traditional registers. | 4941 ;; to allow either DF/SF to use only traditional registers. |
4870 | 4942 |
4871 (define_expand "s<minmax><mode>3" | 4943 (define_expand "s<minmax><mode>3" |
4872 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") | 4944 [(set (match_operand:SFDF 0 "gpc_reg_operand") |
4873 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "") | 4945 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand") |
4874 (match_operand:SFDF 2 "gpc_reg_operand" "")))] | 4946 (match_operand:SFDF 2 "gpc_reg_operand")))] |
4875 "TARGET_MINMAX_<MODE>" | 4947 "TARGET_MINMAX" |
4876 { | 4948 { |
4877 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]); | 4949 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]); |
4878 DONE; | 4950 DONE; |
4879 }) | 4951 }) |
4880 | 4952 |
4881 (define_insn "*s<minmax><mode>3_vsx" | 4953 (define_insn "*s<minmax><mode>3_vsx" |
4882 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>") | 4954 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>") |
4883 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>") | 4955 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>") |
4884 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))] | 4956 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))] |
4885 "TARGET_VSX && TARGET_<MODE>_FPR" | 4957 "TARGET_VSX && TARGET_HARD_FLOAT" |
4886 { | 4958 { |
4887 return (TARGET_P9_MINMAX | 4959 return (TARGET_P9_MINMAX |
4888 ? "xs<minmax>cdp %x0,%x1,%x2" | 4960 ? "xs<minmax>cdp %x0,%x1,%x2" |
4889 : "xs<minmax>dp %x0,%x1,%x2"); | 4961 : "xs<minmax>dp %x0,%x1,%x2"); |
4890 } | 4962 } |
4893 ;; The conditional move instructions allow us to perform max and min operations | 4965 ;; The conditional move instructions allow us to perform max and min operations |
4894 ;; even when we don't have the appropriate max/min instruction using the FSEL | 4966 ;; even when we don't have the appropriate max/min instruction using the FSEL |
4895 ;; instruction. | 4967 ;; instruction. |
4896 | 4968 |
4897 (define_insn_and_split "*s<minmax><mode>3_fpr" | 4969 (define_insn_and_split "*s<minmax><mode>3_fpr" |
4898 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") | 4970 [(set (match_operand:SFDF 0 "gpc_reg_operand") |
4899 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "") | 4971 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand") |
4900 (match_operand:SFDF 2 "gpc_reg_operand" "")))] | 4972 (match_operand:SFDF 2 "gpc_reg_operand")))] |
4901 "!TARGET_VSX && TARGET_MINMAX_<MODE>" | 4973 "!TARGET_VSX && TARGET_MINMAX" |
4902 "#" | 4974 "#" |
4903 "&& 1" | 4975 "&& 1" |
4904 [(const_int 0)] | 4976 [(const_int 0)] |
4905 { | 4977 { |
4906 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]); | 4978 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]); |
4907 DONE; | 4979 DONE; |
4908 }) | 4980 }) |
4909 | 4981 |
4910 (define_expand "mov<mode>cc" | 4982 (define_expand "mov<mode>cc" |
4911 [(set (match_operand:GPR 0 "gpc_reg_operand" "") | 4983 [(set (match_operand:GPR 0 "gpc_reg_operand") |
4912 (if_then_else:GPR (match_operand 1 "comparison_operator" "") | 4984 (if_then_else:GPR (match_operand 1 "comparison_operator") |
4913 (match_operand:GPR 2 "gpc_reg_operand" "") | 4985 (match_operand:GPR 2 "gpc_reg_operand") |
4914 (match_operand:GPR 3 "gpc_reg_operand" "")))] | 4986 (match_operand:GPR 3 "gpc_reg_operand")))] |
4915 "TARGET_ISEL" | 4987 "TARGET_ISEL" |
4916 " | |
4917 { | 4988 { |
4918 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) | 4989 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) |
4919 DONE; | 4990 DONE; |
4920 else | 4991 else |
4921 FAIL; | 4992 FAIL; |
4922 }") | 4993 }) |
4923 | 4994 |
4924 ;; We use the BASE_REGS for the isel input operands because, if rA is | 4995 ;; We use the BASE_REGS for the isel input operands because, if rA is |
4925 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB | 4996 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB |
4926 ;; because we may switch the operands and rB may end up being rA. | 4997 ;; because we may switch the operands and rB may end up being rA. |
4927 ;; | 4998 ;; |
4987 } | 5058 } |
4988 [(set_attr "type" "isel")]) | 5059 [(set_attr "type" "isel")]) |
4989 | 5060 |
4990 ;; Floating point conditional move | 5061 ;; Floating point conditional move |
4991 (define_expand "mov<mode>cc" | 5062 (define_expand "mov<mode>cc" |
4992 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") | 5063 [(set (match_operand:SFDF 0 "gpc_reg_operand") |
4993 (if_then_else:SFDF (match_operand 1 "comparison_operator" "") | 5064 (if_then_else:SFDF (match_operand 1 "comparison_operator") |
4994 (match_operand:SFDF 2 "gpc_reg_operand" "") | 5065 (match_operand:SFDF 2 "gpc_reg_operand") |
4995 (match_operand:SFDF 3 "gpc_reg_operand" "")))] | 5066 (match_operand:SFDF 3 "gpc_reg_operand")))] |
4996 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT" | 5067 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT" |
4997 " | |
4998 { | 5068 { |
4999 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) | 5069 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) |
5000 DONE; | 5070 DONE; |
5001 else | 5071 else |
5002 FAIL; | 5072 FAIL; |
5003 }") | 5073 }) |
5004 | 5074 |
5005 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4" | 5075 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4" |
5006 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>") | 5076 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>") |
5007 (if_then_else:SFDF | 5077 (if_then_else:SFDF |
5008 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>") | 5078 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>") |
5009 (match_operand:SFDF2 4 "zero_fp_constant" "F")) | 5079 (match_operand:SFDF2 4 "zero_fp_constant" "F")) |
5010 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>") | 5080 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>") |
5011 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))] | 5081 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))] |
5012 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT" | 5082 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT" |
5013 "fsel %0,%1,%2,%3" | 5083 "fsel %0,%1,%2,%3" |
5014 [(set_attr "type" "fp")]) | 5084 [(set_attr "type" "fp")]) |
5015 | 5085 |
5016 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9" | 5086 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9" |
5017 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>") | 5087 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>") |
5110 ; don't want to support putting SImode in FPR registers. | 5180 ; don't want to support putting SImode in FPR registers. |
5111 (define_insn "lfiwax" | 5181 (define_insn "lfiwax" |
5112 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK") | 5182 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK") |
5113 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")] | 5183 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")] |
5114 UNSPEC_LFIWAX))] | 5184 UNSPEC_LFIWAX))] |
5115 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX" | 5185 "TARGET_HARD_FLOAT && TARGET_LFIWAX" |
5116 "@ | 5186 "@ |
5117 lfiwax %0,%y1 | 5187 lfiwax %0,%y1 |
5118 lxsiwax %x0,%y1 | 5188 lxsiwax %x0,%y1 |
5119 mtvsrwa %x0,%1 | 5189 mtvsrwa %x0,%1 |
5120 vextsw2d %0,%1" | 5190 vextsw2d %0,%1" |
5127 | 5197 |
5128 (define_insn_and_split "floatsi<mode>2_lfiwax" | 5198 (define_insn_and_split "floatsi<mode>2_lfiwax" |
5129 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") | 5199 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") |
5130 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r"))) | 5200 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r"))) |
5131 (clobber (match_scratch:DI 2 "=wi"))] | 5201 (clobber (match_scratch:DI 2 "=wi"))] |
5132 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX | 5202 "TARGET_HARD_FLOAT && TARGET_LFIWAX |
5133 && <SI_CONVERT_FP> && can_create_pseudo_p ()" | 5203 && <SI_CONVERT_FP> && can_create_pseudo_p ()" |
5134 "#" | 5204 "#" |
5135 "" | 5205 "" |
5136 [(pc)] | 5206 [(pc)] |
5137 " | |
5138 { | 5207 { |
5139 rtx dest = operands[0]; | 5208 rtx dest = operands[0]; |
5140 rtx src = operands[1]; | 5209 rtx src = operands[1]; |
5141 rtx tmp; | 5210 rtx tmp; |
5142 | 5211 |
5160 emit_insn (gen_lfiwax (tmp, stack)); | 5229 emit_insn (gen_lfiwax (tmp, stack)); |
5161 } | 5230 } |
5162 } | 5231 } |
5163 emit_insn (gen_floatdi<mode>2 (dest, tmp)); | 5232 emit_insn (gen_floatdi<mode>2 (dest, tmp)); |
5164 DONE; | 5233 DONE; |
5165 }" | 5234 } |
5166 [(set_attr "length" "12") | 5235 [(set_attr "length" "12") |
5167 (set_attr "type" "fpload")]) | 5236 (set_attr "type" "fpload")]) |
5168 | 5237 |
5169 (define_insn_and_split "floatsi<mode>2_lfiwax_mem" | 5238 (define_insn_and_split "floatsi<mode>2_lfiwax_mem" |
5170 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") | 5239 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") |
5171 (float:SFDF | 5240 (float:SFDF |
5172 (sign_extend:DI | 5241 (sign_extend:DI |
5173 (match_operand:SI 1 "indexed_or_indirect_operand" "Z")))) | 5242 (match_operand:SI 1 "indexed_or_indirect_operand" "Z")))) |
5174 (clobber (match_scratch:DI 2 "=wi"))] | 5243 (clobber (match_scratch:DI 2 "=wi"))] |
5175 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>" | 5244 "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>" |
5176 "#" | 5245 "#" |
5177 "" | 5246 "" |
5178 [(pc)] | 5247 [(pc)] |
5179 " | |
5180 { | 5248 { |
5181 operands[1] = rs6000_address_for_fpconvert (operands[1]); | 5249 operands[1] = rs6000_address_for_fpconvert (operands[1]); |
5182 if (GET_CODE (operands[2]) == SCRATCH) | 5250 if (GET_CODE (operands[2]) == SCRATCH) |
5183 operands[2] = gen_reg_rtx (DImode); | 5251 operands[2] = gen_reg_rtx (DImode); |
5184 if (TARGET_P8_VECTOR) | 5252 if (TARGET_P8_VECTOR) |
5185 emit_insn (gen_extendsidi2 (operands[2], operands[1])); | 5253 emit_insn (gen_extendsidi2 (operands[2], operands[1])); |
5186 else | 5254 else |
5187 emit_insn (gen_lfiwax (operands[2], operands[1])); | 5255 emit_insn (gen_lfiwax (operands[2], operands[1])); |
5188 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2])); | 5256 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2])); |
5189 DONE; | 5257 DONE; |
5190 }" | 5258 } |
5191 [(set_attr "length" "8") | 5259 [(set_attr "length" "8") |
5192 (set_attr "type" "fpload")]) | 5260 (set_attr "type" "fpload")]) |
5193 | 5261 |
5194 (define_insn "lfiwzx" | 5262 (define_insn "lfiwzx" |
5195 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK") | 5263 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK") |
5196 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")] | 5264 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")] |
5197 UNSPEC_LFIWZX))] | 5265 UNSPEC_LFIWZX))] |
5198 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX" | 5266 "TARGET_HARD_FLOAT && TARGET_LFIWZX" |
5199 "@ | 5267 "@ |
5200 lfiwzx %0,%y1 | 5268 lfiwzx %0,%y1 |
5201 lxsiwzx %x0,%y1 | 5269 lxsiwzx %x0,%y1 |
5202 mtvsrwz %x0,%1 | 5270 mtvsrwz %x0,%1 |
5203 xxextractuw %x0,%x1,4" | 5271 xxextractuw %x0,%x1,4" |
5205 | 5273 |
5206 (define_insn_and_split "floatunssi<mode>2_lfiwzx" | 5274 (define_insn_and_split "floatunssi<mode>2_lfiwzx" |
5207 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") | 5275 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") |
5208 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r"))) | 5276 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r"))) |
5209 (clobber (match_scratch:DI 2 "=wi"))] | 5277 (clobber (match_scratch:DI 2 "=wi"))] |
5210 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>" | 5278 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>" |
5211 "#" | 5279 "#" |
5212 "" | 5280 "" |
5213 [(pc)] | 5281 [(pc)] |
5214 " | |
5215 { | 5282 { |
5216 rtx dest = operands[0]; | 5283 rtx dest = operands[0]; |
5217 rtx src = operands[1]; | 5284 rtx src = operands[1]; |
5218 rtx tmp; | 5285 rtx tmp; |
5219 | 5286 |
5237 emit_insn (gen_lfiwzx (tmp, stack)); | 5304 emit_insn (gen_lfiwzx (tmp, stack)); |
5238 } | 5305 } |
5239 } | 5306 } |
5240 emit_insn (gen_floatdi<mode>2 (dest, tmp)); | 5307 emit_insn (gen_floatdi<mode>2 (dest, tmp)); |
5241 DONE; | 5308 DONE; |
5242 }" | 5309 } |
5243 [(set_attr "length" "12") | 5310 [(set_attr "length" "12") |
5244 (set_attr "type" "fpload")]) | 5311 (set_attr "type" "fpload")]) |
5245 | 5312 |
5246 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem" | 5313 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem" |
5247 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") | 5314 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") |
5248 (unsigned_float:SFDF | 5315 (unsigned_float:SFDF |
5249 (zero_extend:DI | 5316 (zero_extend:DI |
5250 (match_operand:SI 1 "indexed_or_indirect_operand" "Z")))) | 5317 (match_operand:SI 1 "indexed_or_indirect_operand" "Z")))) |
5251 (clobber (match_scratch:DI 2 "=wi"))] | 5318 (clobber (match_scratch:DI 2 "=wi"))] |
5252 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>" | 5319 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>" |
5253 "#" | 5320 "#" |
5254 "" | 5321 "" |
5255 [(pc)] | 5322 [(pc)] |
5256 " | |
5257 { | 5323 { |
5258 operands[1] = rs6000_address_for_fpconvert (operands[1]); | 5324 operands[1] = rs6000_address_for_fpconvert (operands[1]); |
5259 if (GET_CODE (operands[2]) == SCRATCH) | 5325 if (GET_CODE (operands[2]) == SCRATCH) |
5260 operands[2] = gen_reg_rtx (DImode); | 5326 operands[2] = gen_reg_rtx (DImode); |
5261 if (TARGET_P8_VECTOR) | 5327 if (TARGET_P8_VECTOR) |
5262 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1])); | 5328 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1])); |
5263 else | 5329 else |
5264 emit_insn (gen_lfiwzx (operands[2], operands[1])); | 5330 emit_insn (gen_lfiwzx (operands[2], operands[1])); |
5265 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2])); | 5331 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2])); |
5266 DONE; | 5332 DONE; |
5267 }" | 5333 } |
5268 [(set_attr "length" "8") | 5334 [(set_attr "length" "8") |
5269 (set_attr "type" "fpload")]) | 5335 (set_attr "type" "fpload")]) |
5270 | 5336 |
5271 ; For each of these conversions, there is a define_expand, a define_insn | 5337 ; For each of these conversions, there is a define_expand, a define_insn |
5272 ; with a '#' template, and a define_split (with C code). The idea is | 5338 ; with a '#' template, and a define_split (with C code). The idea is |
5273 ; to allow constant folding with the template of the define_insn, | 5339 ; to allow constant folding with the template of the define_insn, |
5274 ; then to have the insns split later (between sched1 and final). | 5340 ; then to have the insns split later (between sched1 and final). |
5275 | 5341 |
5276 (define_expand "floatsidf2" | 5342 (define_expand "floatsidf2" |
5277 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "") | 5343 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand") |
5278 (float:DF (match_operand:SI 1 "nonimmediate_operand" ""))) | 5344 (float:DF (match_operand:SI 1 "nonimmediate_operand"))) |
5279 (use (match_dup 2)) | 5345 (use (match_dup 2)) |
5280 (use (match_dup 3)) | 5346 (use (match_dup 3)) |
5281 (clobber (match_dup 4)) | 5347 (clobber (match_dup 4)) |
5282 (clobber (match_dup 5)) | 5348 (clobber (match_dup 5)) |
5283 (clobber (match_dup 6))])] | 5349 (clobber (match_dup 6))])] |
5284 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" | 5350 "TARGET_HARD_FLOAT" |
5285 " | |
5286 { | 5351 { |
5287 if (TARGET_LFIWAX && TARGET_FCFID) | 5352 if (TARGET_LFIWAX && TARGET_FCFID) |
5288 { | 5353 { |
5289 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1])); | 5354 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1])); |
5290 DONE; | 5355 DONE; |
5304 operands[2] = force_reg (SImode, GEN_INT (0x43300000)); | 5369 operands[2] = force_reg (SImode, GEN_INT (0x43300000)); |
5305 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode)); | 5370 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode)); |
5306 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false); | 5371 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false); |
5307 operands[5] = gen_reg_rtx (DFmode); | 5372 operands[5] = gen_reg_rtx (DFmode); |
5308 operands[6] = gen_reg_rtx (SImode); | 5373 operands[6] = gen_reg_rtx (SImode); |
5309 }") | 5374 }) |
5310 | 5375 |
5311 (define_insn_and_split "*floatsidf2_internal" | 5376 (define_insn_and_split "*floatsidf2_internal" |
5312 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d") | 5377 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d") |
5313 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) | 5378 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) |
5314 (use (match_operand:SI 2 "gpc_reg_operand" "r")) | 5379 (use (match_operand:SI 2 "gpc_reg_operand" "r")) |
5315 (use (match_operand:DF 3 "gpc_reg_operand" "d")) | 5380 (use (match_operand:DF 3 "gpc_reg_operand" "d")) |
5316 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) | 5381 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) |
5317 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d")) | 5382 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d")) |
5318 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))] | 5383 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))] |
5319 "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" | 5384 "!TARGET_FCFID && TARGET_HARD_FLOAT" |
5320 "#" | 5385 "#" |
5321 "" | 5386 "" |
5322 [(pc)] | 5387 [(pc)] |
5323 " | |
5324 { | 5388 { |
5325 rtx lowword, highword; | 5389 rtx lowword, highword; |
5326 gcc_assert (MEM_P (operands[4])); | 5390 gcc_assert (MEM_P (operands[4])); |
5327 highword = adjust_address (operands[4], SImode, 0); | 5391 highword = adjust_address (operands[4], SImode, 0); |
5328 lowword = adjust_address (operands[4], SImode, 4); | 5392 lowword = adjust_address (operands[4], SImode, 4); |
5334 emit_move_insn (lowword, operands[6]); | 5398 emit_move_insn (lowword, operands[6]); |
5335 emit_move_insn (highword, operands[2]); | 5399 emit_move_insn (highword, operands[2]); |
5336 emit_move_insn (operands[5], operands[4]); | 5400 emit_move_insn (operands[5], operands[4]); |
5337 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3])); | 5401 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3])); |
5338 DONE; | 5402 DONE; |
5339 }" | 5403 } |
5340 [(set_attr "length" "24") | 5404 [(set_attr "length" "24") |
5341 (set_attr "type" "fp")]) | 5405 (set_attr "type" "fp")]) |
5342 | 5406 |
5343 ;; If we don't have a direct conversion to single precision, don't enable this | 5407 ;; If we don't have a direct conversion to single precision, don't enable this |
5344 ;; conversion for 32-bit without fast math, because we don't have the insn to | 5408 ;; conversion for 32-bit without fast math, because we don't have the insn to |
5345 ;; generate the fixup swizzle to avoid double rounding problems. | 5409 ;; generate the fixup swizzle to avoid double rounding problems. |
5346 (define_expand "floatunssisf2" | 5410 (define_expand "floatunssisf2" |
5347 [(set (match_operand:SF 0 "gpc_reg_operand" "") | 5411 [(set (match_operand:SF 0 "gpc_reg_operand") |
5348 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))] | 5412 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))] |
5349 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT | 5413 "TARGET_HARD_FLOAT |
5350 && ((TARGET_FCFIDUS && TARGET_LFIWZX) | 5414 && ((TARGET_FCFIDUS && TARGET_LFIWZX) |
5351 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID | 5415 || (TARGET_FCFID |
5352 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))" | 5416 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))" |
5353 " | |
5354 { | 5417 { |
5355 if (TARGET_LFIWZX && TARGET_FCFIDUS) | 5418 if (TARGET_LFIWZX && TARGET_FCFIDUS) |
5356 { | 5419 { |
5357 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1])); | 5420 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1])); |
5358 DONE; | 5421 DONE; |
5364 dreg = force_reg (SImode, dreg); | 5427 dreg = force_reg (SImode, dreg); |
5365 dreg = convert_to_mode (DImode, dreg, true); | 5428 dreg = convert_to_mode (DImode, dreg, true); |
5366 emit_insn (gen_floatdisf2 (operands[0], dreg)); | 5429 emit_insn (gen_floatdisf2 (operands[0], dreg)); |
5367 DONE; | 5430 DONE; |
5368 } | 5431 } |
5369 }") | 5432 }) |
5370 | 5433 |
5371 (define_expand "floatunssidf2" | 5434 (define_expand "floatunssidf2" |
5372 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "") | 5435 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand") |
5373 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" ""))) | 5436 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand"))) |
5374 (use (match_dup 2)) | 5437 (use (match_dup 2)) |
5375 (use (match_dup 3)) | 5438 (use (match_dup 3)) |
5376 (clobber (match_dup 4)) | 5439 (clobber (match_dup 4)) |
5377 (clobber (match_dup 5))])] | 5440 (clobber (match_dup 5))])] |
5378 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" | 5441 "TARGET_HARD_FLOAT" |
5379 " | |
5380 { | 5442 { |
5381 if (TARGET_LFIWZX && TARGET_FCFID) | 5443 if (TARGET_LFIWZX && TARGET_FCFID) |
5382 { | 5444 { |
5383 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1])); | 5445 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1])); |
5384 DONE; | 5446 DONE; |
5397 operands[1] = force_reg (SImode, operands[1]); | 5459 operands[1] = force_reg (SImode, operands[1]); |
5398 operands[2] = force_reg (SImode, GEN_INT (0x43300000)); | 5460 operands[2] = force_reg (SImode, GEN_INT (0x43300000)); |
5399 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode)); | 5461 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode)); |
5400 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false); | 5462 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false); |
5401 operands[5] = gen_reg_rtx (DFmode); | 5463 operands[5] = gen_reg_rtx (DFmode); |
5402 }") | 5464 }) |
5403 | 5465 |
5404 (define_insn_and_split "*floatunssidf2_internal" | 5466 (define_insn_and_split "*floatunssidf2_internal" |
5405 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d") | 5467 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d") |
5406 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) | 5468 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) |
5407 (use (match_operand:SI 2 "gpc_reg_operand" "r")) | 5469 (use (match_operand:SI 2 "gpc_reg_operand" "r")) |
5408 (use (match_operand:DF 3 "gpc_reg_operand" "d")) | 5470 (use (match_operand:DF 3 "gpc_reg_operand" "d")) |
5409 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) | 5471 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) |
5410 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))] | 5472 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))] |
5411 "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT | 5473 "!TARGET_FCFIDU && TARGET_HARD_FLOAT |
5412 && !(TARGET_FCFID && TARGET_POWERPC64)" | 5474 && !(TARGET_FCFID && TARGET_POWERPC64)" |
5413 "#" | 5475 "#" |
5414 "" | 5476 "" |
5415 [(pc)] | 5477 [(pc)] |
5416 " | |
5417 { | 5478 { |
5418 rtx lowword, highword; | 5479 rtx lowword, highword; |
5419 gcc_assert (MEM_P (operands[4])); | 5480 gcc_assert (MEM_P (operands[4])); |
5420 highword = adjust_address (operands[4], SImode, 0); | 5481 highword = adjust_address (operands[4], SImode, 0); |
5421 lowword = adjust_address (operands[4], SImode, 4); | 5482 lowword = adjust_address (operands[4], SImode, 4); |
5425 emit_move_insn (lowword, operands[1]); | 5486 emit_move_insn (lowword, operands[1]); |
5426 emit_move_insn (highword, operands[2]); | 5487 emit_move_insn (highword, operands[2]); |
5427 emit_move_insn (operands[5], operands[4]); | 5488 emit_move_insn (operands[5], operands[4]); |
5428 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3])); | 5489 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3])); |
5429 DONE; | 5490 DONE; |
5430 }" | 5491 } |
5431 [(set_attr "length" "20") | 5492 [(set_attr "length" "20") |
5432 (set_attr "type" "fp")]) | 5493 (set_attr "type" "fp")]) |
5433 | 5494 |
5434 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to | 5495 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to |
5435 ;; vector registers. These insns favor doing the sign/zero extension in | 5496 ;; vector registers. These insns favor doing the sign/zero extension in |
5490 }) | 5551 }) |
5491 | 5552 |
5492 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2" | 5553 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2" |
5493 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand") | 5554 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand") |
5494 (unsigned_float:FP_ISA3 | 5555 (unsigned_float:FP_ISA3 |
5495 (match_operand:QHI 1 "input_operand" ""))) | 5556 (match_operand:QHI 1 "input_operand"))) |
5496 (clobber (match_scratch:DI 2 "")) | 5557 (clobber (match_scratch:DI 2)) |
5497 (clobber (match_scratch:DI 3 ""))])] | 5558 (clobber (match_scratch:DI 3))])] |
5498 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64" | 5559 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64" |
5499 { | 5560 { |
5500 if (MEM_P (operands[1])) | 5561 if (MEM_P (operands[1])) |
5501 operands[1] = rs6000_address_for_fpconvert (operands[1]); | 5562 operands[1] = rs6000_address_for_fpconvert (operands[1]); |
5502 }) | 5563 }) |
5533 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di)); | 5594 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di)); |
5534 DONE; | 5595 DONE; |
5535 }) | 5596 }) |
5536 | 5597 |
5537 (define_expand "fix_trunc<mode>si2" | 5598 (define_expand "fix_trunc<mode>si2" |
5538 [(set (match_operand:SI 0 "gpc_reg_operand" "") | 5599 [(set (match_operand:SI 0 "gpc_reg_operand") |
5539 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))] | 5600 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))] |
5540 "TARGET_HARD_FLOAT && <TARGET_FLOAT>" | 5601 "TARGET_HARD_FLOAT" |
5541 " | 5602 { |
5542 { | 5603 if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)) |
5543 if (!TARGET_P8_VECTOR) | |
5544 { | 5604 { |
5545 rtx src = force_reg (<MODE>mode, operands[1]); | 5605 rtx src = force_reg (<MODE>mode, operands[1]); |
5546 | 5606 |
5547 if (TARGET_STFIWX) | 5607 if (TARGET_STFIWX) |
5548 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src)); | 5608 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src)); |
5553 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src, | 5613 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src, |
5554 tmp, stack)); | 5614 tmp, stack)); |
5555 } | 5615 } |
5556 DONE; | 5616 DONE; |
5557 } | 5617 } |
5558 }") | 5618 }) |
5559 | 5619 |
5560 ; Like the convert to float patterns, this insn must be split before | 5620 ; Like the convert to float patterns, this insn must be split before |
5561 ; register allocation so that it can allocate the memory slot if it | 5621 ; register allocation so that it can allocate the memory slot if it |
5562 ; needed | 5622 ; needed |
5563 (define_insn_and_split "fix_trunc<mode>si2_stfiwx" | 5623 (define_insn_and_split "fix_trunc<mode>si2_stfiwx" |
5564 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") | 5624 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") |
5565 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))) | 5625 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))) |
5566 (clobber (match_scratch:DI 2 "=d"))] | 5626 (clobber (match_scratch:DI 2 "=d"))] |
5567 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT | 5627 "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p () |
5568 && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT) | 5628 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)" |
5569 && TARGET_STFIWX && can_create_pseudo_p () | |
5570 && !TARGET_P8_VECTOR" | |
5571 "#" | 5629 "#" |
5572 "" | 5630 "" |
5573 [(pc)] | 5631 [(pc)] |
5574 { | 5632 { |
5575 rtx dest = operands[0]; | 5633 rtx dest = operands[0]; |
5606 (define_insn_and_split "fix_trunc<mode>si2_internal" | 5664 (define_insn_and_split "fix_trunc<mode>si2_internal" |
5607 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r") | 5665 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r") |
5608 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>"))) | 5666 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>"))) |
5609 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d")) | 5667 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d")) |
5610 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))] | 5668 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))] |
5611 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_P8_VECTOR" | 5669 "TARGET_HARD_FLOAT |
5670 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)" | |
5612 "#" | 5671 "#" |
5613 "" | 5672 "" |
5614 [(pc)] | 5673 [(pc)] |
5615 " | |
5616 { | 5674 { |
5617 rtx lowword; | 5675 rtx lowword; |
5618 gcc_assert (MEM_P (operands[3])); | 5676 gcc_assert (MEM_P (operands[3])); |
5619 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0); | 5677 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0); |
5620 | 5678 |
5621 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1])); | 5679 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1])); |
5622 emit_move_insn (operands[3], operands[2]); | 5680 emit_move_insn (operands[3], operands[2]); |
5623 emit_move_insn (operands[0], lowword); | 5681 emit_move_insn (operands[0], lowword); |
5624 DONE; | 5682 DONE; |
5625 }" | 5683 } |
5626 [(set_attr "length" "16") | 5684 [(set_attr "length" "16") |
5627 (set_attr "type" "fp")]) | 5685 (set_attr "type" "fp")]) |
5628 | 5686 |
5629 (define_expand "fix_trunc<mode>di2" | 5687 (define_expand "fix_trunc<mode>di2" |
5630 [(set (match_operand:DI 0 "gpc_reg_operand" "") | 5688 [(set (match_operand:DI 0 "gpc_reg_operand") |
5631 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))] | 5689 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))] |
5632 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID" | 5690 "TARGET_HARD_FLOAT && TARGET_FCFID" |
5633 "") | 5691 "") |
5634 | 5692 |
5635 (define_insn "*fix_trunc<mode>di2_fctidz" | 5693 (define_insn "*fix_trunc<mode>di2_fctidz" |
5636 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi") | 5694 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi") |
5637 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] | 5695 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] |
5638 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID" | 5696 "TARGET_HARD_FLOAT && TARGET_FCFID" |
5639 "@ | 5697 "@ |
5640 fctidz %0,%1 | 5698 fctidz %0,%1 |
5641 xscvdpsxds %x0,%x1" | 5699 xscvdpsxds %x0,%x1" |
5642 [(set_attr "type" "fp")]) | 5700 [(set_attr "type" "fp")]) |
5643 | 5701 |
5644 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2" | 5702 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR |
5645 [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand") | 5703 ;; registers. If we have ISA 2.07, we don't allow QI/HImode values in the |
5646 (fix:QHI (match_operand:SFDF 1 "gpc_reg_operand"))) | 5704 ;; vector registers, so we need to do direct moves to the GPRs, but SImode |
5647 (clobber (match_scratch:DI 2))])] | 5705 ;; values can go in VSX registers. Keeping the direct move part through |
5648 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT" | 5706 ;; register allocation prevents the register allocator from doing a direct move |
5649 { | 5707 ;; of the SImode value to a GPR, and then a store/load. |
5650 if (MEM_P (operands[0])) | 5708 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2" |
5651 operands[0] = rs6000_address_for_fpconvert (operands[0]); | 5709 [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=wJ,wJwK,r") |
5652 }) | 5710 (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "wJ,wJwK,wa"))) |
5653 | 5711 (clobber (match_scratch:SI 2 "=X,X,wi"))] |
5654 (define_insn_and_split "*fix_trunc<SFDF:mode><QHI:mode>2_internal" | 5712 "TARGET_DIRECT_MOVE" |
5655 [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ") | 5713 "@ |
5656 (fix:QHI | 5714 fctiw<u>z %0,%1 |
5657 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>"))) | 5715 xscvdp<su>xws %x0,%x1 |
5658 (clobber (match_scratch:DI 2 "=X,wi"))] | 5716 #" |
5659 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT" | 5717 "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)" |
5660 "#" | 5718 [(set (match_dup 2) |
5661 "&& reload_completed" | 5719 (any_fix:SI (match_dup 1))) |
5662 [(const_int 0)] | 5720 (set (match_dup 3) |
5663 { | 5721 (match_dup 2))] |
5664 rtx dest = operands[0]; | 5722 { |
5665 rtx src = operands[1]; | 5723 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0])); |
5666 | |
5667 if (vsx_register_operand (dest, <QHI:MODE>mode)) | |
5668 { | |
5669 rtx di_dest = gen_rtx_REG (DImode, REGNO (dest)); | |
5670 emit_insn (gen_fix_trunc<SFDF:mode>di2 (di_dest, src)); | |
5671 } | |
5672 else | |
5673 { | |
5674 rtx tmp = operands[2]; | |
5675 rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp)); | |
5676 | |
5677 emit_insn (gen_fix_trunc<SFDF:mode>di2 (tmp, src)); | |
5678 emit_move_insn (dest, tmp2); | |
5679 } | |
5680 DONE; | |
5681 }) | |
5682 | |
5683 (define_expand "fixuns_trunc<mode>si2" | |
5684 [(set (match_operand:SI 0 "gpc_reg_operand" "") | |
5685 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))] | |
5686 "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX" | |
5687 " | |
5688 { | |
5689 if (!TARGET_P8_VECTOR) | |
5690 { | |
5691 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1])); | |
5692 DONE; | |
5693 } | |
5694 }") | |
5695 | |
5696 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx" | |
5697 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") | |
5698 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))) | |
5699 (clobber (match_scratch:DI 2 "=d"))] | |
5700 "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ | |
5701 && TARGET_STFIWX && can_create_pseudo_p () | |
5702 && !TARGET_P8_VECTOR" | |
5703 "#" | |
5704 "" | |
5705 [(pc)] | |
5706 { | |
5707 rtx dest = operands[0]; | |
5708 rtx src = operands[1]; | |
5709 rtx tmp = operands[2]; | |
5710 | |
5711 if (GET_CODE (tmp) == SCRATCH) | |
5712 tmp = gen_reg_rtx (DImode); | |
5713 | |
5714 emit_insn (gen_fctiwuz_<mode> (tmp, src)); | |
5715 if (MEM_P (dest)) | |
5716 { | |
5717 dest = rs6000_address_for_fpconvert (dest); | |
5718 emit_insn (gen_stfiwx (dest, tmp)); | |
5719 DONE; | |
5720 } | |
5721 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE)) | |
5722 { | |
5723 dest = gen_lowpart (DImode, dest); | |
5724 emit_move_insn (dest, tmp); | |
5725 DONE; | |
5726 } | |
5727 else | |
5728 { | |
5729 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); | |
5730 emit_insn (gen_stfiwx (stack, tmp)); | |
5731 emit_move_insn (dest, stack); | |
5732 DONE; | |
5733 } | |
5734 } | 5724 } |
5735 [(set_attr "length" "12") | 5725 [(set_attr "length" "4,4,8") |
5736 (set_attr "type" "fp")]) | 5726 (set_attr "type" "fp")]) |
5737 | 5727 |
5738 (define_insn "fixuns_trunc<mode>di2" | 5728 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8" |
5739 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi") | 5729 [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa") |
5740 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] | 5730 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))] |
5741 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCTIDUZ" | 5731 "TARGET_DIRECT_MOVE" |
5742 "@ | |
5743 fctiduz %0,%1 | |
5744 xscvdpuxds %x0,%x1" | |
5745 [(set_attr "type" "fp")]) | |
5746 | |
5747 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2" | |
5748 [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand") | |
5749 (unsigned_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand"))) | |
5750 (clobber (match_scratch:DI 2))])] | |
5751 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT" | |
5752 { | |
5753 if (MEM_P (operands[0])) | |
5754 operands[0] = rs6000_address_for_fpconvert (operands[0]); | |
5755 }) | |
5756 | |
5757 (define_insn_and_split "*fixuns_trunc<SFDF:mode><QHI:mode>2_internal" | |
5758 [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ") | |
5759 (unsigned_fix:QHI | |
5760 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>"))) | |
5761 (clobber (match_scratch:DI 2 "=X,wi"))] | |
5762 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT" | |
5763 "#" | |
5764 "&& reload_completed" | |
5765 [(const_int 0)] | |
5766 { | |
5767 rtx dest = operands[0]; | |
5768 rtx src = operands[1]; | |
5769 | |
5770 if (vsx_register_operand (dest, <QHI:MODE>mode)) | |
5771 { | |
5772 rtx di_dest = gen_rtx_REG (DImode, REGNO (dest)); | |
5773 emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (di_dest, src)); | |
5774 } | |
5775 else | |
5776 { | |
5777 rtx tmp = operands[2]; | |
5778 rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp)); | |
5779 | |
5780 emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (tmp, src)); | |
5781 emit_move_insn (dest, tmp2); | |
5782 } | |
5783 DONE; | |
5784 }) | |
5785 | |
5786 ;; If -mvsx-small-integer, we can represent the FIX operation directly. On | |
5787 ;; older machines, we have to use an UNSPEC to produce a SImode and move it | |
5788 ;; to another location, since SImode is not allowed in vector registers. | |
5789 (define_insn "*fctiw<u>z_<mode>_smallint" | |
5790 [(set (match_operand:SI 0 "vsx_register_operand" "=d,wi") | |
5791 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] | |
5792 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_P8_VECTOR" | |
5793 "@ | 5732 "@ |
5794 fctiw<u>z %0,%1 | 5733 fctiw<u>z %0,%1 |
5795 xscvdp<su>xws %x0,%x1" | 5734 xscvdp<su>xws %x0,%x1" |
5796 [(set_attr "type" "fp")]) | 5735 [(set_attr "type" "fp")]) |
5797 | 5736 |
5798 ;; Combiner pattern to prevent moving the result of converting a floating point | 5737 ;; Keep the convert and store together through register allocation to prevent |
5799 ;; value to 32-bit integer to GPR in order to save it. | 5738 ;; the register allocator from getting clever and doing a direct move to a GPR |
5800 (define_insn_and_split "*fctiw<u>z_<mode>_mem" | 5739 ;; and then store for reg+offset stores. |
5801 [(set (match_operand:SI 0 "memory_operand" "=Z") | 5740 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem" |
5802 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "wa"))) | 5741 [(set (match_operand:QHSI 0 "memory_operand" "=Z") |
5742 (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa"))) | |
5803 (clobber (match_scratch:SI 2 "=wa"))] | 5743 (clobber (match_scratch:SI 2 "=wa"))] |
5804 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_P8_VECTOR" | 5744 "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR" |
5805 "#" | 5745 "#" |
5806 "&& reload_completed" | 5746 "&& reload_completed" |
5807 [(set (match_dup 2) | 5747 [(set (match_dup 2) |
5808 (any_fix:SI (match_dup 1))) | 5748 (any_fix:SI (match_dup 1))) |
5809 (set (match_dup 0) | 5749 (set (match_dup 0) |
5810 (match_dup 2))]) | 5750 (match_dup 3))] |
5751 { | |
5752 operands[3] = (<QHSI:MODE>mode == SImode | |
5753 ? operands[2] | |
5754 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2]))); | |
5755 }) | |
5756 | |
5757 (define_expand "fixuns_trunc<mode>si2" | |
5758 [(set (match_operand:SI 0 "gpc_reg_operand") | |
5759 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))] | |
5760 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX" | |
5761 { | |
5762 if (!TARGET_P8_VECTOR) | |
5763 { | |
5764 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1])); | |
5765 DONE; | |
5766 } | |
5767 }) | |
5768 | |
5769 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx" | |
5770 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") | |
5771 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))) | |
5772 (clobber (match_scratch:DI 2 "=d"))] | |
5773 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ | |
5774 && TARGET_STFIWX && can_create_pseudo_p () | |
5775 && !TARGET_P8_VECTOR" | |
5776 "#" | |
5777 "" | |
5778 [(pc)] | |
5779 { | |
5780 rtx dest = operands[0]; | |
5781 rtx src = operands[1]; | |
5782 rtx tmp = operands[2]; | |
5783 | |
5784 if (GET_CODE (tmp) == SCRATCH) | |
5785 tmp = gen_reg_rtx (DImode); | |
5786 | |
5787 emit_insn (gen_fctiwuz_<mode> (tmp, src)); | |
5788 if (MEM_P (dest)) | |
5789 { | |
5790 dest = rs6000_address_for_fpconvert (dest); | |
5791 emit_insn (gen_stfiwx (dest, tmp)); | |
5792 DONE; | |
5793 } | |
5794 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE)) | |
5795 { | |
5796 dest = gen_lowpart (DImode, dest); | |
5797 emit_move_insn (dest, tmp); | |
5798 DONE; | |
5799 } | |
5800 else | |
5801 { | |
5802 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); | |
5803 emit_insn (gen_stfiwx (stack, tmp)); | |
5804 emit_move_insn (dest, stack); | |
5805 DONE; | |
5806 } | |
5807 } | |
5808 [(set_attr "length" "12") | |
5809 (set_attr "type" "fp")]) | |
5810 | |
5811 (define_insn "fixuns_trunc<mode>di2" | |
5812 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi") | |
5813 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] | |
5814 "TARGET_HARD_FLOAT && TARGET_FCTIDUZ" | |
5815 "@ | |
5816 fctiduz %0,%1 | |
5817 xscvdpuxds %x0,%x1" | |
5818 [(set_attr "type" "fp")]) | |
5819 | |
5820 (define_insn "rs6000_mtfsb0" | |
5821 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")] | |
5822 UNSPECV_MTFSB0)] | |
5823 "TARGET_HARD_FLOAT" | |
5824 "mtfsb0 %0" | |
5825 [(set_attr "type" "fp")]) | |
5826 | |
5827 (define_insn "rs6000_mtfsb1" | |
5828 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")] | |
5829 UNSPECV_MTFSB1)] | |
5830 "TARGET_HARD_FLOAT" | |
5831 "mtfsb1 %0" | |
5832 [(set_attr "type" "fp")]) | |
5833 | |
5834 (define_insn "rs6000_mffscrn" | |
5835 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") | |
5836 (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] | |
5837 UNSPECV_MFFSCRN))] | |
5838 "TARGET_P9_MISC" | |
5839 "mffscrn %0,%1" | |
5840 [(set_attr "type" "fp")]) | |
5841 | |
5842 (define_insn "rs6000_mffscdrn" | |
5843 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") | |
5844 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN)) | |
5845 (use (match_operand:DF 1 "gpc_reg_operand" "d"))] | |
5846 "TARGET_P9_MISC" | |
5847 "mffscdrn %0,%1" | |
5848 [(set_attr "type" "fp")]) | |
5849 | |
5850 (define_expand "rs6000_set_fpscr_rn" | |
5851 [(match_operand:DI 0 "reg_or_cint_operand")] | |
5852 "TARGET_HARD_FLOAT" | |
5853 { | |
5854 rtx tmp_df = gen_reg_rtx (DFmode); | |
5855 | |
5856 /* The floating point rounding control bits are FPSCR[62:63]. Put the | |
5857 new rounding mode bits from operands[0][62:63] into FPSCR[62:63]. */ | |
5858 if (TARGET_P9_MISC) | |
5859 { | |
5860 rtx src_df = force_reg (DImode, operands[0]); | |
5861 src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0); | |
5862 emit_insn (gen_rs6000_mffscrn (tmp_df, src_df)); | |
5863 DONE; | |
5864 } | |
5865 | |
5866 if (CONST_INT_P (operands[0])) | |
5867 { | |
5868 if ((INTVAL (operands[0]) & 0x1) == 0x1) | |
5869 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31))); | |
5870 else | |
5871 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31))); | |
5872 | |
5873 if ((INTVAL (operands[0]) & 0x2) == 0x2) | |
5874 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30))); | |
5875 else | |
5876 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30))); | |
5877 } | |
5878 else | |
5879 { | |
5880 rtx tmp_rn = gen_reg_rtx (DImode); | |
5881 rtx tmp_di = gen_reg_rtx (DImode); | |
5882 | |
5883 /* Extract new RN mode from operand. */ | |
5884 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3))); | |
5885 | |
5886 /* Insert new RN mode into FSCPR. */ | |
5887 emit_insn (gen_rs6000_mffs (tmp_df)); | |
5888 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0); | |
5889 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4))); | |
5890 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn)); | |
5891 | |
5892 /* Need to write to field k=15. The fields are [0:15]. Hence with | |
5893 L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W). FLM is an | |
5894 8-bit field[0:7]. Need to set the bit that corresponds to the | |
5895 value of i that you want [0:7]. */ | |
5896 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0); | |
5897 emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df)); | |
5898 } | |
5899 DONE; | |
5900 }) | |
5901 | |
5902 (define_expand "rs6000_set_fpscr_drn" | |
5903 [(match_operand:DI 0 "gpc_reg_operand")] | |
5904 "TARGET_HARD_FLOAT" | |
5905 { | |
5906 rtx tmp_df = gen_reg_rtx (DFmode); | |
5907 | |
5908 /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the | |
5909 new rounding mode bits from operands[0][61:63] into FPSCR[29:31]. */ | |
5910 if (TARGET_P9_MISC) | |
5911 { | |
5912 rtx src_df = gen_reg_rtx (DFmode); | |
5913 | |
5914 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32))); | |
5915 src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0); | |
5916 emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df)); | |
5917 } | |
5918 else | |
5919 { | |
5920 rtx tmp_rn = gen_reg_rtx (DImode); | |
5921 rtx tmp_di = gen_reg_rtx (DImode); | |
5922 | |
5923 /* Extract new DRN mode from operand. */ | |
5924 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7))); | |
5925 emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32))); | |
5926 | |
5927 /* Insert new RN mode into FSCPR. */ | |
5928 emit_insn (gen_rs6000_mffs (tmp_df)); | |
5929 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0); | |
5930 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFF))); | |
5931 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn)); | |
5932 | |
5933 /* Need to write to field 7. The fields are [0:15]. The equation to | |
5934 select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set | |
5935 i to 0x1 to get field 7 where i selects the field. */ | |
5936 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0); | |
5937 emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df)); | |
5938 } | |
5939 DONE; | |
5940 }) | |
5811 | 5941 |
5812 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ)) | 5942 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ)) |
5813 ;; rather than (set (subreg:SI (reg)) (fix:SI ...)) | 5943 ;; rather than (set (subreg:SI (reg)) (fix:SI ...)) |
5814 ;; because the first makes it clear that operand 0 is not live | 5944 ;; because the first makes it clear that operand 0 is not live |
5815 ;; before the instruction. | 5945 ;; before the instruction. |
5816 (define_insn "fctiwz_<mode>" | 5946 (define_insn "fctiwz_<mode>" |
5817 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi") | 5947 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi") |
5818 (unspec:DI [(fix:SI | 5948 (unspec:DI [(fix:SI |
5819 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))] | 5949 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))] |
5820 UNSPEC_FCTIWZ))] | 5950 UNSPEC_FCTIWZ))] |
5821 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" | 5951 "TARGET_HARD_FLOAT" |
5822 "@ | 5952 "@ |
5823 fctiwz %0,%1 | 5953 fctiwz %0,%1 |
5824 xscvdpsxws %x0,%x1" | 5954 xscvdpsxws %x0,%x1" |
5825 [(set_attr "type" "fp")]) | 5955 [(set_attr "type" "fp")]) |
5826 | 5956 |
5827 (define_insn "fctiwuz_<mode>" | 5957 (define_insn "fctiwuz_<mode>" |
5828 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi") | 5958 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi") |
5829 (unspec:DI [(unsigned_fix:SI | 5959 (unspec:DI [(unsigned_fix:SI |
5830 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))] | 5960 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))] |
5831 UNSPEC_FCTIWUZ))] | 5961 UNSPEC_FCTIWUZ))] |
5832 "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ" | 5962 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ" |
5833 "@ | 5963 "@ |
5834 fctiwuz %0,%1 | 5964 fctiwuz %0,%1 |
5835 xscvdpuxws %x0,%x1" | 5965 xscvdpuxws %x0,%x1" |
5836 [(set_attr "type" "fp")]) | 5966 [(set_attr "type" "fp")]) |
5837 | 5967 |
5839 ;; since the friz instruction does not truncate the value if the floating | 5969 ;; since the friz instruction does not truncate the value if the floating |
5840 ;; point value is < LONG_MIN or > LONG_MAX. | 5970 ;; point value is < LONG_MIN or > LONG_MAX. |
5841 (define_insn "*friz" | 5971 (define_insn "*friz" |
5842 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") | 5972 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") |
5843 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))] | 5973 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))] |
5844 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRND | 5974 "TARGET_HARD_FLOAT && TARGET_FPRND |
5845 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ" | 5975 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ" |
5846 "@ | 5976 "@ |
5847 friz %0,%1 | 5977 friz %0,%1 |
5848 xsrdpiz %x0,%x1" | 5978 xsrdpiz %x0,%x1" |
5849 [(set_attr "type" "fp")]) | 5979 [(set_attr "type" "fp")]) |
5858 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d") | 5988 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d") |
5859 (float:SFDF | 5989 (float:SFDF |
5860 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))) | 5990 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))) |
5861 (clobber (match_scratch:DI 2 "=d")) | 5991 (clobber (match_scratch:DI 2 "=d")) |
5862 (clobber (match_scratch:DI 3 "=d"))] | 5992 (clobber (match_scratch:DI 3 "=d"))] |
5863 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT | 5993 "TARGET_HARD_FLOAT |
5864 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID | 5994 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID |
5865 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()" | 5995 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()" |
5866 "#" | 5996 "#" |
5867 "" | 5997 "" |
5868 [(pc)] | 5998 [(pc)] |
5891 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d") | 6021 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d") |
5892 (unsigned_float:SFDF | 6022 (unsigned_float:SFDF |
5893 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))) | 6023 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))) |
5894 (clobber (match_scratch:DI 2 "=d")) | 6024 (clobber (match_scratch:DI 2 "=d")) |
5895 (clobber (match_scratch:DI 3 "=d"))] | 6025 (clobber (match_scratch:DI 3 "=d"))] |
5896 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT | 6026 "TARGET_HARD_FLOAT |
5897 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE | 6027 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE |
5898 && can_create_pseudo_p ()" | 6028 && can_create_pseudo_p ()" |
5899 "#" | 6029 "#" |
5900 "" | 6030 "" |
5901 [(pc)] | 6031 [(pc)] |
5918 DONE; | 6048 DONE; |
5919 } | 6049 } |
5920 [(set_attr "type" "fpload") | 6050 [(set_attr "type" "fpload") |
5921 (set_attr "length" "16")]) | 6051 (set_attr "length" "16")]) |
5922 | 6052 |
5923 (define_insn "lrintsfsi2" | |
5924 [(set (match_operand:SI 0 "gpc_reg_operand" "=d") | |
5925 (unspec:SI [(match_operand:DF 1 "gpc_reg_operand" "d")] | |
5926 UNSPEC_FCTIW))] | |
5927 "TARGET_SF_FPR && TARGET_FPRND" | |
5928 "fctiw %0,%1" | |
5929 [(set_attr "type" "fp")]) | |
5930 | |
5931 ;; No VSX equivalent to fctid | 6053 ;; No VSX equivalent to fctid |
5932 (define_insn "lrint<mode>di2" | 6054 (define_insn "lrint<mode>di2" |
5933 [(set (match_operand:DI 0 "gpc_reg_operand" "=d") | 6055 [(set (match_operand:DI 0 "gpc_reg_operand" "=d") |
5934 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")] | 6056 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")] |
5935 UNSPEC_FCTID))] | 6057 UNSPEC_FCTID))] |
5936 "TARGET_<MODE>_FPR && TARGET_FPRND" | 6058 "TARGET_HARD_FLOAT && TARGET_FPRND" |
5937 "fctid %0,%1" | 6059 "fctid %0,%1" |
5938 [(set_attr "type" "fp")]) | 6060 [(set_attr "type" "fp")]) |
5939 | 6061 |
5940 (define_insn "btrunc<mode>2" | 6062 (define_insn "btrunc<mode>2" |
5941 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") | 6063 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") |
5942 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] | 6064 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] |
5943 UNSPEC_FRIZ))] | 6065 UNSPEC_FRIZ))] |
5944 "TARGET_<MODE>_FPR && TARGET_FPRND" | 6066 "TARGET_HARD_FLOAT && TARGET_FPRND" |
5945 "@ | 6067 "@ |
5946 friz %0,%1 | 6068 friz %0,%1 |
5947 xsrdpiz %x0,%x1" | 6069 xsrdpiz %x0,%x1" |
5948 [(set_attr "type" "fp") | 6070 [(set_attr "type" "fp")]) |
5949 (set_attr "fp_type" "fp_addsub_<Fs>")]) | |
5950 | 6071 |
5951 (define_insn "ceil<mode>2" | 6072 (define_insn "ceil<mode>2" |
5952 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") | 6073 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") |
5953 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] | 6074 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] |
5954 UNSPEC_FRIP))] | 6075 UNSPEC_FRIP))] |
5955 "TARGET_<MODE>_FPR && TARGET_FPRND" | 6076 "TARGET_HARD_FLOAT && TARGET_FPRND" |
5956 "@ | 6077 "@ |
5957 frip %0,%1 | 6078 frip %0,%1 |
5958 xsrdpip %x0,%x1" | 6079 xsrdpip %x0,%x1" |
5959 [(set_attr "type" "fp") | 6080 [(set_attr "type" "fp")]) |
5960 (set_attr "fp_type" "fp_addsub_<Fs>")]) | |
5961 | 6081 |
5962 (define_insn "floor<mode>2" | 6082 (define_insn "floor<mode>2" |
5963 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") | 6083 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") |
5964 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] | 6084 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] |
5965 UNSPEC_FRIM))] | 6085 UNSPEC_FRIM))] |
5966 "TARGET_<MODE>_FPR && TARGET_FPRND" | 6086 "TARGET_HARD_FLOAT && TARGET_FPRND" |
5967 "@ | 6087 "@ |
5968 frim %0,%1 | 6088 frim %0,%1 |
5969 xsrdpim %x0,%x1" | 6089 xsrdpim %x0,%x1" |
5970 [(set_attr "type" "fp") | 6090 [(set_attr "type" "fp")]) |
5971 (set_attr "fp_type" "fp_addsub_<Fs>")]) | |
5972 | 6091 |
5973 ;; No VSX equivalent to frin | 6092 ;; No VSX equivalent to frin |
5974 (define_insn "round<mode>2" | 6093 (define_insn "round<mode>2" |
5975 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>") | 6094 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>") |
5976 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")] | 6095 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")] |
5977 UNSPEC_FRIN))] | 6096 UNSPEC_FRIN))] |
5978 "TARGET_<MODE>_FPR && TARGET_FPRND" | 6097 "TARGET_HARD_FLOAT && TARGET_FPRND" |
5979 "frin %0,%1" | 6098 "frin %0,%1" |
5980 [(set_attr "type" "fp") | 6099 [(set_attr "type" "fp")]) |
5981 (set_attr "fp_type" "fp_addsub_<Fs>")]) | |
5982 | 6100 |
5983 (define_insn "*xsrdpi<mode>2" | 6101 (define_insn "*xsrdpi<mode>2" |
5984 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") | 6102 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") |
5985 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")] | 6103 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")] |
5986 UNSPEC_XSRDPI))] | 6104 UNSPEC_XSRDPI))] |
5987 "TARGET_<MODE>_FPR && TARGET_VSX" | 6105 "TARGET_HARD_FLOAT && TARGET_VSX" |
5988 "xsrdpi %x0,%x1" | 6106 "xsrdpi %x0,%x1" |
5989 [(set_attr "type" "fp") | 6107 [(set_attr "type" "fp")]) |
5990 (set_attr "fp_type" "fp_addsub_<Fs>")]) | |
5991 | 6108 |
5992 (define_expand "lround<mode>di2" | 6109 (define_expand "lround<mode>di2" |
5993 [(set (match_dup 2) | 6110 [(set (match_dup 2) |
5994 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")] | 6111 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")] |
5995 UNSPEC_XSRDPI)) | 6112 UNSPEC_XSRDPI)) |
5996 (set (match_operand:DI 0 "gpc_reg_operand" "") | 6113 (set (match_operand:DI 0 "gpc_reg_operand") |
5997 (unspec:DI [(match_dup 2)] | 6114 (unspec:DI [(match_dup 2)] |
5998 UNSPEC_FCTID))] | 6115 UNSPEC_FCTID))] |
5999 "TARGET_<MODE>_FPR && TARGET_VSX" | 6116 "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND" |
6000 { | 6117 { |
6001 operands[2] = gen_reg_rtx (<MODE>mode); | 6118 operands[2] = gen_reg_rtx (<MODE>mode); |
6002 }) | 6119 }) |
6003 | 6120 |
6004 ; An UNSPEC is used so we don't have to support SImode in FP registers. | 6121 ; An UNSPEC is used so we don't have to support SImode in FP registers. |
6016 | 6133 |
6017 ;; If we don't have a direct conversion to single precision, don't enable this | 6134 ;; If we don't have a direct conversion to single precision, don't enable this |
6018 ;; conversion for 32-bit without fast math, because we don't have the insn to | 6135 ;; conversion for 32-bit without fast math, because we don't have the insn to |
6019 ;; generate the fixup swizzle to avoid double rounding problems. | 6136 ;; generate the fixup swizzle to avoid double rounding problems. |
6020 (define_expand "floatsisf2" | 6137 (define_expand "floatsisf2" |
6021 [(set (match_operand:SF 0 "gpc_reg_operand" "") | 6138 [(set (match_operand:SF 0 "gpc_reg_operand") |
6022 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))] | 6139 (float:SF (match_operand:SI 1 "nonimmediate_operand")))] |
6023 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT | 6140 "TARGET_HARD_FLOAT |
6024 && ((TARGET_FCFIDS && TARGET_LFIWAX) | 6141 && ((TARGET_FCFIDS && TARGET_LFIWAX) |
6025 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID | 6142 || (TARGET_FCFID |
6026 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))" | 6143 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))" |
6027 " | |
6028 { | 6144 { |
6029 if (TARGET_FCFIDS && TARGET_LFIWAX) | 6145 if (TARGET_FCFIDS && TARGET_LFIWAX) |
6030 { | 6146 { |
6031 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1])); | 6147 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1])); |
6032 DONE; | 6148 DONE; |
6045 dreg = force_reg (SImode, dreg); | 6161 dreg = force_reg (SImode, dreg); |
6046 dreg = convert_to_mode (DImode, dreg, false); | 6162 dreg = convert_to_mode (DImode, dreg, false); |
6047 emit_insn (gen_floatdisf2 (operands[0], dreg)); | 6163 emit_insn (gen_floatdisf2 (operands[0], dreg)); |
6048 DONE; | 6164 DONE; |
6049 } | 6165 } |
6050 }") | 6166 }) |
6051 | 6167 |
6052 (define_insn "floatdidf2" | 6168 (define_insn "floatdidf2" |
6053 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") | 6169 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") |
6054 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))] | 6170 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))] |
6055 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" | 6171 "TARGET_FCFID && TARGET_HARD_FLOAT" |
6056 "@ | 6172 "@ |
6057 fcfid %0,%1 | 6173 fcfid %0,%1 |
6058 xscvsxddp %x0,%x1" | 6174 xscvsxddp %x0,%x1" |
6059 [(set_attr "type" "fp")]) | 6175 [(set_attr "type" "fp")]) |
6060 | 6176 |
6065 | 6181 |
6066 (define_insn_and_split "*floatdidf2_mem" | 6182 (define_insn_and_split "*floatdidf2_mem" |
6067 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") | 6183 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") |
6068 (float:DF (match_operand:DI 1 "memory_operand" "m,Z"))) | 6184 (float:DF (match_operand:DI 1 "memory_operand" "m,Z"))) |
6069 (clobber (match_scratch:DI 2 "=d,wi"))] | 6185 (clobber (match_scratch:DI 2 "=d,wi"))] |
6070 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID" | 6186 "TARGET_HARD_FLOAT && TARGET_FCFID" |
6071 "#" | 6187 "#" |
6072 "&& reload_completed" | 6188 "&& reload_completed" |
6073 [(set (match_dup 2) (match_dup 1)) | 6189 [(set (match_dup 2) (match_dup 1)) |
6074 (set (match_dup 0) (float:DF (match_dup 2)))] | 6190 (set (match_dup 0) (float:DF (match_dup 2)))] |
6075 "" | 6191 "" |
6076 [(set_attr "length" "8") | 6192 [(set_attr "length" "8") |
6077 (set_attr "type" "fpload")]) | 6193 (set_attr "type" "fpload")]) |
6078 | 6194 |
6079 (define_expand "floatunsdidf2" | 6195 (define_expand "floatunsdidf2" |
6080 [(set (match_operand:DF 0 "gpc_reg_operand" "") | 6196 [(set (match_operand:DF 0 "gpc_reg_operand") |
6081 (unsigned_float:DF | 6197 (unsigned_float:DF |
6082 (match_operand:DI 1 "gpc_reg_operand" "")))] | 6198 (match_operand:DI 1 "gpc_reg_operand")))] |
6083 "TARGET_HARD_FLOAT && TARGET_FCFIDU" | 6199 "TARGET_HARD_FLOAT && TARGET_FCFIDU" |
6084 "") | 6200 "") |
6085 | 6201 |
6086 (define_insn "*floatunsdidf2_fcfidu" | 6202 (define_insn "*floatunsdidf2_fcfidu" |
6087 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") | 6203 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") |
6088 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))] | 6204 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))] |
6089 "TARGET_HARD_FLOAT && TARGET_FCFIDU" | 6205 "TARGET_HARD_FLOAT && TARGET_FCFIDU" |
6090 "@ | 6206 "@ |
6091 fcfidu %0,%1 | 6207 fcfidu %0,%1 |
6092 xscvuxddp %x0,%x1" | 6208 xscvuxddp %x0,%x1" |
6093 [(set_attr "type" "fp") | 6209 [(set_attr "type" "fp")]) |
6094 (set_attr "length" "4")]) | |
6095 | 6210 |
6096 (define_insn_and_split "*floatunsdidf2_mem" | 6211 (define_insn_and_split "*floatunsdidf2_mem" |
6097 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") | 6212 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") |
6098 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z"))) | 6213 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z"))) |
6099 (clobber (match_scratch:DI 2 "=d,wi"))] | 6214 (clobber (match_scratch:DI 2 "=d,wi"))] |
6105 "" | 6220 "" |
6106 [(set_attr "length" "8") | 6221 [(set_attr "length" "8") |
6107 (set_attr "type" "fpload")]) | 6222 (set_attr "type" "fpload")]) |
6108 | 6223 |
6109 (define_expand "floatdisf2" | 6224 (define_expand "floatdisf2" |
6110 [(set (match_operand:SF 0 "gpc_reg_operand" "") | 6225 [(set (match_operand:SF 0 "gpc_reg_operand") |
6111 (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))] | 6226 (float:SF (match_operand:DI 1 "gpc_reg_operand")))] |
6112 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT | 6227 "TARGET_FCFID && TARGET_HARD_FLOAT |
6113 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)" | 6228 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)" |
6114 " | |
6115 { | 6229 { |
6116 if (!TARGET_FCFIDS) | 6230 if (!TARGET_FCFIDS) |
6117 { | 6231 { |
6118 rtx val = operands[1]; | 6232 rtx val = operands[1]; |
6119 if (!flag_unsafe_math_optimizations) | 6233 if (!flag_unsafe_math_optimizations) |
6124 emit_label (label); | 6238 emit_label (label); |
6125 } | 6239 } |
6126 emit_insn (gen_floatdisf2_internal1 (operands[0], val)); | 6240 emit_insn (gen_floatdisf2_internal1 (operands[0], val)); |
6127 DONE; | 6241 DONE; |
6128 } | 6242 } |
6129 }") | 6243 }) |
6130 | 6244 |
6131 (define_insn "floatdisf2_fcfids" | 6245 (define_insn "floatdisf2_fcfids" |
6132 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy") | 6246 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy") |
6133 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))] | 6247 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))] |
6134 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT | 6248 "TARGET_HARD_FLOAT && TARGET_FCFIDS" |
6135 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS" | |
6136 "@ | 6249 "@ |
6137 fcfids %0,%1 | 6250 fcfids %0,%1 |
6138 xscvsxdsp %x0,%x1" | 6251 xscvsxdsp %x0,%x1" |
6139 [(set_attr "type" "fp")]) | 6252 [(set_attr "type" "fp")]) |
6140 | 6253 |
6141 (define_insn_and_split "*floatdisf2_mem" | 6254 (define_insn_and_split "*floatdisf2_mem" |
6142 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy") | 6255 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy") |
6143 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z"))) | 6256 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z"))) |
6144 (clobber (match_scratch:DI 2 "=d,d,wi"))] | 6257 (clobber (match_scratch:DI 2 "=d,d,wi"))] |
6145 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT | 6258 "TARGET_HARD_FLOAT && TARGET_FCFIDS" |
6146 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS" | |
6147 "#" | 6259 "#" |
6148 "&& reload_completed" | 6260 "&& reload_completed" |
6149 [(pc)] | 6261 [(pc)] |
6150 " | |
6151 { | 6262 { |
6152 emit_move_insn (operands[2], operands[1]); | 6263 emit_move_insn (operands[2], operands[1]); |
6153 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2])); | 6264 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2])); |
6154 DONE; | 6265 DONE; |
6155 }" | 6266 } |
6156 [(set_attr "length" "8")]) | 6267 [(set_attr "length" "8")]) |
6157 | 6268 |
6158 ;; This is not IEEE compliant if rounding mode is "round to nearest". | 6269 ;; This is not IEEE compliant if rounding mode is "round to nearest". |
6159 ;; If the DI->DF conversion is inexact, then it's possible to suffer | 6270 ;; If the DI->DF conversion is inexact, then it's possible to suffer |
6160 ;; from double rounding. | 6271 ;; from double rounding. |
6161 ;; Instead of creating a new cpu type for two FP operations, just use fp | 6272 ;; Instead of creating a new cpu type for two FP operations, just use fp |
6162 (define_insn_and_split "floatdisf2_internal1" | 6273 (define_insn_and_split "floatdisf2_internal1" |
6163 [(set (match_operand:SF 0 "gpc_reg_operand" "=f") | 6274 [(set (match_operand:SF 0 "gpc_reg_operand" "=f") |
6164 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d"))) | 6275 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d"))) |
6165 (clobber (match_scratch:DF 2 "=d"))] | 6276 (clobber (match_scratch:DF 2 "=d"))] |
6166 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && !TARGET_FCFIDS" | 6277 "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS" |
6167 "#" | 6278 "#" |
6168 "&& reload_completed" | 6279 "&& reload_completed" |
6169 [(set (match_dup 2) | 6280 [(set (match_dup 2) |
6170 (float:DF (match_dup 1))) | 6281 (float:DF (match_dup 1))) |
6171 (set (match_dup 0) | 6282 (set (match_dup 0) |
6177 ;; Twiddles bits to avoid double rounding. | 6288 ;; Twiddles bits to avoid double rounding. |
6178 ;; Bits that might be truncated when converting to DFmode are replaced | 6289 ;; Bits that might be truncated when converting to DFmode are replaced |
6179 ;; by a bit that won't be lost at that stage, but is below the SFmode | 6290 ;; by a bit that won't be lost at that stage, but is below the SFmode |
6180 ;; rounding position. | 6291 ;; rounding position. |
6181 (define_expand "floatdisf2_internal2" | 6292 (define_expand "floatdisf2_internal2" |
6182 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "") | 6293 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "") |
6183 (const_int 53))) | 6294 (const_int 53))) |
6184 (clobber (reg:DI CA_REGNO))]) | 6295 (clobber (reg:DI CA_REGNO))]) |
6185 (set (match_operand:DI 0 "" "") (and:DI (match_dup 1) | 6296 (set (match_operand:DI 0 "") (and:DI (match_dup 1) |
6186 (const_int 2047))) | 6297 (const_int 2047))) |
6187 (set (match_dup 3) (plus:DI (match_dup 3) | 6298 (set (match_dup 3) (plus:DI (match_dup 3) |
6188 (const_int 1))) | 6299 (const_int 1))) |
6189 (set (match_dup 0) (plus:DI (match_dup 0) | 6300 (set (match_dup 0) (plus:DI (match_dup 0) |
6190 (const_int 2047))) | 6301 (const_int 2047))) |
6191 (set (match_dup 4) (compare:CCUNS (match_dup 3) | 6302 (set (match_dup 4) (compare:CCUNS (match_dup 3) |
6193 (set (match_dup 0) (ior:DI (match_dup 0) | 6304 (set (match_dup 0) (ior:DI (match_dup 0) |
6194 (match_dup 1))) | 6305 (match_dup 1))) |
6195 (set (match_dup 0) (and:DI (match_dup 0) | 6306 (set (match_dup 0) (and:DI (match_dup 0) |
6196 (const_int -2048))) | 6307 (const_int -2048))) |
6197 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0)) | 6308 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0)) |
6198 (label_ref (match_operand:DI 2 "" "")) | 6309 (label_ref (match_operand:DI 2 "")) |
6199 (pc))) | 6310 (pc))) |
6200 (set (match_dup 0) (match_dup 1))] | 6311 (set (match_dup 0) (match_dup 1))] |
6201 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT | 6312 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS" |
6202 && !TARGET_FCFIDS" | |
6203 " | |
6204 { | 6313 { |
6205 operands[3] = gen_reg_rtx (DImode); | 6314 operands[3] = gen_reg_rtx (DImode); |
6206 operands[4] = gen_reg_rtx (CCUNSmode); | 6315 operands[4] = gen_reg_rtx (CCUNSmode); |
6207 }") | 6316 }) |
6208 | 6317 |
6209 (define_expand "floatunsdisf2" | 6318 (define_expand "floatunsdisf2" |
6210 [(set (match_operand:SF 0 "gpc_reg_operand" "") | 6319 [(set (match_operand:SF 0 "gpc_reg_operand") |
6211 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))] | 6320 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))] |
6212 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT | 6321 "TARGET_HARD_FLOAT && TARGET_FCFIDUS" |
6213 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS" | |
6214 "") | 6322 "") |
6215 | 6323 |
6216 (define_insn "floatunsdisf2_fcfidus" | 6324 (define_insn "floatunsdisf2_fcfidus" |
6217 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu") | 6325 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu") |
6218 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))] | 6326 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))] |
6219 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT | 6327 "TARGET_HARD_FLOAT && TARGET_FCFIDUS" |
6220 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS" | |
6221 "@ | 6328 "@ |
6222 fcfidus %0,%1 | 6329 fcfidus %0,%1 |
6223 xscvuxdsp %x0,%x1" | 6330 xscvuxdsp %x0,%x1" |
6224 [(set_attr "type" "fp")]) | 6331 [(set_attr "type" "fp")]) |
6225 | 6332 |
6226 (define_insn_and_split "*floatunsdisf2_mem" | 6333 (define_insn_and_split "*floatunsdisf2_mem" |
6227 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy") | 6334 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy") |
6228 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z"))) | 6335 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z"))) |
6229 (clobber (match_scratch:DI 2 "=d,d,wi"))] | 6336 (clobber (match_scratch:DI 2 "=d,d,wi"))] |
6230 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT | 6337 "TARGET_HARD_FLOAT && TARGET_FCFIDUS" |
6231 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS" | |
6232 "#" | 6338 "#" |
6233 "&& reload_completed" | 6339 "&& reload_completed" |
6234 [(pc)] | 6340 [(pc)] |
6235 " | |
6236 { | 6341 { |
6237 emit_move_insn (operands[2], operands[1]); | 6342 emit_move_insn (operands[2], operands[1]); |
6238 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2])); | 6343 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2])); |
6239 DONE; | 6344 DONE; |
6240 }" | 6345 } |
6241 [(set_attr "length" "8") | 6346 [(set_attr "length" "8") |
6242 (set_attr "type" "fpload")]) | 6347 (set_attr "type" "fpload")]) |
6243 | 6348 |
6244 ;; Define the TImode operations that can be done in a small number | 6349 ;; Define the TImode operations that can be done in a small number |
6245 ;; of instructions. The & constraints are to prevent the register | 6350 ;; of instructions. The & constraints are to prevent the register |
6246 ;; allocator from allocating registers that overlap with the inputs | 6351 ;; allocator from allocating registers that overlap with the inputs |
6247 ;; (for example, having an input in 7,8 and an output in 6,7). We | 6352 ;; (for example, having an input in 7,8 and an output in 6,7). We |
6248 ;; also allow for the output being the same as one of the inputs. | 6353 ;; also allow for the output being the same as one of the inputs. |
6249 | 6354 |
6250 (define_expand "addti3" | 6355 (define_expand "addti3" |
6251 [(set (match_operand:TI 0 "gpc_reg_operand" "") | 6356 [(set (match_operand:TI 0 "gpc_reg_operand") |
6252 (plus:TI (match_operand:TI 1 "gpc_reg_operand" "") | 6357 (plus:TI (match_operand:TI 1 "gpc_reg_operand") |
6253 (match_operand:TI 2 "reg_or_short_operand" "")))] | 6358 (match_operand:TI 2 "reg_or_short_operand")))] |
6254 "TARGET_64BIT" | 6359 "TARGET_64BIT" |
6255 { | 6360 { |
6256 rtx lo0 = gen_lowpart (DImode, operands[0]); | 6361 rtx lo0 = gen_lowpart (DImode, operands[0]); |
6257 rtx lo1 = gen_lowpart (DImode, operands[1]); | 6362 rtx lo1 = gen_lowpart (DImode, operands[1]); |
6258 rtx lo2 = gen_lowpart (DImode, operands[2]); | 6363 rtx lo2 = gen_lowpart (DImode, operands[2]); |
6269 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2)); | 6374 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2)); |
6270 DONE; | 6375 DONE; |
6271 }) | 6376 }) |
6272 | 6377 |
6273 (define_expand "subti3" | 6378 (define_expand "subti3" |
6274 [(set (match_operand:TI 0 "gpc_reg_operand" "") | 6379 [(set (match_operand:TI 0 "gpc_reg_operand") |
6275 (minus:TI (match_operand:TI 1 "reg_or_short_operand" "") | 6380 (minus:TI (match_operand:TI 1 "reg_or_short_operand") |
6276 (match_operand:TI 2 "gpc_reg_operand" "")))] | 6381 (match_operand:TI 2 "gpc_reg_operand")))] |
6277 "TARGET_64BIT" | 6382 "TARGET_64BIT" |
6278 { | 6383 { |
6279 rtx lo0 = gen_lowpart (DImode, operands[0]); | 6384 rtx lo0 = gen_lowpart (DImode, operands[0]); |
6280 rtx lo1 = gen_lowpart (DImode, operands[1]); | 6385 rtx lo1 = gen_lowpart (DImode, operands[1]); |
6281 rtx lo2 = gen_lowpart (DImode, operands[2]); | 6386 rtx lo2 = gen_lowpart (DImode, operands[2]); |
6294 }) | 6399 }) |
6295 | 6400 |
6296 ;; 128-bit logical operations expanders | 6401 ;; 128-bit logical operations expanders |
6297 | 6402 |
6298 (define_expand "and<mode>3" | 6403 (define_expand "and<mode>3" |
6299 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") | 6404 [(set (match_operand:BOOL_128 0 "vlogical_operand") |
6300 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "") | 6405 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand") |
6301 (match_operand:BOOL_128 2 "vlogical_operand" "")))] | 6406 (match_operand:BOOL_128 2 "vlogical_operand")))] |
6302 "" | 6407 "" |
6303 "") | 6408 "") |
6304 | 6409 |
6305 (define_expand "ior<mode>3" | 6410 (define_expand "ior<mode>3" |
6306 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") | 6411 [(set (match_operand:BOOL_128 0 "vlogical_operand") |
6307 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "") | 6412 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand") |
6308 (match_operand:BOOL_128 2 "vlogical_operand" "")))] | 6413 (match_operand:BOOL_128 2 "vlogical_operand")))] |
6309 "" | 6414 "" |
6310 "") | 6415 "") |
6311 | 6416 |
6312 (define_expand "xor<mode>3" | 6417 (define_expand "xor<mode>3" |
6313 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") | 6418 [(set (match_operand:BOOL_128 0 "vlogical_operand") |
6314 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "") | 6419 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand") |
6315 (match_operand:BOOL_128 2 "vlogical_operand" "")))] | 6420 (match_operand:BOOL_128 2 "vlogical_operand")))] |
6316 "" | 6421 "" |
6317 "") | 6422 "") |
6318 | 6423 |
6319 (define_expand "one_cmpl<mode>2" | 6424 (define_expand "one_cmpl<mode>2" |
6320 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") | 6425 [(set (match_operand:BOOL_128 0 "vlogical_operand") |
6321 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))] | 6426 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")))] |
6322 "" | 6427 "" |
6323 "") | 6428 "") |
6324 | 6429 |
6325 (define_expand "nor<mode>3" | 6430 (define_expand "nor<mode>3" |
6326 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") | 6431 [(set (match_operand:BOOL_128 0 "vlogical_operand") |
6327 (and:BOOL_128 | 6432 (and:BOOL_128 |
6328 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")) | 6433 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")) |
6329 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))] | 6434 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))] |
6330 "" | 6435 "" |
6331 "") | 6436 "") |
6332 | 6437 |
6333 (define_expand "andc<mode>3" | 6438 (define_expand "andc<mode>3" |
6334 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") | 6439 [(set (match_operand:BOOL_128 0 "vlogical_operand") |
6335 (and:BOOL_128 | 6440 (and:BOOL_128 |
6336 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" "")) | 6441 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand")) |
6337 (match_operand:BOOL_128 1 "vlogical_operand" "")))] | 6442 (match_operand:BOOL_128 1 "vlogical_operand")))] |
6338 "" | 6443 "" |
6339 "") | 6444 "") |
6340 | 6445 |
6341 ;; Power8 vector logical instructions. | 6446 ;; Power8 vector logical instructions. |
6342 (define_expand "eqv<mode>3" | 6447 (define_expand "eqv<mode>3" |
6343 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") | 6448 [(set (match_operand:BOOL_128 0 "vlogical_operand") |
6344 (not:BOOL_128 | 6449 (not:BOOL_128 |
6345 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "") | 6450 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand") |
6346 (match_operand:BOOL_128 2 "vlogical_operand" ""))))] | 6451 (match_operand:BOOL_128 2 "vlogical_operand"))))] |
6347 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR" | 6452 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR" |
6348 "") | 6453 "") |
6349 | 6454 |
6350 ;; Rewrite nand into canonical form | 6455 ;; Rewrite nand into canonical form |
6351 (define_expand "nand<mode>3" | 6456 (define_expand "nand<mode>3" |
6352 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") | 6457 [(set (match_operand:BOOL_128 0 "vlogical_operand") |
6353 (ior:BOOL_128 | 6458 (ior:BOOL_128 |
6354 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")) | 6459 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")) |
6355 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))] | 6460 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))] |
6356 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR" | 6461 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR" |
6357 "") | 6462 "") |
6358 | 6463 |
6359 ;; The canonical form is to have the negated element first, so we need to | 6464 ;; The canonical form is to have the negated element first, so we need to |
6360 ;; reverse arguments. | 6465 ;; reverse arguments. |
6361 (define_expand "orc<mode>3" | 6466 (define_expand "orc<mode>3" |
6362 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") | 6467 [(set (match_operand:BOOL_128 0 "vlogical_operand") |
6363 (ior:BOOL_128 | 6468 (ior:BOOL_128 |
6364 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" "")) | 6469 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand")) |
6365 (match_operand:BOOL_128 1 "vlogical_operand" "")))] | 6470 (match_operand:BOOL_128 1 "vlogical_operand")))] |
6366 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR" | 6471 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR" |
6367 "") | 6472 "") |
6368 | 6473 |
6369 ;; 128-bit logical operations insns and split operations | 6474 ;; 128-bit logical operations insns and split operations |
6370 (define_insn_and_split "*and<mode>3_internal" | 6475 (define_insn_and_split "*and<mode>3_internal" |
6654 ;; Now define ways of moving data around. | 6759 ;; Now define ways of moving data around. |
6655 | 6760 |
6656 ;; Set up a register with a value from the GOT table | 6761 ;; Set up a register with a value from the GOT table |
6657 | 6762 |
6658 (define_expand "movsi_got" | 6763 (define_expand "movsi_got" |
6659 [(set (match_operand:SI 0 "gpc_reg_operand" "") | 6764 [(set (match_operand:SI 0 "gpc_reg_operand") |
6660 (unspec:SI [(match_operand:SI 1 "got_operand" "") | 6765 (unspec:SI [(match_operand:SI 1 "got_operand") |
6661 (match_dup 2)] UNSPEC_MOVSI_GOT))] | 6766 (match_dup 2)] UNSPEC_MOVSI_GOT))] |
6662 "DEFAULT_ABI == ABI_V4 && flag_pic == 1" | 6767 "DEFAULT_ABI == ABI_V4 && flag_pic == 1" |
6663 " | |
6664 { | 6768 { |
6665 if (GET_CODE (operands[1]) == CONST) | 6769 if (GET_CODE (operands[1]) == CONST) |
6666 { | 6770 { |
6667 rtx offset = const0_rtx; | 6771 rtx offset = const0_rtx; |
6668 HOST_WIDE_INT value; | 6772 HOST_WIDE_INT value; |
6679 DONE; | 6783 DONE; |
6680 } | 6784 } |
6681 } | 6785 } |
6682 | 6786 |
6683 operands[2] = rs6000_got_register (operands[1]); | 6787 operands[2] = rs6000_got_register (operands[1]); |
6684 }") | 6788 }) |
6685 | 6789 |
6686 (define_insn "*movsi_got_internal" | 6790 (define_insn "*movsi_got_internal" |
6687 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") | 6791 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") |
6688 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "") | 6792 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "") |
6689 (match_operand:SI 2 "gpc_reg_operand" "b")] | 6793 (match_operand:SI 2 "gpc_reg_operand" "b")] |
6693 [(set_attr "type" "load")]) | 6797 [(set_attr "type" "load")]) |
6694 | 6798 |
6695 ;; Used by sched, shorten_branches and final when the GOT pseudo reg | 6799 ;; Used by sched, shorten_branches and final when the GOT pseudo reg |
6696 ;; didn't get allocated to a hard register. | 6800 ;; didn't get allocated to a hard register. |
6697 (define_split | 6801 (define_split |
6698 [(set (match_operand:SI 0 "gpc_reg_operand" "") | 6802 [(set (match_operand:SI 0 "gpc_reg_operand") |
6699 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "") | 6803 (unspec:SI [(match_operand:SI 1 "got_no_const_operand") |
6700 (match_operand:SI 2 "memory_operand" "")] | 6804 (match_operand:SI 2 "memory_operand")] |
6701 UNSPEC_MOVSI_GOT))] | 6805 UNSPEC_MOVSI_GOT))] |
6702 "DEFAULT_ABI == ABI_V4 | 6806 "DEFAULT_ABI == ABI_V4 |
6703 && flag_pic == 1 | 6807 && flag_pic == 1 |
6704 && reload_completed" | 6808 && reload_completed" |
6705 [(set (match_dup 0) (match_dup 2)) | 6809 [(set (match_dup 0) (match_dup 2)) |
6715 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") | 6819 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") |
6716 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") | 6820 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") |
6717 (match_operand 2 "" ""))))] | 6821 (match_operand 2 "" ""))))] |
6718 "TARGET_MACHO && ! TARGET_64BIT" | 6822 "TARGET_MACHO && ! TARGET_64BIT" |
6719 "lwz %0,lo16(%2)(%1)" | 6823 "lwz %0,lo16(%2)(%1)" |
6720 [(set_attr "type" "load") | 6824 [(set_attr "type" "load")]) |
6721 (set_attr "length" "4")]) | |
6722 | 6825 |
6723 ;; MR LA LWZ LFIWZX LXSIWZX | 6826 ;; MR LA LWZ LFIWZX LXSIWZX |
6724 ;; STW STFIWX STXSIWX LI LIS | 6827 ;; STW STFIWX STXSIWX LI LIS |
6725 ;; # XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW | 6828 ;; # XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW |
6726 ;; XXLXOR 0 XXLORC -1 P9 const MTVSRWZ MFVSRWZ | 6829 ;; XXLXOR 0 XXLORC -1 P9 const MTVSRWZ MFVSRWZ |
6738 r, wI, wH, I, L, | 6841 r, wI, wH, I, L, |
6739 n, wIwH, O, wM, wB, | 6842 n, wIwH, O, wM, wB, |
6740 O, wM, wS, r, wIwH, | 6843 O, wM, wS, r, wIwH, |
6741 *h, r, r, 0"))] | 6844 *h, r, r, 0"))] |
6742 | 6845 |
6743 "!TARGET_SINGLE_FPU && | 6846 "gpc_reg_operand (operands[0], SImode) |
6744 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))" | 6847 || gpc_reg_operand (operands[1], SImode)" |
6745 "@ | 6848 "@ |
6746 mr %0,%1 | 6849 mr %0,%1 |
6747 la %0,%a1 | 6850 la %0,%a1 |
6748 lwz%U1%X1 %0,%1 | 6851 lwz%U1%X1 %0,%1 |
6749 lfiwzx %0,%y1 | 6852 lfiwzx %0,%y1 |
6779 4, 4, 4, 4, 4, | 6882 4, 4, 4, 4, 4, |
6780 8, 4, 4, 4, 4, | 6883 8, 4, 4, 4, 4, |
6781 4, 4, 8, 4, 4, | 6884 4, 4, 8, 4, 4, |
6782 4, 4, 4, 4")]) | 6885 4, 4, 4, 4")]) |
6783 | 6886 |
6784 (define_insn "*movsi_internal1_single" | |
6785 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f") | |
6786 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))] | |
6787 "TARGET_SINGLE_FPU && | |
6788 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))" | |
6789 "@ | |
6790 mr %0,%1 | |
6791 la %0,%a1 | |
6792 lwz%U1%X1 %0,%1 | |
6793 stw%U0%X0 %1,%0 | |
6794 li %0,%1 | |
6795 lis %0,%v1 | |
6796 # | |
6797 mf%1 %0 | |
6798 mt%0 %1 | |
6799 mt%0 %1 | |
6800 nop | |
6801 stfs%U0%X0 %1,%0 | |
6802 lfs%U1%X1 %0,%1" | |
6803 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload") | |
6804 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")]) | |
6805 | |
6806 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e. | 6887 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e. |
6807 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0)) | 6888 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0)) |
6808 ;; | 6889 ;; |
6809 ;; Because SF values are actually stored as DF values within the vector | 6890 ;; Because SF values are actually stored as DF values within the vector |
6810 ;; registers, we need to convert the value to the vector SF format when | 6891 ;; registers, we need to convert the value to the vector SF format when |
6954 | 7035 |
6955 ;; Split a load of a large constant into the appropriate two-insn | 7036 ;; Split a load of a large constant into the appropriate two-insn |
6956 ;; sequence. | 7037 ;; sequence. |
6957 | 7038 |
6958 (define_split | 7039 (define_split |
6959 [(set (match_operand:SI 0 "gpc_reg_operand" "") | 7040 [(set (match_operand:SI 0 "gpc_reg_operand") |
6960 (match_operand:SI 1 "const_int_operand" ""))] | 7041 (match_operand:SI 1 "const_int_operand"))] |
6961 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000 | 7042 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000 |
6962 && (INTVAL (operands[1]) & 0xffff) != 0" | 7043 && (INTVAL (operands[1]) & 0xffff) != 0" |
6963 [(set (match_dup 0) | 7044 [(set (match_dup 0) |
6964 (match_dup 2)) | 7045 (match_dup 2)) |
6965 (set (match_dup 0) | 7046 (set (match_dup 0) |
6966 (ior:SI (match_dup 0) | 7047 (ior:SI (match_dup 0) |
6967 (match_dup 3)))] | 7048 (match_dup 3)))] |
6968 " | |
6969 { | 7049 { |
6970 if (rs6000_emit_set_const (operands[0], operands[1])) | 7050 if (rs6000_emit_set_const (operands[0], operands[1])) |
6971 DONE; | 7051 DONE; |
6972 else | 7052 else |
6973 FAIL; | 7053 FAIL; |
6974 }") | 7054 }) |
6975 | 7055 |
6976 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D | 7056 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D |
6977 (define_split | 7057 (define_split |
6978 [(set (match_operand:DI 0 "altivec_register_operand") | 7058 [(set (match_operand:DI 0 "altivec_register_operand") |
6979 (match_operand:DI 1 "xxspltib_constant_split"))] | 7059 (match_operand:DI 1 "xxspltib_constant_split"))] |
7015 (compare:CC (match_dup 0) | 7095 (compare:CC (match_dup 0) |
7016 (const_int 0)))] | 7096 (const_int 0)))] |
7017 "") | 7097 "") |
7018 | 7098 |
7019 (define_expand "mov<mode>" | 7099 (define_expand "mov<mode>" |
7020 [(set (match_operand:INT 0 "general_operand" "") | 7100 [(set (match_operand:INT 0 "general_operand") |
7021 (match_operand:INT 1 "any_operand" ""))] | 7101 (match_operand:INT 1 "any_operand"))] |
7022 "" | 7102 "" |
7023 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }") | 7103 { |
7104 rs6000_emit_move (operands[0], operands[1], <MODE>mode); | |
7105 DONE; | |
7106 }) | |
7024 | 7107 |
7025 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI | 7108 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI |
7026 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ | 7109 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ |
7027 ;; MTVSRWZ MF%1 MT%1 NOP | 7110 ;; MTVSRWZ MF%1 MT%1 NOP |
7028 (define_insn "*mov<mode>_internal" | 7111 (define_insn "*mov<mode>_internal" |
7068 | 7151 |
7069 ;; Here is how to move condition codes around. When we store CC data in | 7152 ;; Here is how to move condition codes around. When we store CC data in |
7070 ;; an integer register or memory, we store just the high-order 4 bits. | 7153 ;; an integer register or memory, we store just the high-order 4 bits. |
7071 ;; This lets us not shift in the most common case of CR0. | 7154 ;; This lets us not shift in the most common case of CR0. |
7072 (define_expand "movcc" | 7155 (define_expand "movcc" |
7073 [(set (match_operand:CC 0 "nonimmediate_operand" "") | 7156 [(set (match_operand:CC 0 "nonimmediate_operand") |
7074 (match_operand:CC 1 "nonimmediate_operand" ""))] | 7157 (match_operand:CC 1 "nonimmediate_operand"))] |
7075 "" | 7158 "" |
7076 "") | 7159 "") |
7077 | 7160 |
7078 (define_insn "*movcc_internal1" | 7161 (define_insn "*movcc_internal1" |
7079 [(set (match_operand:CC 0 "nonimmediate_operand" | 7162 [(set (match_operand:CC 0 "nonimmediate_operand" |
7093 li %0,%1 | 7176 li %0,%1 |
7094 mf%1 %0 | 7177 mf%1 %0 |
7095 mt%0 %1 | 7178 mt%0 %1 |
7096 lwz%U1%X1 %0,%1 | 7179 lwz%U1%X1 %0,%1 |
7097 stw%U0%X0 %1,%0" | 7180 stw%U0%X0 %1,%0" |
7098 [(set (attr "type") | 7181 [(set_attr_alternative "type" |
7099 (cond [(eq_attr "alternative" "0,3") | 7182 [(const_string "cr_logical") |
7100 (const_string "cr_logical") | 7183 (const_string "mtcr") |
7101 (eq_attr "alternative" "1,2") | 7184 (const_string "mtcr") |
7102 (const_string "mtcr") | 7185 (const_string "cr_logical") |
7103 (eq_attr "alternative" "6,7") | 7186 (if_then_else (match_test "TARGET_MFCRF") |
7104 (const_string "integer") | 7187 (const_string "mfcrf") (const_string "mfcr")) |
7105 (eq_attr "alternative" "8") | 7188 (if_then_else (match_test "TARGET_MFCRF") |
7106 (const_string "mfjmpr") | 7189 (const_string "mfcrf") (const_string "mfcr")) |
7107 (eq_attr "alternative" "9") | 7190 (const_string "integer") |
7108 (const_string "mtjmpr") | 7191 (const_string "integer") |
7109 (eq_attr "alternative" "10") | 7192 (const_string "mfjmpr") |
7110 (const_string "load") | 7193 (const_string "mtjmpr") |
7111 (eq_attr "alternative" "11") | 7194 (const_string "load") |
7112 (const_string "store") | 7195 (const_string "store")]) |
7113 (match_test "TARGET_MFCRF") | |
7114 (const_string "mfcrf") | |
7115 ] | |
7116 (const_string "mfcr"))) | |
7117 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")]) | 7196 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")]) |
7118 | 7197 |
7119 ;; For floating-point, we normally deal with the floating-point registers | 7198 ;; For floating-point, we normally deal with the floating-point registers |
7120 ;; unless -msoft-float is used. The sole exception is that parameter passing | 7199 ;; unless -msoft-float is used. The sole exception is that parameter passing |
7121 ;; can produce floating-point values in fixed-point registers. Unless the | 7200 ;; can produce floating-point values in fixed-point registers. Unless the |
7122 ;; value is a simple constant or already in memory, we deal with this by | 7201 ;; value is a simple constant or already in memory, we deal with this by |
7123 ;; allocating memory and copying the value explicitly via that memory location. | 7202 ;; allocating memory and copying the value explicitly via that memory location. |
7124 | 7203 |
7125 ;; Move 32-bit binary/decimal floating point | 7204 ;; Move 32-bit binary/decimal floating point |
7126 (define_expand "mov<mode>" | 7205 (define_expand "mov<mode>" |
7127 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "") | 7206 [(set (match_operand:FMOVE32 0 "nonimmediate_operand") |
7128 (match_operand:FMOVE32 1 "any_operand" ""))] | 7207 (match_operand:FMOVE32 1 "any_operand"))] |
7129 "<fmove_ok>" | 7208 "<fmove_ok>" |
7130 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }") | 7209 { |
7210 rs6000_emit_move (operands[0], operands[1], <MODE>mode); | |
7211 DONE; | |
7212 }) | |
7131 | 7213 |
7132 (define_split | 7214 (define_split |
7133 [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "") | 7215 [(set (match_operand:FMOVE32 0 "gpc_reg_operand") |
7134 (match_operand:FMOVE32 1 "const_double_operand" ""))] | 7216 (match_operand:FMOVE32 1 "const_double_operand"))] |
7135 "reload_completed | 7217 "reload_completed |
7136 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) | 7218 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) |
7137 || (GET_CODE (operands[0]) == SUBREG | 7219 || (GET_CODE (operands[0]) == SUBREG |
7138 && GET_CODE (SUBREG_REG (operands[0])) == REG | 7220 && GET_CODE (SUBREG_REG (operands[0])) == REG |
7139 && REGNO (SUBREG_REG (operands[0])) <= 31))" | 7221 && REGNO (SUBREG_REG (operands[0])) <= 31))" |
7140 [(set (match_dup 2) (match_dup 3))] | 7222 [(set (match_dup 2) (match_dup 3))] |
7141 " | |
7142 { | 7223 { |
7143 long l; | 7224 long l; |
7144 | 7225 |
7145 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); | 7226 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); |
7146 | 7227 |
7148 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode); | 7229 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode); |
7149 else | 7230 else |
7150 operands[2] = gen_lowpart (SImode, operands[0]); | 7231 operands[2] = gen_lowpart (SImode, operands[0]); |
7151 | 7232 |
7152 operands[3] = gen_int_mode (l, SImode); | 7233 operands[3] = gen_int_mode (l, SImode); |
7153 }") | 7234 }) |
7154 | 7235 |
7155 ;; Originally, we tried to keep movsf and movsd common, but the differences | 7236 ;; Originally, we tried to keep movsf and movsd common, but the differences |
7156 ;; addressing was making it rather difficult to hide with mode attributes. In | 7237 ;; addressing was making it rather difficult to hide with mode attributes. In |
7157 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store | 7238 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store |
7158 ;; before the VSX stores meant that the register allocator would tend to do a | 7239 ;; before the VSX stores meant that the register allocator would tend to do a |
7174 "m, m, wY, Z, f, wb, | 7255 "m, m, wY, Z, f, wb, |
7175 wu, r, j, j, f, ww, | 7256 wu, r, j, j, f, ww, |
7176 r, r, *h, 0"))] | 7257 r, r, *h, 0"))] |
7177 "(register_operand (operands[0], SFmode) | 7258 "(register_operand (operands[0], SFmode) |
7178 || register_operand (operands[1], SFmode)) | 7259 || register_operand (operands[1], SFmode)) |
7179 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT | 7260 && TARGET_HARD_FLOAT |
7180 && (TARGET_ALLOW_SF_SUBREG | 7261 && (TARGET_ALLOW_SF_SUBREG |
7181 || valid_sf_si_move (operands[0], operands[1], SFmode))" | 7262 || valid_sf_si_move (operands[0], operands[1], SFmode))" |
7182 "@ | 7263 "@ |
7183 lwz%U1%X1 %0,%1 | 7264 lwz%U1%X1 %0,%1 |
7184 lfs%U1%X1 %0,%1 | 7265 lfs%U1%X1 %0,%1 |
7210 (match_operand:SD 1 "input_operand" | 7291 (match_operand:SD 1 "input_operand" |
7211 "m, Z, r, wx, r, wh, | 7292 "m, Z, r, wx, r, wh, |
7212 f, r, r, *h, 0"))] | 7293 f, r, r, *h, 0"))] |
7213 "(register_operand (operands[0], SDmode) | 7294 "(register_operand (operands[0], SDmode) |
7214 || register_operand (operands[1], SDmode)) | 7295 || register_operand (operands[1], SDmode)) |
7215 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT" | 7296 && TARGET_HARD_FLOAT" |
7216 "@ | 7297 "@ |
7217 lwz%U1%X1 %0,%1 | 7298 lwz%U1%X1 %0,%1 |
7218 lfiwzx %0,%y1 | 7299 lfiwzx %0,%y1 |
7219 stw%U0%X0 %1,%0 | 7300 stw%U0%X0 %1,%0 |
7220 stfiwx %1,%y0 | 7301 stfiwx %1,%y0 |
7227 nop" | 7308 nop" |
7228 [(set_attr "type" | 7309 [(set_attr "type" |
7229 "load, fpload, store, fpstore, mffgpr, mftgpr, | 7310 "load, fpload, store, fpstore, mffgpr, mftgpr, |
7230 fpsimple, *, mtjmpr, mfjmpr, *")]) | 7311 fpsimple, *, mtjmpr, mfjmpr, *")]) |
7231 | 7312 |
7313 ;; MR MT%0 MF%0 LWZ STW LI | |
7314 ;; LIS G-const. F/n-const NOP | |
7232 (define_insn "*mov<mode>_softfloat" | 7315 (define_insn "*mov<mode>_softfloat" |
7233 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h") | 7316 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" |
7234 (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))] | 7317 "=r, cl, r, r, m, r, |
7318 r, r, r, *h") | |
7319 | |
7320 (match_operand:FMOVE32 1 "input_operand" | |
7321 "r, r, h, m, r, I, | |
7322 L, G, Fn, 0"))] | |
7323 | |
7235 "(gpc_reg_operand (operands[0], <MODE>mode) | 7324 "(gpc_reg_operand (operands[0], <MODE>mode) |
7236 || gpc_reg_operand (operands[1], <MODE>mode)) | 7325 || gpc_reg_operand (operands[1], <MODE>mode)) |
7237 && TARGET_SOFT_FLOAT" | 7326 && TARGET_SOFT_FLOAT" |
7238 "@ | 7327 "@ |
7239 mr %0,%1 | 7328 mr %0,%1 |
7244 li %0,%1 | 7333 li %0,%1 |
7245 lis %0,%v1 | 7334 lis %0,%v1 |
7246 # | 7335 # |
7247 # | 7336 # |
7248 nop" | 7337 nop" |
7249 [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*") | 7338 [(set_attr "type" |
7250 (set_attr "length" "4,4,4,4,4,4,4,4,8,4")]) | 7339 "*, mtjmpr, mfjmpr, load, store, *, |
7340 *, *, *, *") | |
7341 | |
7342 (set_attr "length" | |
7343 "4, 4, 4, 4, 4, 4, | |
7344 4, 4, 8, 4")]) | |
7251 | 7345 |
7252 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e. | 7346 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e. |
7253 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0)) | 7347 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0)) |
7254 ;; | 7348 ;; |
7255 ;; Because SF values are actually stored as DF values within the vector | 7349 ;; Because SF values are actually stored as DF values within the vector |
7319 fpstore, vecfloat, mffgpr, *")]) | 7413 fpstore, vecfloat, mffgpr, *")]) |
7320 | 7414 |
7321 | 7415 |
7322 ;; Move 64-bit binary/decimal floating point | 7416 ;; Move 64-bit binary/decimal floating point |
7323 (define_expand "mov<mode>" | 7417 (define_expand "mov<mode>" |
7324 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "") | 7418 [(set (match_operand:FMOVE64 0 "nonimmediate_operand") |
7325 (match_operand:FMOVE64 1 "any_operand" ""))] | 7419 (match_operand:FMOVE64 1 "any_operand"))] |
7326 "" | 7420 "" |
7327 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }") | 7421 { |
7422 rs6000_emit_move (operands[0], operands[1], <MODE>mode); | |
7423 DONE; | |
7424 }) | |
7328 | 7425 |
7329 (define_split | 7426 (define_split |
7330 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "") | 7427 [(set (match_operand:FMOVE64 0 "gpc_reg_operand") |
7331 (match_operand:FMOVE64 1 "const_int_operand" ""))] | 7428 (match_operand:FMOVE64 1 "const_int_operand"))] |
7332 "! TARGET_POWERPC64 && reload_completed | 7429 "! TARGET_POWERPC64 && reload_completed |
7333 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) | 7430 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) |
7334 || (GET_CODE (operands[0]) == SUBREG | 7431 || (GET_CODE (operands[0]) == SUBREG |
7335 && GET_CODE (SUBREG_REG (operands[0])) == REG | 7432 && GET_CODE (SUBREG_REG (operands[0])) == REG |
7336 && REGNO (SUBREG_REG (operands[0])) <= 31))" | 7433 && REGNO (SUBREG_REG (operands[0])) <= 31))" |
7337 [(set (match_dup 2) (match_dup 4)) | 7434 [(set (match_dup 2) (match_dup 4)) |
7338 (set (match_dup 3) (match_dup 1))] | 7435 (set (match_dup 3) (match_dup 1))] |
7339 " | |
7340 { | 7436 { |
7341 int endian = (WORDS_BIG_ENDIAN == 0); | 7437 int endian = (WORDS_BIG_ENDIAN == 0); |
7342 HOST_WIDE_INT value = INTVAL (operands[1]); | 7438 HOST_WIDE_INT value = INTVAL (operands[1]); |
7343 | 7439 |
7344 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode); | 7440 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode); |
7345 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode); | 7441 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode); |
7346 operands[4] = GEN_INT (value >> 32); | 7442 operands[4] = GEN_INT (value >> 32); |
7347 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); | 7443 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); |
7348 }") | 7444 }) |
7349 | 7445 |
7350 (define_split | 7446 (define_split |
7351 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "") | 7447 [(set (match_operand:FMOVE64 0 "gpc_reg_operand") |
7352 (match_operand:FMOVE64 1 "const_double_operand" ""))] | 7448 (match_operand:FMOVE64 1 "const_double_operand"))] |
7353 "! TARGET_POWERPC64 && reload_completed | 7449 "! TARGET_POWERPC64 && reload_completed |
7354 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) | 7450 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) |
7355 || (GET_CODE (operands[0]) == SUBREG | 7451 || (GET_CODE (operands[0]) == SUBREG |
7356 && GET_CODE (SUBREG_REG (operands[0])) == REG | 7452 && GET_CODE (SUBREG_REG (operands[0])) == REG |
7357 && REGNO (SUBREG_REG (operands[0])) <= 31))" | 7453 && REGNO (SUBREG_REG (operands[0])) <= 31))" |
7358 [(set (match_dup 2) (match_dup 4)) | 7454 [(set (match_dup 2) (match_dup 4)) |
7359 (set (match_dup 3) (match_dup 5))] | 7455 (set (match_dup 3) (match_dup 5))] |
7360 " | |
7361 { | 7456 { |
7362 int endian = (WORDS_BIG_ENDIAN == 0); | 7457 int endian = (WORDS_BIG_ENDIAN == 0); |
7363 long l[2]; | 7458 long l[2]; |
7364 | 7459 |
7365 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); | 7460 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); |
7366 | 7461 |
7367 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode); | 7462 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode); |
7368 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode); | 7463 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode); |
7369 operands[4] = gen_int_mode (l[endian], SImode); | 7464 operands[4] = gen_int_mode (l[endian], SImode); |
7370 operands[5] = gen_int_mode (l[1 - endian], SImode); | 7465 operands[5] = gen_int_mode (l[1 - endian], SImode); |
7371 }") | 7466 }) |
7372 | 7467 |
7373 (define_split | 7468 (define_split |
7374 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "") | 7469 [(set (match_operand:FMOVE64 0 "gpc_reg_operand") |
7375 (match_operand:FMOVE64 1 "const_double_operand" ""))] | 7470 (match_operand:FMOVE64 1 "const_double_operand"))] |
7376 "TARGET_POWERPC64 && reload_completed | 7471 "TARGET_POWERPC64 && reload_completed |
7377 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) | 7472 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) |
7378 || (GET_CODE (operands[0]) == SUBREG | 7473 || (GET_CODE (operands[0]) == SUBREG |
7379 && GET_CODE (SUBREG_REG (operands[0])) == REG | 7474 && GET_CODE (SUBREG_REG (operands[0])) == REG |
7380 && REGNO (SUBREG_REG (operands[0])) <= 31))" | 7475 && REGNO (SUBREG_REG (operands[0])) <= 31))" |
7381 [(set (match_dup 2) (match_dup 3))] | 7476 [(set (match_dup 2) (match_dup 3))] |
7382 " | |
7383 { | 7477 { |
7384 int endian = (WORDS_BIG_ENDIAN == 0); | 7478 int endian = (WORDS_BIG_ENDIAN == 0); |
7385 long l[2]; | 7479 long l[2]; |
7386 HOST_WIDE_INT val; | 7480 HOST_WIDE_INT val; |
7387 | 7481 |
7391 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */ | 7485 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */ |
7392 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32 | 7486 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32 |
7393 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian])); | 7487 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian])); |
7394 | 7488 |
7395 operands[3] = gen_int_mode (val, DImode); | 7489 operands[3] = gen_int_mode (val, DImode); |
7396 }") | 7490 }) |
7397 | 7491 |
7398 ;; Don't have reload use general registers to load a constant. It is | 7492 ;; Don't have reload use general registers to load a constant. It is |
7399 ;; less efficient than loading the constant into an FP register, since | 7493 ;; less efficient than loading the constant into an FP register, since |
7400 ;; it will probably be used there. | 7494 ;; it will probably be used there. |
7401 | 7495 |
7408 ;; registers. | 7502 ;; registers. |
7409 | 7503 |
7410 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory, | 7504 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory, |
7411 ;; except for 0.0 which can be created on VSX with an xor instruction. | 7505 ;; except for 0.0 which can be created on VSX with an xor instruction. |
7412 | 7506 |
7507 ;; STFD LFD FMR LXSD STXSD | |
7508 ;; LXSD STXSD XXLOR XXLXOR GPR<-0 | |
7509 ;; LWZ STW MR | |
7510 | |
7511 | |
7413 (define_insn "*mov<mode>_hardfloat32" | 7512 (define_insn "*mov<mode>_hardfloat32" |
7414 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r") | 7513 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" |
7415 (match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))] | 7514 "=m, d, d, <f64_p9>, wY, |
7416 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT | 7515 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r, |
7516 Y, r, !r") | |
7517 | |
7518 (match_operand:FMOVE64 1 "input_operand" | |
7519 "d, m, d, wY, <f64_p9>, | |
7520 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>, | |
7521 r, Y, r"))] | |
7522 | |
7523 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT | |
7417 && (gpc_reg_operand (operands[0], <MODE>mode) | 7524 && (gpc_reg_operand (operands[0], <MODE>mode) |
7418 || gpc_reg_operand (operands[1], <MODE>mode))" | 7525 || gpc_reg_operand (operands[1], <MODE>mode))" |
7419 "@ | 7526 "@ |
7420 stfd%U0%X0 %1,%0 | 7527 stfd%U0%X0 %1,%0 |
7421 lfd%U1%X1 %0,%1 | 7528 lfd%U1%X1 %0,%1 |
7422 fmr %0,%1 | 7529 fmr %0,%1 |
7423 lxsd %0,%1 | 7530 lxsd %0,%1 |
7424 stxsd %1,%0 | 7531 stxsd %1,%0 |
7425 lxsd%U1x %x0,%y1 | 7532 lxsdx %x0,%y1 |
7426 stxsd%U0x %x1,%y0 | 7533 stxsdx %x1,%y0 |
7427 xxlor %x0,%x1,%x1 | 7534 xxlor %x0,%x1,%x1 |
7428 xxlxor %x0,%x0,%x0 | 7535 xxlxor %x0,%x0,%x0 |
7429 # | 7536 # |
7430 # | 7537 # |
7431 # | 7538 # |
7432 #" | 7539 #" |
7433 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two") | 7540 [(set_attr "type" |
7541 "fpstore, fpload, fpsimple, fpload, fpstore, | |
7542 fpload, fpstore, veclogical, veclogical, two, | |
7543 store, load, two") | |
7544 | |
7434 (set_attr "size" "64") | 7545 (set_attr "size" "64") |
7435 (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")]) | 7546 (set_attr "length" |
7547 "4, 4, 4, 4, 4, | |
7548 4, 4, 4, 4, 8, | |
7549 8, 8, 8")]) | |
7550 | |
7551 ;; STW LWZ MR G-const H-const F-const | |
7436 | 7552 |
7437 (define_insn "*mov<mode>_softfloat32" | 7553 (define_insn "*mov<mode>_softfloat32" |
7438 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r") | 7554 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" |
7439 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))] | 7555 "=Y, r, r, r, r, r") |
7440 "! TARGET_POWERPC64 | 7556 |
7441 && (TARGET_SINGLE_FLOAT || TARGET_SOFT_FLOAT) | 7557 (match_operand:FMOVE64 1 "input_operand" |
7558 "r, Y, r, G, H, F"))] | |
7559 | |
7560 "!TARGET_POWERPC64 | |
7442 && (gpc_reg_operand (operands[0], <MODE>mode) | 7561 && (gpc_reg_operand (operands[0], <MODE>mode) |
7443 || gpc_reg_operand (operands[1], <MODE>mode))" | 7562 || gpc_reg_operand (operands[1], <MODE>mode))" |
7444 "#" | 7563 "#" |
7445 [(set_attr "type" "store,load,two,*,*,*") | 7564 [(set_attr "type" |
7446 (set_attr "length" "8,8,8,8,12,16")]) | 7565 "store, load, two, *, *, *") |
7566 | |
7567 (set_attr "length" | |
7568 "8, 8, 8, 8, 12, 16")]) | |
7447 | 7569 |
7448 ; ld/std require word-aligned displacements -> 'Y' constraint. | 7570 ; ld/std require word-aligned displacements -> 'Y' constraint. |
7449 ; List Y->r and r->Y before r->r for reload. | 7571 ; List Y->r and r->Y before r->r for reload. |
7572 | |
7573 ;; STFD LFD FMR LXSD STXSD | |
7574 ;; LXSDX STXSDX XXLOR XXLXOR LI 0 | |
7575 ;; STD LD MR MT{CTR,LR} MF{CTR,LR} | |
7576 ;; NOP MFTGPR MFFGPR MFVSRD MTVSRD | |
7577 | |
7450 (define_insn "*mov<mode>_hardfloat64" | 7578 (define_insn "*mov<mode>_hardfloat64" |
7451 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r,*c*l,!r,*h,r,wg,r,<f64_dm>") | 7579 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" |
7452 (match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r,r,h,0,wg,r,<f64_dm>,r"))] | 7580 "=m, d, d, <f64_p9>, wY, |
7453 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT | 7581 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r, |
7582 YZ, r, !r, *c*l, !r, | |
7583 *h, r, wg, r, <f64_dm>") | |
7584 | |
7585 (match_operand:FMOVE64 1 "input_operand" | |
7586 "d, m, d, wY, <f64_p9>, | |
7587 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>, | |
7588 r, YZ, r, r, h, | |
7589 0, wg, r, <f64_dm>, r"))] | |
7590 | |
7591 "TARGET_POWERPC64 && TARGET_HARD_FLOAT | |
7454 && (gpc_reg_operand (operands[0], <MODE>mode) | 7592 && (gpc_reg_operand (operands[0], <MODE>mode) |
7455 || gpc_reg_operand (operands[1], <MODE>mode))" | 7593 || gpc_reg_operand (operands[1], <MODE>mode))" |
7456 "@ | 7594 "@ |
7457 stfd%U0%X0 %1,%0 | 7595 stfd%U0%X0 %1,%0 |
7458 lfd%U1%X1 %0,%1 | 7596 lfd%U1%X1 %0,%1 |
7459 fmr %0,%1 | 7597 fmr %0,%1 |
7460 lxsd %0,%1 | 7598 lxsd %0,%1 |
7461 stxsd %1,%0 | 7599 stxsd %1,%0 |
7462 lxsd%U1x %x0,%y1 | 7600 lxsdx %x0,%y1 |
7463 stxsd%U0x %x1,%y0 | 7601 stxsdx %x1,%y0 |
7464 xxlor %x0,%x1,%x1 | 7602 xxlor %x0,%x1,%x1 |
7465 xxlxor %x0,%x0,%x0 | 7603 xxlxor %x0,%x0,%x0 |
7466 li %0,0 | 7604 li %0,0 |
7467 std%U0%X0 %1,%0 | 7605 std%U0%X0 %1,%0 |
7468 ld%U1%X1 %0,%1 | 7606 ld%U1%X1 %0,%1 |
7472 nop | 7610 nop |
7473 mftgpr %0,%1 | 7611 mftgpr %0,%1 |
7474 mffgpr %0,%1 | 7612 mffgpr %0,%1 |
7475 mfvsrd %0,%x1 | 7613 mfvsrd %0,%x1 |
7476 mtvsrd %x0,%1" | 7614 mtvsrd %x0,%1" |
7477 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr") | 7615 [(set_attr "type" |
7616 "fpstore, fpload, fpsimple, fpload, fpstore, | |
7617 fpload, fpstore, veclogical, veclogical, integer, | |
7618 store, load, *, mtjmpr, mfjmpr, | |
7619 *, mftgpr, mffgpr, mftgpr, mffgpr") | |
7620 | |
7478 (set_attr "size" "64") | 7621 (set_attr "size" "64") |
7479 (set_attr "length" "4")]) | 7622 (set_attr "length" "4")]) |
7480 | 7623 |
7624 ;; STD LD MR MT<SPR> MF<SPR> G-const | |
7625 ;; H-const F-const Special | |
7626 | |
7481 (define_insn "*mov<mode>_softfloat64" | 7627 (define_insn "*mov<mode>_softfloat64" |
7482 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h") | 7628 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" |
7483 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))] | 7629 "=Y, r, r, cl, r, r, |
7630 r, r, *h") | |
7631 | |
7632 (match_operand:FMOVE64 1 "input_operand" | |
7633 "r, Y, r, r, h, G, | |
7634 H, F, 0"))] | |
7635 | |
7484 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT | 7636 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT |
7485 && (gpc_reg_operand (operands[0], <MODE>mode) | 7637 && (gpc_reg_operand (operands[0], <MODE>mode) |
7486 || gpc_reg_operand (operands[1], <MODE>mode))" | 7638 || gpc_reg_operand (operands[1], <MODE>mode))" |
7487 "@ | 7639 "@ |
7488 std%U0%X0 %1,%0 | 7640 std%U0%X0 %1,%0 |
7492 mf%1 %0 | 7644 mf%1 %0 |
7493 # | 7645 # |
7494 # | 7646 # |
7495 # | 7647 # |
7496 nop" | 7648 nop" |
7497 [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*") | 7649 [(set_attr "type" |
7498 (set_attr "length" "4,4,4,4,4,8,12,16,4")]) | 7650 "store, load, *, mtjmpr, mfjmpr, *, |
7651 *, *, *") | |
7652 | |
7653 (set_attr "length" | |
7654 "4, 4, 4, 4, 4, 8, | |
7655 12, 16, 4")]) | |
7499 | 7656 |
7500 (define_expand "mov<mode>" | 7657 (define_expand "mov<mode>" |
7501 [(set (match_operand:FMOVE128 0 "general_operand" "") | 7658 [(set (match_operand:FMOVE128 0 "general_operand") |
7502 (match_operand:FMOVE128 1 "any_operand" ""))] | 7659 (match_operand:FMOVE128 1 "any_operand"))] |
7503 "" | 7660 "" |
7504 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }") | 7661 { |
7662 rs6000_emit_move (operands[0], operands[1], <MODE>mode); | |
7663 DONE; | |
7664 }) | |
7505 | 7665 |
7506 ;; It's important to list Y->r and r->Y before r->r because otherwise | 7666 ;; It's important to list Y->r and r->Y before r->r because otherwise |
7507 ;; reload, given m->r, will try to pick r->r and reload it, which | 7667 ;; reload, given m->r, will try to pick r->r and reload it, which |
7508 ;; doesn't make progress. | 7668 ;; doesn't make progress. |
7509 | 7669 |
7562 [(pc)] | 7722 [(pc)] |
7563 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; } | 7723 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; } |
7564 [(set_attr "length" "20,20,16")]) | 7724 [(set_attr "length" "20,20,16")]) |
7565 | 7725 |
7566 (define_expand "extenddf<mode>2" | 7726 (define_expand "extenddf<mode>2" |
7567 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "") | 7727 [(set (match_operand:FLOAT128 0 "gpc_reg_operand") |
7568 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))] | 7728 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))] |
7569 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" | 7729 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" |
7570 { | 7730 { |
7571 if (FLOAT128_IEEE_P (<MODE>mode)) | 7731 if (FLOAT128_IEEE_P (<MODE>mode)) |
7572 rs6000_expand_float128_convert (operands[0], operands[1], false); | 7732 rs6000_expand_float128_convert (operands[0], operands[1], false); |
7573 else if (TARGET_VSX) | 7733 else if (TARGET_VSX) |
7598 (define_insn_and_split "extenddf<mode>2_fprs" | 7758 (define_insn_and_split "extenddf<mode>2_fprs" |
7599 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d") | 7759 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d") |
7600 (float_extend:IBM128 | 7760 (float_extend:IBM128 |
7601 (match_operand:DF 1 "nonimmediate_operand" "d,m,d"))) | 7761 (match_operand:DF 1 "nonimmediate_operand" "d,m,d"))) |
7602 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))] | 7762 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))] |
7603 "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT | 7763 "!TARGET_VSX && TARGET_HARD_FLOAT |
7604 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)" | 7764 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)" |
7605 "#" | 7765 "#" |
7606 "&& reload_completed" | 7766 "&& reload_completed" |
7607 [(set (match_dup 3) (match_dup 1)) | 7767 [(set (match_dup 3) (match_dup 1)) |
7608 (set (match_dup 4) (match_dup 2))] | 7768 (set (match_dup 4) (match_dup 2))] |
7631 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word); | 7791 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word); |
7632 operands[4] = CONST0_RTX (DFmode); | 7792 operands[4] = CONST0_RTX (DFmode); |
7633 }) | 7793 }) |
7634 | 7794 |
7635 (define_expand "extendsf<mode>2" | 7795 (define_expand "extendsf<mode>2" |
7636 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "") | 7796 [(set (match_operand:FLOAT128 0 "gpc_reg_operand") |
7637 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))] | 7797 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))] |
7638 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" | 7798 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" |
7639 { | 7799 { |
7640 if (FLOAT128_IEEE_P (<MODE>mode)) | 7800 if (FLOAT128_IEEE_P (<MODE>mode)) |
7641 rs6000_expand_float128_convert (operands[0], operands[1], false); | 7801 rs6000_expand_float128_convert (operands[0], operands[1], false); |
7642 else | 7802 else |
7647 } | 7807 } |
7648 DONE; | 7808 DONE; |
7649 }) | 7809 }) |
7650 | 7810 |
7651 (define_expand "trunc<mode>df2" | 7811 (define_expand "trunc<mode>df2" |
7652 [(set (match_operand:DF 0 "gpc_reg_operand" "") | 7812 [(set (match_operand:DF 0 "gpc_reg_operand") |
7653 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))] | 7813 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))] |
7654 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" | 7814 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" |
7655 { | 7815 { |
7656 if (FLOAT128_IEEE_P (<MODE>mode)) | 7816 if (FLOAT128_IEEE_P (<MODE>mode)) |
7657 { | 7817 { |
7658 rs6000_expand_float128_convert (operands[0], operands[1], false); | 7818 rs6000_expand_float128_convert (operands[0], operands[1], false); |
7679 | 7839 |
7680 (define_insn "trunc<mode>df2_internal2" | 7840 (define_insn "trunc<mode>df2_internal2" |
7681 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") | 7841 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") |
7682 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))] | 7842 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))] |
7683 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT | 7843 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT |
7684 && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" | 7844 && TARGET_LONG_DOUBLE_128" |
7685 "fadd %0,%1,%L1" | 7845 "fadd %0,%1,%L1" |
7686 [(set_attr "type" "fp") | 7846 [(set_attr "type" "fp")]) |
7687 (set_attr "fp_type" "fp_addsub_d")]) | |
7688 | 7847 |
7689 (define_expand "trunc<mode>sf2" | 7848 (define_expand "trunc<mode>sf2" |
7690 [(set (match_operand:SF 0 "gpc_reg_operand" "") | 7849 [(set (match_operand:SF 0 "gpc_reg_operand") |
7691 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))] | 7850 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))] |
7692 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" | 7851 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" |
7693 { | 7852 { |
7694 if (FLOAT128_IEEE_P (<MODE>mode)) | 7853 if (FLOAT128_IEEE_P (<MODE>mode)) |
7695 rs6000_expand_float128_convert (operands[0], operands[1], false); | 7854 rs6000_expand_float128_convert (operands[0], operands[1], false); |
7696 else if (<MODE>mode == TFmode) | |
7697 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1])); | |
7698 else if (<MODE>mode == IFmode) | |
7699 emit_insn (gen_truncifsf2_fprs (operands[0], operands[1])); | |
7700 else | 7855 else |
7701 gcc_unreachable (); | 7856 { |
7857 rtx tmp = gen_reg_rtx (DFmode); | |
7858 emit_insn (gen_trunc<mode>df2 (tmp, operands[1])); | |
7859 emit_insn (gen_truncdfsf2 (operands[0], tmp)); | |
7860 } | |
7702 DONE; | 7861 DONE; |
7703 }) | 7862 }) |
7704 | |
7705 (define_insn_and_split "trunc<mode>sf2_fprs" | |
7706 [(set (match_operand:SF 0 "gpc_reg_operand" "=f") | |
7707 (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d"))) | |
7708 (clobber (match_scratch:DF 2 "=d"))] | |
7709 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT | |
7710 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)" | |
7711 "#" | |
7712 "&& reload_completed" | |
7713 [(set (match_dup 2) | |
7714 (float_truncate:DF (match_dup 1))) | |
7715 (set (match_dup 0) | |
7716 (float_truncate:SF (match_dup 2)))] | |
7717 "") | |
7718 | 7863 |
7719 (define_expand "floatsi<mode>2" | 7864 (define_expand "floatsi<mode>2" |
7720 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand") | 7865 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand") |
7721 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand"))) | 7866 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand"))) |
7722 (clobber (match_scratch:DI 2))])] | 7867 (clobber (match_scratch:DI 2))])] |
7751 (define_insn "fix_trunc_helper<mode>" | 7896 (define_insn "fix_trunc_helper<mode>" |
7752 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") | 7897 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") |
7753 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")] | 7898 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")] |
7754 UNSPEC_FIX_TRUNC_TF)) | 7899 UNSPEC_FIX_TRUNC_TF)) |
7755 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))] | 7900 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))] |
7756 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && FLOAT128_IBM_P (<MODE>mode)" | 7901 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)" |
7757 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2" | 7902 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2" |
7758 [(set_attr "type" "fp") | 7903 [(set_attr "type" "fp") |
7759 (set_attr "length" "20")]) | 7904 (set_attr "length" "20")]) |
7760 | 7905 |
7761 (define_expand "fix_trunc<mode>si2" | 7906 (define_expand "fix_trunc<mode>si2" |
7762 [(set (match_operand:SI 0 "gpc_reg_operand" "") | 7907 [(set (match_operand:SI 0 "gpc_reg_operand") |
7763 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))] | 7908 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))] |
7764 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" | 7909 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" |
7765 { | 7910 { |
7766 rtx op0 = operands[0]; | 7911 rtx op0 = operands[0]; |
7767 rtx op1 = operands[1]; | 7912 rtx op1 = operands[1]; |
7768 | 7913 |
7781 DONE; | 7926 DONE; |
7782 } | 7927 } |
7783 }) | 7928 }) |
7784 | 7929 |
7785 (define_expand "fix_trunc<mode>si2_fprs" | 7930 (define_expand "fix_trunc<mode>si2_fprs" |
7786 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "") | 7931 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand") |
7787 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" ""))) | 7932 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand"))) |
7788 (clobber (match_dup 2)) | 7933 (clobber (match_dup 2)) |
7789 (clobber (match_dup 3)) | 7934 (clobber (match_dup 3)) |
7790 (clobber (match_dup 4)) | 7935 (clobber (match_dup 4)) |
7791 (clobber (match_dup 5))])] | 7936 (clobber (match_dup 5))])] |
7792 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" | 7937 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" |
7821 emit_move_insn (operands[0], lowword); | 7966 emit_move_insn (operands[0], lowword); |
7822 DONE; | 7967 DONE; |
7823 }) | 7968 }) |
7824 | 7969 |
7825 (define_expand "fix_trunc<mode>di2" | 7970 (define_expand "fix_trunc<mode>di2" |
7826 [(set (match_operand:DI 0 "gpc_reg_operand" "") | 7971 [(set (match_operand:DI 0 "gpc_reg_operand") |
7827 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))] | 7972 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))] |
7828 "TARGET_FLOAT128_TYPE" | 7973 "TARGET_FLOAT128_TYPE" |
7829 { | 7974 { |
7830 if (!TARGET_FLOAT128_HW) | 7975 if (!TARGET_FLOAT128_HW) |
7831 { | 7976 { |
7832 rs6000_expand_float128_convert (operands[0], operands[1], false); | 7977 rs6000_expand_float128_convert (operands[0], operands[1], false); |
7833 DONE; | 7978 DONE; |
7834 } | 7979 } |
7835 }) | 7980 }) |
7836 | 7981 |
7837 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2" | 7982 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2" |
7838 [(set (match_operand:SDI 0 "gpc_reg_operand" "") | 7983 [(set (match_operand:SDI 0 "gpc_reg_operand") |
7839 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))] | 7984 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))] |
7840 "TARGET_FLOAT128_TYPE" | 7985 "TARGET_FLOAT128_TYPE" |
7841 { | 7986 { |
7842 rs6000_expand_float128_convert (operands[0], operands[1], true); | 7987 rs6000_expand_float128_convert (operands[0], operands[1], true); |
7843 DONE; | 7988 DONE; |
7844 }) | 7989 }) |
7845 | 7990 |
7846 (define_expand "floatdi<mode>2" | 7991 (define_expand "floatdi<mode>2" |
7847 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "") | 7992 [(set (match_operand:IEEE128 0 "gpc_reg_operand") |
7848 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))] | 7993 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))] |
7849 "TARGET_FLOAT128_TYPE" | 7994 "TARGET_FLOAT128_TYPE" |
7850 { | 7995 { |
7851 if (!TARGET_FLOAT128_HW) | 7996 if (!TARGET_FLOAT128_HW) |
7852 { | 7997 { |
7853 rs6000_expand_float128_convert (operands[0], operands[1], false); | 7998 rs6000_expand_float128_convert (operands[0], operands[1], false); |
7854 DONE; | 7999 DONE; |
7855 } | 8000 } |
7856 }) | 8001 }) |
7857 | 8002 |
7858 (define_expand "floatunsdi<IEEE128:mode>2" | 8003 (define_expand "floatunsdi<IEEE128:mode>2" |
7859 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "") | 8004 [(set (match_operand:IEEE128 0 "gpc_reg_operand") |
7860 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))] | 8005 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))] |
7861 "TARGET_FLOAT128_TYPE" | 8006 "TARGET_FLOAT128_TYPE" |
7862 { | 8007 { |
7863 if (!TARGET_FLOAT128_HW) | 8008 if (!TARGET_FLOAT128_HW) |
7864 { | 8009 { |
7865 rs6000_expand_float128_convert (operands[0], operands[1], true); | 8010 rs6000_expand_float128_convert (operands[0], operands[1], true); |
7866 DONE; | 8011 DONE; |
7867 } | 8012 } |
7868 }) | 8013 }) |
7869 | 8014 |
7870 (define_expand "floatuns<IEEE128:mode>2" | 8015 (define_expand "floatuns<IEEE128:mode>2" |
7871 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "") | 8016 [(set (match_operand:IEEE128 0 "gpc_reg_operand") |
7872 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand" "")))] | 8017 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))] |
7873 "TARGET_FLOAT128_TYPE" | 8018 "TARGET_FLOAT128_TYPE" |
7874 { | 8019 { |
7875 rtx op0 = operands[0]; | 8020 rtx op0 = operands[0]; |
7876 rtx op1 = operands[1]; | 8021 rtx op1 = operands[1]; |
7877 | 8022 |
7881 rs6000_expand_float128_convert (op0, op1, true); | 8026 rs6000_expand_float128_convert (op0, op1, true); |
7882 DONE; | 8027 DONE; |
7883 }) | 8028 }) |
7884 | 8029 |
7885 (define_expand "neg<mode>2" | 8030 (define_expand "neg<mode>2" |
7886 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "") | 8031 [(set (match_operand:FLOAT128 0 "gpc_reg_operand") |
7887 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))] | 8032 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))] |
7888 "FLOAT128_IEEE_P (<MODE>mode) | 8033 "FLOAT128_IEEE_P (<MODE>mode) |
7889 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)" | 8034 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)" |
7890 " | |
7891 { | 8035 { |
7892 if (FLOAT128_IEEE_P (<MODE>mode)) | 8036 if (FLOAT128_IEEE_P (<MODE>mode)) |
7893 { | 8037 { |
7894 if (TARGET_FLOAT128_HW) | 8038 if (TARGET_FLOAT128_HW) |
7895 { | 8039 { |
7919 if (target && !rtx_equal_p (target, operands[0])) | 8063 if (target && !rtx_equal_p (target, operands[0])) |
7920 emit_move_insn (operands[0], target); | 8064 emit_move_insn (operands[0], target); |
7921 } | 8065 } |
7922 DONE; | 8066 DONE; |
7923 } | 8067 } |
7924 }") | 8068 }) |
7925 | 8069 |
7926 (define_insn "neg<mode>2_internal" | 8070 (define_insn "neg<mode>2_internal" |
7927 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d") | 8071 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d") |
7928 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))] | 8072 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))] |
7929 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (TFmode)" | 8073 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)" |
7930 "* | |
7931 { | 8074 { |
7932 if (REGNO (operands[0]) == REGNO (operands[1]) + 1) | 8075 if (REGNO (operands[0]) == REGNO (operands[1]) + 1) |
7933 return \"fneg %L0,%L1\;fneg %0,%1\"; | 8076 return "fneg %L0,%L1\;fneg %0,%1"; |
7934 else | 8077 else |
7935 return \"fneg %0,%1\;fneg %L0,%L1\"; | 8078 return "fneg %0,%1\;fneg %L0,%L1"; |
7936 }" | 8079 } |
7937 [(set_attr "type" "fpsimple") | 8080 [(set_attr "type" "fpsimple") |
7938 (set_attr "length" "8")]) | 8081 (set_attr "length" "8")]) |
7939 | 8082 |
7940 (define_expand "abs<mode>2" | 8083 (define_expand "abs<mode>2" |
7941 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "") | 8084 [(set (match_operand:FLOAT128 0 "gpc_reg_operand") |
7942 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))] | 8085 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))] |
7943 "FLOAT128_IEEE_P (<MODE>mode) | 8086 "FLOAT128_IEEE_P (<MODE>mode) |
7944 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)" | 8087 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)" |
7945 " | |
7946 { | 8088 { |
7947 rtx label; | 8089 rtx label; |
7948 | 8090 |
7949 if (FLOAT128_IEEE_P (<MODE>mode)) | 8091 if (FLOAT128_IEEE_P (<MODE>mode)) |
7950 { | 8092 { |
7973 } | 8115 } |
7974 | 8116 |
7975 label = gen_label_rtx (); | 8117 label = gen_label_rtx (); |
7976 if (<MODE>mode == TFmode) | 8118 if (<MODE>mode == TFmode) |
7977 emit_insn (gen_abstf2_internal (operands[0], operands[1], label)); | 8119 emit_insn (gen_abstf2_internal (operands[0], operands[1], label)); |
7978 else if (<MODE>mode == TFmode) | 8120 else if (<MODE>mode == IFmode) |
7979 emit_insn (gen_absif2_internal (operands[0], operands[1], label)); | 8121 emit_insn (gen_absif2_internal (operands[0], operands[1], label)); |
7980 else | 8122 else |
7981 FAIL; | 8123 FAIL; |
7982 emit_label (label); | 8124 emit_label (label); |
7983 DONE; | 8125 DONE; |
7984 }") | 8126 }) |
7985 | 8127 |
7986 (define_expand "abs<mode>2_internal" | 8128 (define_expand "abs<mode>2_internal" |
7987 [(set (match_operand:IBM128 0 "gpc_reg_operand" "") | 8129 [(set (match_operand:IBM128 0 "gpc_reg_operand") |
7988 (match_operand:IBM128 1 "gpc_reg_operand" "")) | 8130 (match_operand:IBM128 1 "gpc_reg_operand")) |
7989 (set (match_dup 3) (match_dup 5)) | 8131 (set (match_dup 3) (match_dup 5)) |
7990 (set (match_dup 5) (abs:DF (match_dup 5))) | 8132 (set (match_dup 5) (abs:DF (match_dup 5))) |
7991 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5))) | 8133 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5))) |
7992 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0)) | 8134 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0)) |
7993 (label_ref (match_operand 2 "" "")) | 8135 (label_ref (match_operand 2 "")) |
7994 (pc))) | 8136 (pc))) |
7995 (set (match_dup 6) (neg:DF (match_dup 6)))] | 8137 (set (match_dup 6) (neg:DF (match_dup 6)))] |
7996 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" | 8138 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" |
7997 " | |
7998 { | 8139 { |
7999 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); | 8140 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); |
8000 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; | 8141 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; |
8001 operands[3] = gen_reg_rtx (DFmode); | 8142 operands[3] = gen_reg_rtx (DFmode); |
8002 operands[4] = gen_reg_rtx (CCFPmode); | 8143 operands[4] = gen_reg_rtx (CCFPmode); |
8003 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word); | 8144 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word); |
8004 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word); | 8145 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word); |
8005 }") | 8146 }) |
8006 | 8147 |
8007 | 8148 |
8008 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector | 8149 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector |
8009 ;; register | 8150 ;; register |
8010 | 8151 |
8011 (define_expand "ieee_128bit_negative_zero" | 8152 (define_expand "ieee_128bit_negative_zero" |
8012 [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))] | 8153 [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))] |
8013 "TARGET_FLOAT128_TYPE" | 8154 "TARGET_FLOAT128_TYPE" |
8014 { | 8155 { |
8015 rtvec v = rtvec_alloc (16); | 8156 rtvec v = rtvec_alloc (16); |
8016 int i, high; | 8157 int i, high; |
8017 | 8158 |
8018 for (i = 0; i < 16; i++) | 8159 for (i = 0; i < 16; i++) |
8019 RTVEC_ELT (v, i) = const0_rtx; | 8160 RTVEC_ELT (v, i) = const0_rtx; |
8020 | 8161 |
8021 high = (BYTES_BIG_ENDIAN) ? 0 : 15; | 8162 high = (BYTES_BIG_ENDIAN) ? 0 : 15; |
8022 RTVEC_ELT (v, high) = GEN_INT (0x80); | 8163 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode); |
8023 | 8164 |
8024 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v)); | 8165 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v)); |
8025 DONE; | 8166 DONE; |
8026 }) | 8167 }) |
8027 | 8168 |
8126 | 8267 |
8127 ;; Float128 conversion functions. These expand to library function calls. | 8268 ;; Float128 conversion functions. These expand to library function calls. |
8128 ;; We use expand to convert from IBM double double to IEEE 128-bit | 8269 ;; We use expand to convert from IBM double double to IEEE 128-bit |
8129 ;; and trunc for the opposite. | 8270 ;; and trunc for the opposite. |
8130 (define_expand "extendiftf2" | 8271 (define_expand "extendiftf2" |
8131 [(set (match_operand:TF 0 "gpc_reg_operand" "") | 8272 [(set (match_operand:TF 0 "gpc_reg_operand") |
8132 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))] | 8273 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))] |
8133 "TARGET_FLOAT128_TYPE" | 8274 "TARGET_FLOAT128_TYPE" |
8134 { | 8275 { |
8135 rs6000_expand_float128_convert (operands[0], operands[1], false); | 8276 rs6000_expand_float128_convert (operands[0], operands[1], false); |
8136 DONE; | 8277 DONE; |
8137 }) | 8278 }) |
8138 | 8279 |
8139 (define_expand "extendifkf2" | 8280 (define_expand "extendifkf2" |
8140 [(set (match_operand:KF 0 "gpc_reg_operand" "") | 8281 [(set (match_operand:KF 0 "gpc_reg_operand") |
8141 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))] | 8282 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))] |
8142 "TARGET_FLOAT128_TYPE" | 8283 "TARGET_FLOAT128_TYPE" |
8143 { | 8284 { |
8144 rs6000_expand_float128_convert (operands[0], operands[1], false); | 8285 rs6000_expand_float128_convert (operands[0], operands[1], false); |
8145 DONE; | 8286 DONE; |
8146 }) | 8287 }) |
8147 | 8288 |
8148 (define_expand "extendtfkf2" | 8289 (define_expand "extendtfkf2" |
8149 [(set (match_operand:KF 0 "gpc_reg_operand" "") | 8290 [(set (match_operand:KF 0 "gpc_reg_operand") |
8150 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))] | 8291 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))] |
8151 "TARGET_FLOAT128_TYPE" | 8292 "TARGET_FLOAT128_TYPE" |
8152 { | 8293 { |
8153 rs6000_expand_float128_convert (operands[0], operands[1], false); | 8294 rs6000_expand_float128_convert (operands[0], operands[1], false); |
8154 DONE; | 8295 DONE; |
8155 }) | 8296 }) |
8156 | 8297 |
8157 (define_expand "trunciftf2" | 8298 (define_expand "extendtfif2" |
8158 [(set (match_operand:IF 0 "gpc_reg_operand" "") | 8299 [(set (match_operand:IF 0 "gpc_reg_operand") |
8159 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))] | 8300 (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))] |
8160 "TARGET_FLOAT128_TYPE" | 8301 "TARGET_FLOAT128_TYPE" |
8161 { | 8302 { |
8162 rs6000_expand_float128_convert (operands[0], operands[1], false); | 8303 rs6000_expand_float128_convert (operands[0], operands[1], false); |
8163 DONE; | 8304 DONE; |
8164 }) | 8305 }) |
8165 | 8306 |
8166 (define_expand "truncifkf2" | 8307 (define_expand "trunciftf2" |
8167 [(set (match_operand:IF 0 "gpc_reg_operand" "") | 8308 [(set (match_operand:TF 0 "gpc_reg_operand") |
8168 (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))] | 8309 (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))] |
8169 "TARGET_FLOAT128_TYPE" | 8310 "TARGET_FLOAT128_TYPE" |
8170 { | 8311 { |
8171 rs6000_expand_float128_convert (operands[0], operands[1], false); | 8312 rs6000_expand_float128_convert (operands[0], operands[1], false); |
8172 DONE; | 8313 DONE; |
8173 }) | 8314 }) |
8174 | 8315 |
8175 (define_expand "trunckftf2" | 8316 (define_expand "truncifkf2" |
8176 [(set (match_operand:TF 0 "gpc_reg_operand" "") | 8317 [(set (match_operand:KF 0 "gpc_reg_operand") |
8177 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))] | 8318 (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))] |
8178 "TARGET_FLOAT128_TYPE" | 8319 "TARGET_FLOAT128_TYPE" |
8179 { | 8320 { |
8180 rs6000_expand_float128_convert (operands[0], operands[1], false); | 8321 rs6000_expand_float128_convert (operands[0], operands[1], false); |
8181 DONE; | 8322 DONE; |
8182 }) | 8323 }) |
8183 | 8324 |
8184 (define_expand "trunctfif2" | 8325 (define_expand "trunckftf2" |
8185 [(set (match_operand:IF 0 "gpc_reg_operand" "") | 8326 [(set (match_operand:TF 0 "gpc_reg_operand") |
8186 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))] | 8327 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))] |
8187 "TARGET_FLOAT128_TYPE" | 8328 "TARGET_FLOAT128_TYPE" |
8188 { | 8329 { |
8189 rs6000_expand_float128_convert (operands[0], operands[1], false); | 8330 rs6000_expand_float128_convert (operands[0], operands[1], false); |
8190 DONE; | 8331 DONE; |
8332 }) | |
8333 | |
8334 (define_expand "trunctfif2" | |
8335 [(set (match_operand:IF 0 "gpc_reg_operand") | |
8336 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))] | |
8337 "TARGET_FLOAT128_TYPE" | |
8338 { | |
8339 rs6000_expand_float128_convert (operands[0], operands[1], false); | |
8340 DONE; | |
8341 }) | |
8342 | |
8343 (define_insn_and_split "*extend<mode>tf2_internal" | |
8344 [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>") | |
8345 (float_extend:TF | |
8346 (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))] | |
8347 "TARGET_FLOAT128_TYPE | |
8348 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)" | |
8349 "#" | |
8350 "&& reload_completed" | |
8351 [(set (match_dup 0) (match_dup 2))] | |
8352 { | |
8353 operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1])); | |
8354 }) | |
8355 | |
8356 (define_insn_and_split "*extendtf<mode>2_internal" | |
8357 [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>") | |
8358 (float_extend:IFKF | |
8359 (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))] | |
8360 "TARGET_FLOAT128_TYPE | |
8361 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)" | |
8362 "#" | |
8363 "&& reload_completed" | |
8364 [(set (match_dup 0) (match_dup 2))] | |
8365 { | |
8366 operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1])); | |
8191 }) | 8367 }) |
8192 | 8368 |
8193 | 8369 |
8194 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all | 8370 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all |
8195 ;; must have 3 arguments, and scratch register constraint must be a single | 8371 ;; must have 3 arguments, and scratch register constraint must be a single |
8360 } | 8536 } |
8361 [(set_attr "length" "12") | 8537 [(set_attr "length" "12") |
8362 (set_attr "type" "three")]) | 8538 (set_attr "type" "three")]) |
8363 | 8539 |
8364 (define_split | 8540 (define_split |
8365 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "") | 8541 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand") |
8366 (match_operand:FMOVE128_GPR 1 "input_operand" ""))] | 8542 (match_operand:FMOVE128_GPR 1 "input_operand"))] |
8367 "reload_completed | 8543 "reload_completed |
8368 && (int_reg_operand (operands[0], <MODE>mode) | 8544 && (int_reg_operand (operands[0], <MODE>mode) |
8369 || int_reg_operand (operands[1], <MODE>mode)) | 8545 || int_reg_operand (operands[1], <MODE>mode)) |
8370 && (!TARGET_DIRECT_MOVE_128 | 8546 && (!TARGET_DIRECT_MOVE_128 |
8371 || (!vsx_register_operand (operands[0], <MODE>mode) | 8547 || (!vsx_register_operand (operands[0], <MODE>mode) |
8485 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const | 8661 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const |
8486 ;; AVX const | 8662 ;; AVX const |
8487 | 8663 |
8488 (define_insn "*movdi_internal32" | 8664 (define_insn "*movdi_internal32" |
8489 [(set (match_operand:DI 0 "nonimmediate_operand" | 8665 [(set (match_operand:DI 0 "nonimmediate_operand" |
8490 "=Y, r, r, ^m, ^d, ^d, | 8666 "=Y, r, r, m, ^d, ^d, |
8491 r, ^wY, $Z, ^wb, $wv, ^wi, | 8667 r, wY, Z, ^wb, $wv, ^wi, |
8492 *wo, *wo, *wv, *wi, *wi, *wv, | 8668 *wo, *wo, *wv, *wi, *wi, *wv, |
8493 *wv") | 8669 *wv") |
8494 | 8670 |
8495 (match_operand:DI 1 "input_operand" | 8671 (match_operand:DI 1 "input_operand" |
8496 "r, Y, r, d, m, d, | 8672 "r, Y, r, ^d, m, ^d, |
8497 IJKnGHF, wb, wv, wY, Z, wi, | 8673 IJKnGHF, ^wb, $wv, wY, Z, ^wi, |
8498 Oj, wM, OjwM, Oj, wM, wS, | 8674 Oj, wM, OjwM, Oj, wM, wS, |
8499 wB"))] | 8675 wB"))] |
8500 | 8676 |
8501 "! TARGET_POWERPC64 | 8677 "! TARGET_POWERPC64 |
8502 && (gpc_reg_operand (operands[0], DImode) | 8678 && (gpc_reg_operand (operands[0], DImode) |
8503 || gpc_reg_operand (operands[1], DImode))" | 8679 || gpc_reg_operand (operands[1], DImode))" |
8504 "@ | 8680 "@ |
8527 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple, | 8703 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple, |
8528 vecsimple") | 8704 vecsimple") |
8529 (set_attr "size" "64")]) | 8705 (set_attr "size" "64")]) |
8530 | 8706 |
8531 (define_split | 8707 (define_split |
8532 [(set (match_operand:DI 0 "gpc_reg_operand" "") | 8708 [(set (match_operand:DI 0 "gpc_reg_operand") |
8533 (match_operand:DI 1 "const_int_operand" ""))] | 8709 (match_operand:DI 1 "const_int_operand"))] |
8534 "! TARGET_POWERPC64 && reload_completed | 8710 "! TARGET_POWERPC64 && reload_completed |
8535 && gpr_or_gpr_p (operands[0], operands[1]) | 8711 && gpr_or_gpr_p (operands[0], operands[1]) |
8536 && !direct_move_p (operands[0], operands[1])" | 8712 && !direct_move_p (operands[0], operands[1])" |
8537 [(set (match_dup 2) (match_dup 4)) | 8713 [(set (match_dup 2) (match_dup 4)) |
8538 (set (match_dup 3) (match_dup 1))] | 8714 (set (match_dup 3) (match_dup 1))] |
8539 " | |
8540 { | 8715 { |
8541 HOST_WIDE_INT value = INTVAL (operands[1]); | 8716 HOST_WIDE_INT value = INTVAL (operands[1]); |
8542 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0, | 8717 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0, |
8543 DImode); | 8718 DImode); |
8544 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0, | 8719 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0, |
8545 DImode); | 8720 DImode); |
8546 operands[4] = GEN_INT (value >> 32); | 8721 operands[4] = GEN_INT (value >> 32); |
8547 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); | 8722 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); |
8548 }") | 8723 }) |
8549 | 8724 |
8550 (define_split | 8725 (define_split |
8551 [(set (match_operand:DIFD 0 "nonimmediate_operand" "") | 8726 [(set (match_operand:DIFD 0 "nonimmediate_operand") |
8552 (match_operand:DIFD 1 "input_operand" ""))] | 8727 (match_operand:DIFD 1 "input_operand"))] |
8553 "reload_completed && !TARGET_POWERPC64 | 8728 "reload_completed && !TARGET_POWERPC64 |
8554 && gpr_or_gpr_p (operands[0], operands[1]) | 8729 && gpr_or_gpr_p (operands[0], operands[1]) |
8555 && !direct_move_p (operands[0], operands[1])" | 8730 && !direct_move_p (operands[0], operands[1])" |
8556 [(pc)] | 8731 [(pc)] |
8557 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) | 8732 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) |
8561 ;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0 | 8736 ;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0 |
8562 ;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR | 8737 ;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR |
8563 ;; FPR->GPR GPR->FPR VSX->GPR GPR->VSX | 8738 ;; FPR->GPR GPR->FPR VSX->GPR GPR->VSX |
8564 (define_insn "*movdi_internal64" | 8739 (define_insn "*movdi_internal64" |
8565 [(set (match_operand:DI 0 "nonimmediate_operand" | 8740 [(set (match_operand:DI 0 "nonimmediate_operand" |
8566 "=Y, r, r, r, r, r, | 8741 "=YZ, r, r, r, r, r, |
8567 ^m, ^d, ^d, ^wY, $Z, $wb, | 8742 m, ^d, ^d, wY, Z, $wb, |
8568 $wv, ^wi, *wo, *wo, *wv, *wi, | 8743 $wv, ^wi, *wo, *wo, *wv, *wi, |
8569 *wi, *wv, *wv, r, *h, *h, | 8744 *wi, *wv, *wv, r, *h, *h, |
8570 ?*r, ?*wg, ?*r, ?*wj") | 8745 ?*r, ?*wg, ?*r, ?*wj") |
8571 | 8746 |
8572 (match_operand:DI 1 "input_operand" | 8747 (match_operand:DI 1 "input_operand" |
8573 "r, Y, r, I, L, nF, | 8748 "r, YZ, r, I, L, nF, |
8574 d, m, d, wb, wv, wY, | 8749 ^d, m, ^d, ^wb, $wv, wY, |
8575 Z, wi, Oj, wM, OjwM, Oj, | 8750 Z, ^wi, Oj, wM, OjwM, Oj, |
8576 wM, wS, wB, *h, r, 0, | 8751 wM, wS, wB, *h, r, 0, |
8577 wg, r, wj, r"))] | 8752 wg, r, wj, r"))] |
8578 | 8753 |
8579 "TARGET_POWERPC64 | 8754 "TARGET_POWERPC64 |
8580 && (gpc_reg_operand (operands[0], DImode) | 8755 && (gpc_reg_operand (operands[0], DImode) |
8581 || gpc_reg_operand (operands[1], DImode))" | 8756 || gpc_reg_operand (operands[1], DImode))" |
8582 "@ | 8757 "@ |
8642 ;; Split a load of a large constant into the appropriate five-instruction | 8817 ;; Split a load of a large constant into the appropriate five-instruction |
8643 ;; sequence. Handle anything in a constant number of insns. | 8818 ;; sequence. Handle anything in a constant number of insns. |
8644 ;; When non-easy constants can go in the TOC, this should use | 8819 ;; When non-easy constants can go in the TOC, this should use |
8645 ;; easy_fp_constant predicate. | 8820 ;; easy_fp_constant predicate. |
8646 (define_split | 8821 (define_split |
8647 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "") | 8822 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo") |
8648 (match_operand:DI 1 "const_int_operand" ""))] | 8823 (match_operand:DI 1 "const_int_operand"))] |
8649 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1" | 8824 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1" |
8650 [(set (match_dup 0) (match_dup 2)) | 8825 [(set (match_dup 0) (match_dup 2)) |
8651 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] | 8826 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] |
8652 " | |
8653 { | 8827 { |
8654 if (rs6000_emit_set_const (operands[0], operands[1])) | 8828 if (rs6000_emit_set_const (operands[0], operands[1])) |
8655 DONE; | 8829 DONE; |
8656 else | 8830 else |
8657 FAIL; | 8831 FAIL; |
8658 }") | 8832 }) |
8659 | 8833 |
8660 (define_split | 8834 (define_split |
8661 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "") | 8835 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo") |
8662 (match_operand:DI 1 "const_scalar_int_operand" ""))] | 8836 (match_operand:DI 1 "const_scalar_int_operand"))] |
8663 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1" | 8837 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1" |
8664 [(set (match_dup 0) (match_dup 2)) | 8838 [(set (match_dup 0) (match_dup 2)) |
8665 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] | 8839 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] |
8666 " | |
8667 { | 8840 { |
8668 if (rs6000_emit_set_const (operands[0], operands[1])) | 8841 if (rs6000_emit_set_const (operands[0], operands[1])) |
8669 DONE; | 8842 DONE; |
8670 else | 8843 else |
8671 FAIL; | 8844 FAIL; |
8672 }") | 8845 }) |
8673 | 8846 |
8674 (define_split | 8847 (define_split |
8675 [(set (match_operand:DI 0 "altivec_register_operand" "") | 8848 [(set (match_operand:DI 0 "altivec_register_operand") |
8676 (match_operand:DI 1 "s5bit_cint_operand" ""))] | 8849 (match_operand:DI 1 "s5bit_cint_operand"))] |
8677 "TARGET_VSX && reload_completed" | 8850 "TARGET_VSX && reload_completed" |
8678 [(const_int 0)] | 8851 [(const_int 0)] |
8679 { | 8852 { |
8680 rtx op0 = operands[0]; | 8853 rtx op0 = operands[0]; |
8681 rtx op1 = operands[1]; | 8854 rtx op1 = operands[1]; |
8692 }) | 8865 }) |
8693 | 8866 |
8694 ;; Split integer constants that can be loaded with XXSPLTIB and a | 8867 ;; Split integer constants that can be loaded with XXSPLTIB and a |
8695 ;; sign extend operation. | 8868 ;; sign extend operation. |
8696 (define_split | 8869 (define_split |
8697 [(set (match_operand:INT_ISA3 0 "altivec_register_operand" "") | 8870 [(set (match_operand:INT_ISA3 0 "altivec_register_operand") |
8698 (match_operand:INT_ISA3 1 "xxspltib_constant_split" ""))] | 8871 (match_operand:INT_ISA3 1 "xxspltib_constant_split"))] |
8699 "TARGET_P9_VECTOR && reload_completed" | 8872 "TARGET_P9_VECTOR && reload_completed" |
8700 [(const_int 0)] | 8873 [(const_int 0)] |
8701 { | 8874 { |
8702 rtx op0 = operands[0]; | 8875 rtx op0 = operands[0]; |
8703 rtx op1 = operands[1]; | 8876 rtx op1 = operands[1]; |
8726 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))] | 8899 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))] |
8727 "! TARGET_POWERPC64 | 8900 "! TARGET_POWERPC64 |
8728 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode)) | 8901 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode)) |
8729 && (gpc_reg_operand (operands[0], <MODE>mode) | 8902 && (gpc_reg_operand (operands[0], <MODE>mode) |
8730 || gpc_reg_operand (operands[1], <MODE>mode))" | 8903 || gpc_reg_operand (operands[1], <MODE>mode))" |
8731 "* | 8904 "#" |
8732 { | |
8733 switch (which_alternative) | |
8734 { | |
8735 default: | |
8736 gcc_unreachable (); | |
8737 case 0: | |
8738 if (TARGET_STRING) | |
8739 return \"stswi %1,%P0,16\"; | |
8740 /* FALLTHRU */ | |
8741 case 1: | |
8742 return \"#\"; | |
8743 case 2: | |
8744 /* If the address is not used in the output, we can use lsi. Otherwise, | |
8745 fall through to generating four loads. */ | |
8746 if (TARGET_STRING | |
8747 && ! reg_overlap_mentioned_p (operands[0], operands[1])) | |
8748 return \"lswi %0,%P1,16\"; | |
8749 /* fall through */ | |
8750 case 3: | |
8751 case 4: | |
8752 case 5: | |
8753 return \"#\"; | |
8754 } | |
8755 }" | |
8756 [(set_attr "type" "store,store,load,load,*,*") | 8905 [(set_attr "type" "store,store,load,load,*,*") |
8757 (set_attr "update" "yes") | 8906 (set_attr "update" "yes") |
8758 (set_attr "indexed" "yes") | 8907 (set_attr "indexed" "yes") |
8759 (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING") | 8908 (set_attr "cell_micro" "conditional")]) |
8760 (const_string "always") | |
8761 (const_string "conditional")))]) | |
8762 | 8909 |
8763 (define_insn "*mov<mode>_ppc64" | 8910 (define_insn "*mov<mode>_ppc64" |
8764 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r") | 8911 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r") |
8765 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))] | 8912 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))] |
8766 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode) | 8913 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode) |
8771 } | 8918 } |
8772 [(set_attr "type" "store,store,load,load,*,*") | 8919 [(set_attr "type" "store,store,load,load,*,*") |
8773 (set_attr "length" "8")]) | 8920 (set_attr "length" "8")]) |
8774 | 8921 |
8775 (define_split | 8922 (define_split |
8776 [(set (match_operand:TI2 0 "int_reg_operand" "") | 8923 [(set (match_operand:TI2 0 "int_reg_operand") |
8777 (match_operand:TI2 1 "const_scalar_int_operand" ""))] | 8924 (match_operand:TI2 1 "const_scalar_int_operand"))] |
8778 "TARGET_POWERPC64 | 8925 "TARGET_POWERPC64 |
8779 && (VECTOR_MEM_NONE_P (<MODE>mode) | 8926 && (VECTOR_MEM_NONE_P (<MODE>mode) |
8780 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))" | 8927 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))" |
8781 [(set (match_dup 2) (match_dup 4)) | 8928 [(set (match_dup 2) (match_dup 4)) |
8782 (set (match_dup 3) (match_dup 5))] | 8929 (set (match_dup 3) (match_dup 5))] |
8783 " | |
8784 { | 8930 { |
8785 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0, | 8931 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0, |
8786 <MODE>mode); | 8932 <MODE>mode); |
8787 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0, | 8933 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0, |
8788 <MODE>mode); | 8934 <MODE>mode); |
8796 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0)); | 8942 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0)); |
8797 operands[5] = operands[1]; | 8943 operands[5] = operands[1]; |
8798 } | 8944 } |
8799 else | 8945 else |
8800 FAIL; | 8946 FAIL; |
8801 }") | 8947 }) |
8802 | 8948 |
8803 (define_split | 8949 (define_split |
8804 [(set (match_operand:TI2 0 "nonimmediate_operand" "") | 8950 [(set (match_operand:TI2 0 "nonimmediate_operand") |
8805 (match_operand:TI2 1 "input_operand" ""))] | 8951 (match_operand:TI2 1 "input_operand"))] |
8806 "reload_completed | 8952 "reload_completed |
8807 && gpr_or_gpr_p (operands[0], operands[1]) | 8953 && gpr_or_gpr_p (operands[0], operands[1]) |
8808 && !direct_move_p (operands[0], operands[1]) | 8954 && !direct_move_p (operands[0], operands[1]) |
8809 && !quad_load_store_p (operands[0], operands[1])" | 8955 && !quad_load_store_p (operands[0], operands[1])" |
8810 [(pc)] | 8956 [(pc)] |
8811 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) | 8957 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) |
8812 | 8958 |
8813 (define_expand "load_multiple" | |
8814 [(match_par_dup 3 [(set (match_operand:SI 0 "" "") | |
8815 (match_operand:SI 1 "" "")) | |
8816 (use (match_operand:SI 2 "" ""))])] | |
8817 "TARGET_STRING && !TARGET_POWERPC64" | |
8818 " | |
8819 { | |
8820 int regno; | |
8821 int count; | |
8822 rtx op1; | |
8823 int i; | |
8824 | |
8825 /* Support only loading a constant number of fixed-point registers from | |
8826 memory and only bother with this if more than two; the machine | |
8827 doesn't support more than eight. */ | |
8828 if (GET_CODE (operands[2]) != CONST_INT | |
8829 || INTVAL (operands[2]) <= 2 | |
8830 || INTVAL (operands[2]) > 8 | |
8831 || GET_CODE (operands[1]) != MEM | |
8832 || GET_CODE (operands[0]) != REG | |
8833 || REGNO (operands[0]) >= 32) | |
8834 FAIL; | |
8835 | |
8836 count = INTVAL (operands[2]); | |
8837 regno = REGNO (operands[0]); | |
8838 | |
8839 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count)); | |
8840 op1 = replace_equiv_address (operands[1], | |
8841 force_reg (SImode, XEXP (operands[1], 0))); | |
8842 | |
8843 for (i = 0; i < count; i++) | |
8844 XVECEXP (operands[3], 0, i) | |
8845 = gen_rtx_SET (gen_rtx_REG (SImode, regno + i), | |
8846 adjust_address_nv (op1, SImode, i * 4)); | |
8847 }") | |
8848 | |
8849 (define_insn "*ldmsi8" | |
8850 [(match_parallel 0 "load_multiple_operation" | |
8851 [(set (match_operand:SI 2 "gpc_reg_operand" "") | |
8852 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) | |
8853 (set (match_operand:SI 3 "gpc_reg_operand" "") | |
8854 (mem:SI (plus:SI (match_dup 1) (const_int 4)))) | |
8855 (set (match_operand:SI 4 "gpc_reg_operand" "") | |
8856 (mem:SI (plus:SI (match_dup 1) (const_int 8)))) | |
8857 (set (match_operand:SI 5 "gpc_reg_operand" "") | |
8858 (mem:SI (plus:SI (match_dup 1) (const_int 12)))) | |
8859 (set (match_operand:SI 6 "gpc_reg_operand" "") | |
8860 (mem:SI (plus:SI (match_dup 1) (const_int 16)))) | |
8861 (set (match_operand:SI 7 "gpc_reg_operand" "") | |
8862 (mem:SI (plus:SI (match_dup 1) (const_int 20)))) | |
8863 (set (match_operand:SI 8 "gpc_reg_operand" "") | |
8864 (mem:SI (plus:SI (match_dup 1) (const_int 24)))) | |
8865 (set (match_operand:SI 9 "gpc_reg_operand" "") | |
8866 (mem:SI (plus:SI (match_dup 1) (const_int 28))))])] | |
8867 "TARGET_STRING && XVECLEN (operands[0], 0) == 8" | |
8868 "* | |
8869 { return rs6000_output_load_multiple (operands); }" | |
8870 [(set_attr "type" "load") | |
8871 (set_attr "update" "yes") | |
8872 (set_attr "indexed" "yes") | |
8873 (set_attr "length" "32")]) | |
8874 | |
8875 (define_insn "*ldmsi7" | |
8876 [(match_parallel 0 "load_multiple_operation" | |
8877 [(set (match_operand:SI 2 "gpc_reg_operand" "") | |
8878 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) | |
8879 (set (match_operand:SI 3 "gpc_reg_operand" "") | |
8880 (mem:SI (plus:SI (match_dup 1) (const_int 4)))) | |
8881 (set (match_operand:SI 4 "gpc_reg_operand" "") | |
8882 (mem:SI (plus:SI (match_dup 1) (const_int 8)))) | |
8883 (set (match_operand:SI 5 "gpc_reg_operand" "") | |
8884 (mem:SI (plus:SI (match_dup 1) (const_int 12)))) | |
8885 (set (match_operand:SI 6 "gpc_reg_operand" "") | |
8886 (mem:SI (plus:SI (match_dup 1) (const_int 16)))) | |
8887 (set (match_operand:SI 7 "gpc_reg_operand" "") | |
8888 (mem:SI (plus:SI (match_dup 1) (const_int 20)))) | |
8889 (set (match_operand:SI 8 "gpc_reg_operand" "") | |
8890 (mem:SI (plus:SI (match_dup 1) (const_int 24))))])] | |
8891 "TARGET_STRING && XVECLEN (operands[0], 0) == 7" | |
8892 "* | |
8893 { return rs6000_output_load_multiple (operands); }" | |
8894 [(set_attr "type" "load") | |
8895 (set_attr "update" "yes") | |
8896 (set_attr "indexed" "yes") | |
8897 (set_attr "length" "32")]) | |
8898 | |
8899 (define_insn "*ldmsi6" | |
8900 [(match_parallel 0 "load_multiple_operation" | |
8901 [(set (match_operand:SI 2 "gpc_reg_operand" "") | |
8902 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) | |
8903 (set (match_operand:SI 3 "gpc_reg_operand" "") | |
8904 (mem:SI (plus:SI (match_dup 1) (const_int 4)))) | |
8905 (set (match_operand:SI 4 "gpc_reg_operand" "") | |
8906 (mem:SI (plus:SI (match_dup 1) (const_int 8)))) | |
8907 (set (match_operand:SI 5 "gpc_reg_operand" "") | |
8908 (mem:SI (plus:SI (match_dup 1) (const_int 12)))) | |
8909 (set (match_operand:SI 6 "gpc_reg_operand" "") | |
8910 (mem:SI (plus:SI (match_dup 1) (const_int 16)))) | |
8911 (set (match_operand:SI 7 "gpc_reg_operand" "") | |
8912 (mem:SI (plus:SI (match_dup 1) (const_int 20))))])] | |
8913 "TARGET_STRING && XVECLEN (operands[0], 0) == 6" | |
8914 "* | |
8915 { return rs6000_output_load_multiple (operands); }" | |
8916 [(set_attr "type" "load") | |
8917 (set_attr "update" "yes") | |
8918 (set_attr "indexed" "yes") | |
8919 (set_attr "length" "32")]) | |
8920 | |
8921 (define_insn "*ldmsi5" | |
8922 [(match_parallel 0 "load_multiple_operation" | |
8923 [(set (match_operand:SI 2 "gpc_reg_operand" "") | |
8924 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) | |
8925 (set (match_operand:SI 3 "gpc_reg_operand" "") | |
8926 (mem:SI (plus:SI (match_dup 1) (const_int 4)))) | |
8927 (set (match_operand:SI 4 "gpc_reg_operand" "") | |
8928 (mem:SI (plus:SI (match_dup 1) (const_int 8)))) | |
8929 (set (match_operand:SI 5 "gpc_reg_operand" "") | |
8930 (mem:SI (plus:SI (match_dup 1) (const_int 12)))) | |
8931 (set (match_operand:SI 6 "gpc_reg_operand" "") | |
8932 (mem:SI (plus:SI (match_dup 1) (const_int 16))))])] | |
8933 "TARGET_STRING && XVECLEN (operands[0], 0) == 5" | |
8934 "* | |
8935 { return rs6000_output_load_multiple (operands); }" | |
8936 [(set_attr "type" "load") | |
8937 (set_attr "update" "yes") | |
8938 (set_attr "indexed" "yes") | |
8939 (set_attr "length" "32")]) | |
8940 | |
8941 (define_insn "*ldmsi4" | |
8942 [(match_parallel 0 "load_multiple_operation" | |
8943 [(set (match_operand:SI 2 "gpc_reg_operand" "") | |
8944 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) | |
8945 (set (match_operand:SI 3 "gpc_reg_operand" "") | |
8946 (mem:SI (plus:SI (match_dup 1) (const_int 4)))) | |
8947 (set (match_operand:SI 4 "gpc_reg_operand" "") | |
8948 (mem:SI (plus:SI (match_dup 1) (const_int 8)))) | |
8949 (set (match_operand:SI 5 "gpc_reg_operand" "") | |
8950 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])] | |
8951 "TARGET_STRING && XVECLEN (operands[0], 0) == 4" | |
8952 "* | |
8953 { return rs6000_output_load_multiple (operands); }" | |
8954 [(set_attr "type" "load") | |
8955 (set_attr "update" "yes") | |
8956 (set_attr "indexed" "yes") | |
8957 (set_attr "length" "32")]) | |
8958 | |
8959 (define_insn "*ldmsi3" | |
8960 [(match_parallel 0 "load_multiple_operation" | |
8961 [(set (match_operand:SI 2 "gpc_reg_operand" "") | |
8962 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) | |
8963 (set (match_operand:SI 3 "gpc_reg_operand" "") | |
8964 (mem:SI (plus:SI (match_dup 1) (const_int 4)))) | |
8965 (set (match_operand:SI 4 "gpc_reg_operand" "") | |
8966 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])] | |
8967 "TARGET_STRING && XVECLEN (operands[0], 0) == 3" | |
8968 "* | |
8969 { return rs6000_output_load_multiple (operands); }" | |
8970 [(set_attr "type" "load") | |
8971 (set_attr "update" "yes") | |
8972 (set_attr "indexed" "yes") | |
8973 (set_attr "length" "32")]) | |
8974 | |
8975 (define_expand "store_multiple" | |
8976 [(match_par_dup 3 [(set (match_operand:SI 0 "" "") | |
8977 (match_operand:SI 1 "" "")) | |
8978 (clobber (scratch:SI)) | |
8979 (use (match_operand:SI 2 "" ""))])] | |
8980 "TARGET_STRING && !TARGET_POWERPC64" | |
8981 " | |
8982 { | |
8983 int regno; | |
8984 int count; | |
8985 rtx to; | |
8986 rtx op0; | |
8987 int i; | |
8988 | |
8989 /* Support only storing a constant number of fixed-point registers to | |
8990 memory and only bother with this if more than two; the machine | |
8991 doesn't support more than eight. */ | |
8992 if (GET_CODE (operands[2]) != CONST_INT | |
8993 || INTVAL (operands[2]) <= 2 | |
8994 || INTVAL (operands[2]) > 8 | |
8995 || GET_CODE (operands[0]) != MEM | |
8996 || GET_CODE (operands[1]) != REG | |
8997 || REGNO (operands[1]) >= 32) | |
8998 FAIL; | |
8999 | |
9000 count = INTVAL (operands[2]); | |
9001 regno = REGNO (operands[1]); | |
9002 | |
9003 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1)); | |
9004 to = force_reg (SImode, XEXP (operands[0], 0)); | |
9005 op0 = replace_equiv_address (operands[0], to); | |
9006 | |
9007 XVECEXP (operands[3], 0, 0) | |
9008 = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]); | |
9009 XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode, | |
9010 gen_rtx_SCRATCH (SImode)); | |
9011 | |
9012 for (i = 1; i < count; i++) | |
9013 XVECEXP (operands[3], 0, i + 1) | |
9014 = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4), | |
9015 gen_rtx_REG (SImode, regno + i)); | |
9016 }") | |
9017 | |
9018 (define_insn "*stmsi8" | |
9019 [(match_parallel 0 "store_multiple_operation" | |
9020 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")) | |
9021 (match_operand:SI 2 "gpc_reg_operand" "r")) | |
9022 (clobber (match_scratch:SI 3 "=X")) | |
9023 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) | |
9024 (match_operand:SI 4 "gpc_reg_operand" "r")) | |
9025 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) | |
9026 (match_operand:SI 5 "gpc_reg_operand" "r")) | |
9027 (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) | |
9028 (match_operand:SI 6 "gpc_reg_operand" "r")) | |
9029 (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) | |
9030 (match_operand:SI 7 "gpc_reg_operand" "r")) | |
9031 (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) | |
9032 (match_operand:SI 8 "gpc_reg_operand" "r")) | |
9033 (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) | |
9034 (match_operand:SI 9 "gpc_reg_operand" "r")) | |
9035 (set (mem:SI (plus:SI (match_dup 1) (const_int 28))) | |
9036 (match_operand:SI 10 "gpc_reg_operand" "r"))])] | |
9037 "TARGET_STRING && XVECLEN (operands[0], 0) == 9" | |
9038 "stswi %2,%1,%O0" | |
9039 [(set_attr "type" "store") | |
9040 (set_attr "update" "yes") | |
9041 (set_attr "indexed" "yes") | |
9042 (set_attr "cell_micro" "always")]) | |
9043 | |
9044 (define_insn "*stmsi7" | |
9045 [(match_parallel 0 "store_multiple_operation" | |
9046 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")) | |
9047 (match_operand:SI 2 "gpc_reg_operand" "r")) | |
9048 (clobber (match_scratch:SI 3 "=X")) | |
9049 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) | |
9050 (match_operand:SI 4 "gpc_reg_operand" "r")) | |
9051 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) | |
9052 (match_operand:SI 5 "gpc_reg_operand" "r")) | |
9053 (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) | |
9054 (match_operand:SI 6 "gpc_reg_operand" "r")) | |
9055 (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) | |
9056 (match_operand:SI 7 "gpc_reg_operand" "r")) | |
9057 (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) | |
9058 (match_operand:SI 8 "gpc_reg_operand" "r")) | |
9059 (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) | |
9060 (match_operand:SI 9 "gpc_reg_operand" "r"))])] | |
9061 "TARGET_STRING && XVECLEN (operands[0], 0) == 8" | |
9062 "stswi %2,%1,%O0" | |
9063 [(set_attr "type" "store") | |
9064 (set_attr "update" "yes") | |
9065 (set_attr "indexed" "yes") | |
9066 (set_attr "cell_micro" "always")]) | |
9067 | |
9068 (define_insn "*stmsi6" | |
9069 [(match_parallel 0 "store_multiple_operation" | |
9070 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")) | |
9071 (match_operand:SI 2 "gpc_reg_operand" "r")) | |
9072 (clobber (match_scratch:SI 3 "=X")) | |
9073 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) | |
9074 (match_operand:SI 4 "gpc_reg_operand" "r")) | |
9075 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) | |
9076 (match_operand:SI 5 "gpc_reg_operand" "r")) | |
9077 (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) | |
9078 (match_operand:SI 6 "gpc_reg_operand" "r")) | |
9079 (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) | |
9080 (match_operand:SI 7 "gpc_reg_operand" "r")) | |
9081 (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) | |
9082 (match_operand:SI 8 "gpc_reg_operand" "r"))])] | |
9083 "TARGET_STRING && XVECLEN (operands[0], 0) == 7" | |
9084 "stswi %2,%1,%O0" | |
9085 [(set_attr "type" "store") | |
9086 (set_attr "update" "yes") | |
9087 (set_attr "indexed" "yes") | |
9088 (set_attr "cell_micro" "always")]) | |
9089 | |
9090 (define_insn "*stmsi5" | |
9091 [(match_parallel 0 "store_multiple_operation" | |
9092 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")) | |
9093 (match_operand:SI 2 "gpc_reg_operand" "r")) | |
9094 (clobber (match_scratch:SI 3 "=X")) | |
9095 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) | |
9096 (match_operand:SI 4 "gpc_reg_operand" "r")) | |
9097 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) | |
9098 (match_operand:SI 5 "gpc_reg_operand" "r")) | |
9099 (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) | |
9100 (match_operand:SI 6 "gpc_reg_operand" "r")) | |
9101 (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) | |
9102 (match_operand:SI 7 "gpc_reg_operand" "r"))])] | |
9103 "TARGET_STRING && XVECLEN (operands[0], 0) == 6" | |
9104 "stswi %2,%1,%O0" | |
9105 [(set_attr "type" "store") | |
9106 (set_attr "update" "yes") | |
9107 (set_attr "indexed" "yes") | |
9108 (set_attr "cell_micro" "always")]) | |
9109 | |
9110 (define_insn "*stmsi4" | |
9111 [(match_parallel 0 "store_multiple_operation" | |
9112 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")) | |
9113 (match_operand:SI 2 "gpc_reg_operand" "r")) | |
9114 (clobber (match_scratch:SI 3 "=X")) | |
9115 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) | |
9116 (match_operand:SI 4 "gpc_reg_operand" "r")) | |
9117 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) | |
9118 (match_operand:SI 5 "gpc_reg_operand" "r")) | |
9119 (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) | |
9120 (match_operand:SI 6 "gpc_reg_operand" "r"))])] | |
9121 "TARGET_STRING && XVECLEN (operands[0], 0) == 5" | |
9122 "stswi %2,%1,%O0" | |
9123 [(set_attr "type" "store") | |
9124 (set_attr "update" "yes") | |
9125 (set_attr "indexed" "yes") | |
9126 (set_attr "cell_micro" "always")]) | |
9127 | |
9128 (define_insn "*stmsi3" | |
9129 [(match_parallel 0 "store_multiple_operation" | |
9130 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")) | |
9131 (match_operand:SI 2 "gpc_reg_operand" "r")) | |
9132 (clobber (match_scratch:SI 3 "=X")) | |
9133 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) | |
9134 (match_operand:SI 4 "gpc_reg_operand" "r")) | |
9135 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) | |
9136 (match_operand:SI 5 "gpc_reg_operand" "r"))])] | |
9137 "TARGET_STRING && XVECLEN (operands[0], 0) == 4" | |
9138 "stswi %2,%1,%O0" | |
9139 [(set_attr "type" "store") | |
9140 (set_attr "update" "yes") | |
9141 (set_attr "indexed" "yes") | |
9142 (set_attr "cell_micro" "always")]) | |
9143 | |
9144 (define_expand "setmemsi" | 8959 (define_expand "setmemsi" |
9145 [(parallel [(set (match_operand:BLK 0 "" "") | 8960 [(parallel [(set (match_operand:BLK 0 "") |
9146 (match_operand 2 "const_int_operand" "")) | 8961 (match_operand 2 "const_int_operand")) |
9147 (use (match_operand:SI 1 "" "")) | 8962 (use (match_operand:SI 1 "")) |
9148 (use (match_operand:SI 3 "" ""))])] | 8963 (use (match_operand:SI 3 ""))])] |
9149 "" | 8964 "" |
9150 " | |
9151 { | 8965 { |
9152 /* If value to set is not zero, use the library routine. */ | 8966 /* If value to set is not zero, use the library routine. */ |
9153 if (operands[2] != const0_rtx) | 8967 if (operands[2] != const0_rtx) |
9154 FAIL; | 8968 FAIL; |
9155 | 8969 |
9156 if (expand_block_clear (operands)) | 8970 if (expand_block_clear (operands)) |
9157 DONE; | 8971 DONE; |
9158 else | 8972 else |
9159 FAIL; | 8973 FAIL; |
9160 }") | 8974 }) |
9161 | 8975 |
9162 ;; String compare N insn. | 8976 ;; String compare N insn. |
9163 ;; Argument 0 is the target (result) | 8977 ;; Argument 0 is the target (result) |
9164 ;; Argument 1 is the destination | 8978 ;; Argument 1 is the destination |
9165 ;; Argument 2 is the source | 8979 ;; Argument 2 is the source |
9231 ;; Argument 1 is the source | 9045 ;; Argument 1 is the source |
9232 ;; Argument 2 is the length | 9046 ;; Argument 2 is the length |
9233 ;; Argument 3 is the alignment | 9047 ;; Argument 3 is the alignment |
9234 | 9048 |
9235 (define_expand "movmemsi" | 9049 (define_expand "movmemsi" |
9236 [(parallel [(set (match_operand:BLK 0 "" "") | 9050 [(parallel [(set (match_operand:BLK 0 "") |
9237 (match_operand:BLK 1 "" "")) | 9051 (match_operand:BLK 1 "")) |
9238 (use (match_operand:SI 2 "" "")) | 9052 (use (match_operand:SI 2 "")) |
9239 (use (match_operand:SI 3 "" ""))])] | 9053 (use (match_operand:SI 3 ""))])] |
9240 "" | 9054 "" |
9241 " | |
9242 { | 9055 { |
9243 if (expand_block_move (operands)) | 9056 if (expand_block_move (operands)) |
9244 DONE; | 9057 DONE; |
9245 else | 9058 else |
9246 FAIL; | 9059 FAIL; |
9247 }") | 9060 }) |
9248 | |
9249 ;; Move up to 32 bytes at a time. The fixed registers are needed because the | |
9250 ;; register allocator doesn't have a clue about allocating 8 word registers. | |
9251 ;; rD/rS = r5 is preferred, efficient form. | |
9252 (define_expand "movmemsi_8reg" | |
9253 [(parallel [(set (match_operand 0 "" "") | |
9254 (match_operand 1 "" "")) | |
9255 (use (match_operand 2 "" "")) | |
9256 (use (match_operand 3 "" "")) | |
9257 (clobber (reg:SI 5)) | |
9258 (clobber (reg:SI 6)) | |
9259 (clobber (reg:SI 7)) | |
9260 (clobber (reg:SI 8)) | |
9261 (clobber (reg:SI 9)) | |
9262 (clobber (reg:SI 10)) | |
9263 (clobber (reg:SI 11)) | |
9264 (clobber (reg:SI 12)) | |
9265 (clobber (match_scratch:SI 4 ""))])] | |
9266 "TARGET_STRING" | |
9267 "") | |
9268 | |
9269 (define_insn "" | |
9270 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b")) | |
9271 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b"))) | |
9272 (use (match_operand:SI 2 "immediate_operand" "i")) | |
9273 (use (match_operand:SI 3 "immediate_operand" "i")) | |
9274 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r")) | |
9275 (clobber (reg:SI 6)) | |
9276 (clobber (reg:SI 7)) | |
9277 (clobber (reg:SI 8)) | |
9278 (clobber (reg:SI 9)) | |
9279 (clobber (reg:SI 10)) | |
9280 (clobber (reg:SI 11)) | |
9281 (clobber (reg:SI 12)) | |
9282 (clobber (match_scratch:SI 5 "=X"))] | |
9283 "TARGET_STRING | |
9284 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) | |
9285 || INTVAL (operands[2]) == 0) | |
9286 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12) | |
9287 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12) | |
9288 && REGNO (operands[4]) == 5" | |
9289 "lswi %4,%1,%2\;stswi %4,%0,%2" | |
9290 [(set_attr "type" "store") | |
9291 (set_attr "update" "yes") | |
9292 (set_attr "indexed" "yes") | |
9293 (set_attr "cell_micro" "always") | |
9294 (set_attr "length" "8")]) | |
9295 | |
9296 ;; Move up to 24 bytes at a time. The fixed registers are needed because the | |
9297 ;; register allocator doesn't have a clue about allocating 6 word registers. | |
9298 ;; rD/rS = r5 is preferred, efficient form. | |
9299 (define_expand "movmemsi_6reg" | |
9300 [(parallel [(set (match_operand 0 "" "") | |
9301 (match_operand 1 "" "")) | |
9302 (use (match_operand 2 "" "")) | |
9303 (use (match_operand 3 "" "")) | |
9304 (clobber (reg:SI 5)) | |
9305 (clobber (reg:SI 6)) | |
9306 (clobber (reg:SI 7)) | |
9307 (clobber (reg:SI 8)) | |
9308 (clobber (reg:SI 9)) | |
9309 (clobber (reg:SI 10)) | |
9310 (clobber (match_scratch:SI 4 ""))])] | |
9311 "TARGET_STRING" | |
9312 "") | |
9313 | |
9314 (define_insn "" | |
9315 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b")) | |
9316 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b"))) | |
9317 (use (match_operand:SI 2 "immediate_operand" "i")) | |
9318 (use (match_operand:SI 3 "immediate_operand" "i")) | |
9319 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r")) | |
9320 (clobber (reg:SI 6)) | |
9321 (clobber (reg:SI 7)) | |
9322 (clobber (reg:SI 8)) | |
9323 (clobber (reg:SI 9)) | |
9324 (clobber (reg:SI 10)) | |
9325 (clobber (match_scratch:SI 5 "=X"))] | |
9326 "TARGET_STRING | |
9327 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32 | |
9328 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10) | |
9329 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10) | |
9330 && REGNO (operands[4]) == 5" | |
9331 "lswi %4,%1,%2\;stswi %4,%0,%2" | |
9332 [(set_attr "type" "store") | |
9333 (set_attr "update" "yes") | |
9334 (set_attr "indexed" "yes") | |
9335 (set_attr "cell_micro" "always") | |
9336 (set_attr "length" "8")]) | |
9337 | |
9338 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill | |
9339 ;; problems with TImode. | |
9340 ;; rD/rS = r5 is preferred, efficient form. | |
9341 (define_expand "movmemsi_4reg" | |
9342 [(parallel [(set (match_operand 0 "" "") | |
9343 (match_operand 1 "" "")) | |
9344 (use (match_operand 2 "" "")) | |
9345 (use (match_operand 3 "" "")) | |
9346 (clobber (reg:SI 5)) | |
9347 (clobber (reg:SI 6)) | |
9348 (clobber (reg:SI 7)) | |
9349 (clobber (reg:SI 8)) | |
9350 (clobber (match_scratch:SI 4 ""))])] | |
9351 "TARGET_STRING" | |
9352 "") | |
9353 | |
9354 (define_insn "" | |
9355 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b")) | |
9356 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b"))) | |
9357 (use (match_operand:SI 2 "immediate_operand" "i")) | |
9358 (use (match_operand:SI 3 "immediate_operand" "i")) | |
9359 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r")) | |
9360 (clobber (reg:SI 6)) | |
9361 (clobber (reg:SI 7)) | |
9362 (clobber (reg:SI 8)) | |
9363 (clobber (match_scratch:SI 5 "=X"))] | |
9364 "TARGET_STRING | |
9365 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16 | |
9366 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8) | |
9367 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8) | |
9368 && REGNO (operands[4]) == 5" | |
9369 "lswi %4,%1,%2\;stswi %4,%0,%2" | |
9370 [(set_attr "type" "store") | |
9371 (set_attr "update" "yes") | |
9372 (set_attr "indexed" "yes") | |
9373 (set_attr "cell_micro" "always") | |
9374 (set_attr "length" "8")]) | |
9375 | |
9376 ;; Move up to 8 bytes at a time. | |
9377 (define_expand "movmemsi_2reg" | |
9378 [(parallel [(set (match_operand 0 "" "") | |
9379 (match_operand 1 "" "")) | |
9380 (use (match_operand 2 "" "")) | |
9381 (use (match_operand 3 "" "")) | |
9382 (clobber (match_scratch:DI 4 "")) | |
9383 (clobber (match_scratch:SI 5 ""))])] | |
9384 "TARGET_STRING && ! TARGET_POWERPC64" | |
9385 "") | |
9386 | |
9387 (define_insn "" | |
9388 [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b")) | |
9389 (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b"))) | |
9390 (use (match_operand:SI 2 "immediate_operand" "i")) | |
9391 (use (match_operand:SI 3 "immediate_operand" "i")) | |
9392 (clobber (match_scratch:DI 4 "=&r")) | |
9393 (clobber (match_scratch:SI 5 "=X"))] | |
9394 "TARGET_STRING && ! TARGET_POWERPC64 | |
9395 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8" | |
9396 "lswi %4,%1,%2\;stswi %4,%0,%2" | |
9397 [(set_attr "type" "store") | |
9398 (set_attr "update" "yes") | |
9399 (set_attr "indexed" "yes") | |
9400 (set_attr "cell_micro" "always") | |
9401 (set_attr "length" "8")]) | |
9402 | |
9403 ;; Move up to 4 bytes at a time. | |
9404 (define_expand "movmemsi_1reg" | |
9405 [(parallel [(set (match_operand 0 "" "") | |
9406 (match_operand 1 "" "")) | |
9407 (use (match_operand 2 "" "")) | |
9408 (use (match_operand 3 "" "")) | |
9409 (clobber (match_scratch:SI 4 "")) | |
9410 (clobber (match_scratch:SI 5 ""))])] | |
9411 "TARGET_STRING" | |
9412 "") | |
9413 | |
9414 (define_insn "" | |
9415 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b")) | |
9416 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b"))) | |
9417 (use (match_operand:SI 2 "immediate_operand" "i")) | |
9418 (use (match_operand:SI 3 "immediate_operand" "i")) | |
9419 (clobber (match_scratch:SI 4 "=&r")) | |
9420 (clobber (match_scratch:SI 5 "=X"))] | |
9421 "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4" | |
9422 "lswi %4,%1,%2\;stswi %4,%0,%2" | |
9423 [(set_attr "type" "store") | |
9424 (set_attr "update" "yes") | |
9425 (set_attr "indexed" "yes") | |
9426 (set_attr "cell_micro" "always") | |
9427 (set_attr "length" "8")]) | |
9428 | 9061 |
9429 ;; Define insns that do load or store with update. Some of these we can | 9062 ;; Define insns that do load or store with update. Some of these we can |
9430 ;; get by using pre-decrement or pre-increment, but the hardware can also | 9063 ;; get by using pre-decrement or pre-increment, but the hardware can also |
9431 ;; do cases where the increment is not the size of the object. | 9064 ;; do cases where the increment is not the size of the object. |
9432 ;; | 9065 ;; |
9669 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f") | 9302 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f") |
9670 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") | 9303 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") |
9671 (match_operand:SI 2 "reg_or_short_operand" "r,I")))) | 9304 (match_operand:SI 2 "reg_or_short_operand" "r,I")))) |
9672 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") | 9305 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") |
9673 (plus:SI (match_dup 1) (match_dup 2)))] | 9306 (plus:SI (match_dup 1) (match_dup 2)))] |
9674 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE | 9307 "TARGET_HARD_FLOAT && TARGET_UPDATE |
9675 && (!avoiding_indexed_address_p (SImode) | 9308 && (!avoiding_indexed_address_p (SImode) |
9676 || !gpc_reg_operand (operands[2], SImode))" | 9309 || !gpc_reg_operand (operands[2], SImode))" |
9677 "@ | 9310 "@ |
9678 lfsux %3,%0,%2 | 9311 lfsux %3,%0,%2 |
9679 lfsu %3,%2(%0)" | 9312 lfsu %3,%2(%0)" |
9685 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") | 9318 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") |
9686 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) | 9319 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) |
9687 (match_operand:SF 3 "gpc_reg_operand" "f,f")) | 9320 (match_operand:SF 3 "gpc_reg_operand" "f,f")) |
9688 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") | 9321 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") |
9689 (plus:SI (match_dup 1) (match_dup 2)))] | 9322 (plus:SI (match_dup 1) (match_dup 2)))] |
9690 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE | 9323 "TARGET_HARD_FLOAT && TARGET_UPDATE |
9691 && (!avoiding_indexed_address_p (SImode) | 9324 && (!avoiding_indexed_address_p (SImode) |
9692 || !gpc_reg_operand (operands[2], SImode))" | 9325 || !gpc_reg_operand (operands[2], SImode))" |
9693 "@ | 9326 "@ |
9694 stfsux %3,%0,%2 | 9327 stfsux %3,%0,%2 |
9695 stfsu %3,%2(%0)" | 9328 stfsu %3,%2(%0)" |
9733 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d") | 9366 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d") |
9734 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") | 9367 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") |
9735 (match_operand:SI 2 "reg_or_short_operand" "r,I")))) | 9368 (match_operand:SI 2 "reg_or_short_operand" "r,I")))) |
9736 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") | 9369 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") |
9737 (plus:SI (match_dup 1) (match_dup 2)))] | 9370 (plus:SI (match_dup 1) (match_dup 2)))] |
9738 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE | 9371 "TARGET_HARD_FLOAT && TARGET_UPDATE |
9739 && (!avoiding_indexed_address_p (SImode) | 9372 && (!avoiding_indexed_address_p (SImode) |
9740 || !gpc_reg_operand (operands[2], SImode))" | 9373 || !gpc_reg_operand (operands[2], SImode))" |
9741 "@ | 9374 "@ |
9742 lfdux %3,%0,%2 | 9375 lfdux %3,%0,%2 |
9743 lfdu %3,%2(%0)" | 9376 lfdu %3,%2(%0)" |
9750 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") | 9383 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") |
9751 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) | 9384 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) |
9752 (match_operand:DF 3 "gpc_reg_operand" "d,d")) | 9385 (match_operand:DF 3 "gpc_reg_operand" "d,d")) |
9753 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") | 9386 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") |
9754 (plus:SI (match_dup 1) (match_dup 2)))] | 9387 (plus:SI (match_dup 1) (match_dup 2)))] |
9755 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE | 9388 "TARGET_HARD_FLOAT && TARGET_UPDATE |
9756 && (!avoiding_indexed_address_p (SImode) | 9389 && (!avoiding_indexed_address_p (SImode) |
9757 || !gpc_reg_operand (operands[2], SImode))" | 9390 || !gpc_reg_operand (operands[2], SImode))" |
9758 "@ | 9391 "@ |
9759 stfdux %3,%0,%2 | 9392 stfdux %3,%0,%2 |
9760 stfdu %3,%2(%0)" | 9393 stfdu %3,%2(%0)" |
9770 ;; sequences, using get_attr_length here will smash the operands | 9403 ;; sequences, using get_attr_length here will smash the operands |
9771 ;; array. Neither is there an early_cobbler_p predicate. | 9404 ;; array. Neither is there an early_cobbler_p predicate. |
9772 ;; Also this optimization interferes with scalars going into | 9405 ;; Also this optimization interferes with scalars going into |
9773 ;; altivec registers (the code does reloading through the FPRs). | 9406 ;; altivec registers (the code does reloading through the FPRs). |
9774 (define_peephole2 | 9407 (define_peephole2 |
9775 [(set (match_operand:DF 0 "gpc_reg_operand" "") | 9408 [(set (match_operand:DF 0 "gpc_reg_operand") |
9776 (match_operand:DF 1 "any_operand" "")) | 9409 (match_operand:DF 1 "any_operand")) |
9777 (set (match_operand:DF 2 "gpc_reg_operand" "") | 9410 (set (match_operand:DF 2 "gpc_reg_operand") |
9778 (match_dup 0))] | 9411 (match_dup 0))] |
9779 "!TARGET_VSX | 9412 "!TARGET_VSX |
9780 && peep2_reg_dead_p (2, operands[0])" | 9413 && peep2_reg_dead_p (2, operands[0])" |
9781 [(set (match_dup 2) (match_dup 1))]) | 9414 [(set (match_dup 2) (match_dup 1))]) |
9782 | 9415 |
9783 (define_peephole2 | 9416 (define_peephole2 |
9784 [(set (match_operand:SF 0 "gpc_reg_operand" "") | 9417 [(set (match_operand:SF 0 "gpc_reg_operand") |
9785 (match_operand:SF 1 "any_operand" "")) | 9418 (match_operand:SF 1 "any_operand")) |
9786 (set (match_operand:SF 2 "gpc_reg_operand" "") | 9419 (set (match_operand:SF 2 "gpc_reg_operand") |
9787 (match_dup 0))] | 9420 (match_dup 0))] |
9788 "!TARGET_P8_VECTOR | 9421 "!TARGET_P8_VECTOR |
9789 && peep2_reg_dead_p (2, operands[0])" | 9422 && peep2_reg_dead_p (2, operands[0])" |
9790 [(set (match_dup 2) (match_dup 1))]) | 9423 [(set (match_dup 2) (match_dup 1))]) |
9791 | 9424 |
9877 (high:TLSmode | 9510 (high:TLSmode |
9878 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD))) | 9511 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD))) |
9879 (set (match_dup 0) | 9512 (set (match_dup 0) |
9880 (lo_sum:TLSmode (match_dup 3) | 9513 (lo_sum:TLSmode (match_dup 3) |
9881 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))] | 9514 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))] |
9882 " | |
9883 { | 9515 { |
9884 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); | 9516 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); |
9885 }" | 9517 } |
9886 [(set (attr "length") | 9518 [(set (attr "length") |
9887 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) | 9519 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) |
9888 (const_int 8) | 9520 (const_int 8) |
9889 (const_int 4)))]) | 9521 (const_int 4)))]) |
9890 | 9522 |
9893 (high:TLSmode | 9525 (high:TLSmode |
9894 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") | 9526 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") |
9895 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] | 9527 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] |
9896 UNSPEC_TLSGD)))] | 9528 UNSPEC_TLSGD)))] |
9897 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" | 9529 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" |
9898 "addis %0,%1,%2@got@tlsgd@ha" | 9530 "addis %0,%1,%2@got@tlsgd@ha") |
9899 [(set_attr "length" "4")]) | |
9900 | 9531 |
9901 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>" | 9532 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>" |
9902 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") | 9533 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") |
9903 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") | 9534 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") |
9904 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b") | 9535 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b") |
9905 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] | 9536 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] |
9906 UNSPEC_TLSGD)))] | 9537 UNSPEC_TLSGD)))] |
9907 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" | 9538 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" |
9908 "addi %0,%1,%2@got@tlsgd@l" | 9539 "addi %0,%1,%2@got@tlsgd@l") |
9909 [(set_attr "length" "4")]) | |
9910 | 9540 |
9911 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>" | 9541 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>" |
9912 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") | 9542 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") |
9913 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) | 9543 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) |
9914 (match_operand 2 "" "g"))) | 9544 (match_operand 2 "" "g"))) |
9936 return "bl %z1+32768(%3@tlsgd)@plt"; | 9566 return "bl %z1+32768(%3@tlsgd)@plt"; |
9937 return "bl %z1(%3@tlsgd)@plt"; | 9567 return "bl %z1(%3@tlsgd)@plt"; |
9938 } | 9568 } |
9939 return "bl %z1(%3@tlsgd)"; | 9569 return "bl %z1(%3@tlsgd)"; |
9940 } | 9570 } |
9941 [(set_attr "type" "branch") | 9571 [(set_attr "type" "branch")]) |
9942 (set_attr "length" "4")]) | |
9943 | 9572 |
9944 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>" | 9573 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>" |
9945 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") | 9574 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") |
9946 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s")) | 9575 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s")) |
9947 (match_operand 3 "" "g"))) | 9576 (match_operand 3 "" "g"))) |
10014 (high:TLSmode | 9643 (high:TLSmode |
10015 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD))) | 9644 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD))) |
10016 (set (match_dup 0) | 9645 (set (match_dup 0) |
10017 (lo_sum:TLSmode (match_dup 2) | 9646 (lo_sum:TLSmode (match_dup 2) |
10018 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))] | 9647 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))] |
10019 " | |
10020 { | 9648 { |
10021 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); | 9649 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); |
10022 }" | 9650 } |
10023 [(set (attr "length") | 9651 [(set (attr "length") |
10024 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) | 9652 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) |
10025 (const_int 8) | 9653 (const_int 8) |
10026 (const_int 4)))]) | 9654 (const_int 4)))]) |
10027 | 9655 |
10030 (high:TLSmode | 9658 (high:TLSmode |
10031 (unspec:TLSmode [(const_int 0) | 9659 (unspec:TLSmode [(const_int 0) |
10032 (match_operand:TLSmode 1 "gpc_reg_operand" "b")] | 9660 (match_operand:TLSmode 1 "gpc_reg_operand" "b")] |
10033 UNSPEC_TLSLD)))] | 9661 UNSPEC_TLSLD)))] |
10034 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" | 9662 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" |
10035 "addis %0,%1,%&@got@tlsld@ha" | 9663 "addis %0,%1,%&@got@tlsld@ha") |
10036 [(set_attr "length" "4")]) | |
10037 | 9664 |
10038 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>" | 9665 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>" |
10039 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") | 9666 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") |
10040 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") | 9667 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") |
10041 (unspec:TLSmode [(const_int 0) | 9668 (unspec:TLSmode [(const_int 0) |
10042 (match_operand:TLSmode 2 "gpc_reg_operand" "b")] | 9669 (match_operand:TLSmode 2 "gpc_reg_operand" "b")] |
10043 UNSPEC_TLSLD)))] | 9670 UNSPEC_TLSLD)))] |
10044 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" | 9671 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" |
10045 "addi %0,%1,%&@got@tlsld@l" | 9672 "addi %0,%1,%&@got@tlsld@l") |
10046 [(set_attr "length" "4")]) | |
10047 | 9673 |
10048 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>" | 9674 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>" |
10049 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") | 9675 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") |
10050 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) | 9676 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) |
10051 (match_operand 2 "" "g"))) | 9677 (match_operand 2 "" "g"))) |
10071 return "bl %z1+32768(%&@tlsld)@plt"; | 9697 return "bl %z1+32768(%&@tlsld)@plt"; |
10072 return "bl %z1(%&@tlsld)@plt"; | 9698 return "bl %z1(%&@tlsld)@plt"; |
10073 } | 9699 } |
10074 return "bl %z1(%&@tlsld)"; | 9700 return "bl %z1(%&@tlsld)"; |
10075 } | 9701 } |
10076 [(set_attr "type" "branch") | 9702 [(set_attr "type" "branch")]) |
10077 (set_attr "length" "4")]) | |
10078 | 9703 |
10079 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>" | 9704 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>" |
10080 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") | 9705 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") |
10081 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") | 9706 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") |
10082 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] | 9707 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] |
10112 (high:TLSmode | 9737 (high:TLSmode |
10113 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL))) | 9738 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL))) |
10114 (set (match_dup 0) | 9739 (set (match_dup 0) |
10115 (lo_sum:TLSmode (match_dup 3) | 9740 (lo_sum:TLSmode (match_dup 3) |
10116 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))] | 9741 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))] |
10117 " | |
10118 { | 9742 { |
10119 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); | 9743 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); |
10120 }" | 9744 } |
10121 [(set (attr "length") | 9745 [(set (attr "length") |
10122 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) | 9746 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) |
10123 (const_int 8) | 9747 (const_int 8) |
10124 (const_int 4)))]) | 9748 (const_int 4)))]) |
10125 | 9749 |
10128 (high:TLSmode | 9752 (high:TLSmode |
10129 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") | 9753 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") |
10130 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] | 9754 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] |
10131 UNSPEC_TLSGOTDTPREL)))] | 9755 UNSPEC_TLSGOTDTPREL)))] |
10132 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" | 9756 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" |
10133 "addis %0,%1,%2@got@dtprel@ha" | 9757 "addis %0,%1,%2@got@dtprel@ha") |
10134 [(set_attr "length" "4")]) | |
10135 | 9758 |
10136 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>" | 9759 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>" |
10137 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") | 9760 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") |
10138 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") | 9761 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") |
10139 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b") | 9762 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b") |
10140 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] | 9763 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] |
10141 UNSPEC_TLSGOTDTPREL)))] | 9764 UNSPEC_TLSGOTDTPREL)))] |
10142 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" | 9765 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" |
10143 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)" | 9766 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)") |
10144 [(set_attr "length" "4")]) | |
10145 | 9767 |
10146 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>" | 9768 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>" |
10147 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") | 9769 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") |
10148 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") | 9770 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") |
10149 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] | 9771 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] |
10182 (high:TLSmode | 9804 (high:TLSmode |
10183 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL))) | 9805 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL))) |
10184 (set (match_dup 0) | 9806 (set (match_dup 0) |
10185 (lo_sum:TLSmode (match_dup 3) | 9807 (lo_sum:TLSmode (match_dup 3) |
10186 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))] | 9808 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))] |
10187 " | |
10188 { | 9809 { |
10189 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); | 9810 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); |
10190 }" | 9811 } |
10191 [(set (attr "length") | 9812 [(set (attr "length") |
10192 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) | 9813 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) |
10193 (const_int 8) | 9814 (const_int 8) |
10194 (const_int 4)))]) | 9815 (const_int 4)))]) |
10195 | 9816 |
10198 (high:TLSmode | 9819 (high:TLSmode |
10199 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") | 9820 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") |
10200 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] | 9821 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] |
10201 UNSPEC_TLSGOTTPREL)))] | 9822 UNSPEC_TLSGOTTPREL)))] |
10202 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" | 9823 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" |
10203 "addis %0,%1,%2@got@tprel@ha" | 9824 "addis %0,%1,%2@got@tprel@ha") |
10204 [(set_attr "length" "4")]) | |
10205 | 9825 |
10206 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>" | 9826 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>" |
10207 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") | 9827 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") |
10208 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") | 9828 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") |
10209 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b") | 9829 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b") |
10210 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] | 9830 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] |
10211 UNSPEC_TLSGOTTPREL)))] | 9831 UNSPEC_TLSGOTTPREL)))] |
10212 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" | 9832 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" |
10213 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)" | 9833 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)") |
10214 [(set_attr "length" "4")]) | |
10215 | 9834 |
10216 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>" | 9835 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>" |
10217 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") | 9836 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") |
10218 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") | 9837 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") |
10219 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] | 9838 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] |
10220 UNSPEC_TLSTLS))] | 9839 UNSPEC_TLSTLS))] |
10221 "TARGET_ELF && HAVE_AS_TLS" | 9840 "TARGET_ELF && HAVE_AS_TLS" |
10222 "add %0,%1,%2@tls") | 9841 "add %0,%1,%2@tls") |
10223 | 9842 |
10224 (define_expand "tls_get_tpointer" | 9843 (define_expand "tls_get_tpointer" |
10225 [(set (match_operand:SI 0 "gpc_reg_operand" "") | 9844 [(set (match_operand:SI 0 "gpc_reg_operand") |
10226 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))] | 9845 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))] |
10227 "TARGET_XCOFF && HAVE_AS_TLS" | 9846 "TARGET_XCOFF && HAVE_AS_TLS" |
10228 " | |
10229 { | 9847 { |
10230 emit_insn (gen_tls_get_tpointer_internal ()); | 9848 emit_insn (gen_tls_get_tpointer_internal ()); |
10231 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3)); | 9849 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3)); |
10232 DONE; | 9850 DONE; |
10233 }") | 9851 }) |
10234 | 9852 |
10235 (define_insn "tls_get_tpointer_internal" | 9853 (define_insn "tls_get_tpointer_internal" |
10236 [(set (reg:SI 3) | 9854 [(set (reg:SI 3) |
10237 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS)) | 9855 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS)) |
10238 (clobber (reg:SI LR_REGNO))] | 9856 (clobber (reg:SI LR_REGNO))] |
10239 "TARGET_XCOFF && HAVE_AS_TLS" | 9857 "TARGET_XCOFF && HAVE_AS_TLS" |
10240 "bla __get_tpointer") | 9858 "bla __get_tpointer") |
10241 | 9859 |
10242 (define_expand "tls_get_addr<mode>" | 9860 (define_expand "tls_get_addr<mode>" |
10243 [(set (match_operand:P 0 "gpc_reg_operand" "") | 9861 [(set (match_operand:P 0 "gpc_reg_operand") |
10244 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "") | 9862 (unspec:P [(match_operand:P 1 "gpc_reg_operand") |
10245 (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))] | 9863 (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))] |
10246 "TARGET_XCOFF && HAVE_AS_TLS" | 9864 "TARGET_XCOFF && HAVE_AS_TLS" |
10247 " | |
10248 { | 9865 { |
10249 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]); | 9866 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]); |
10250 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]); | 9867 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]); |
10251 emit_insn (gen_tls_get_addr_internal<mode> ()); | 9868 emit_insn (gen_tls_get_addr_internal<mode> ()); |
10252 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3)); | 9869 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3)); |
10253 DONE; | 9870 DONE; |
10254 }") | 9871 }) |
10255 | 9872 |
10256 (define_insn "tls_get_addr_internal<mode>" | 9873 (define_insn "tls_get_addr_internal<mode>" |
10257 [(set (reg:P 3) | 9874 [(set (reg:P 3) |
10258 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS)) | 9875 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS)) |
10259 (clobber (reg:P 0)) | 9876 (clobber (reg:P 0)) |
10279 ;; | 9896 ;; |
10280 ;; Thus we allow reg_or_cint_operand instead so that the expander can see | 9897 ;; Thus we allow reg_or_cint_operand instead so that the expander can see |
10281 ;; the constant size. The value is forced into a register if necessary. | 9898 ;; the constant size. The value is forced into a register if necessary. |
10282 ;; | 9899 ;; |
10283 (define_expand "allocate_stack" | 9900 (define_expand "allocate_stack" |
10284 [(set (match_operand 0 "gpc_reg_operand" "") | 9901 [(set (match_operand 0 "gpc_reg_operand") |
10285 (minus (reg 1) (match_operand 1 "reg_or_cint_operand" ""))) | 9902 (minus (reg 1) (match_operand 1 "reg_or_cint_operand"))) |
10286 (set (reg 1) | 9903 (set (reg 1) |
10287 (minus (reg 1) (match_dup 1)))] | 9904 (minus (reg 1) (match_dup 1)))] |
10288 "" | 9905 "" |
10289 " | 9906 { |
10290 { rtx chain = gen_reg_rtx (Pmode); | 9907 rtx chain = gen_reg_rtx (Pmode); |
10291 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx); | 9908 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx); |
10292 rtx neg_op0; | 9909 rtx neg_op0; |
10293 rtx insn, par, set, mem; | 9910 rtx insn, par, set, mem; |
10294 | 9911 |
10295 /* By allowing reg_or_cint_operand as the predicate we can get | 9912 /* By allowing reg_or_cint_operand as the predicate we can get |
10331 as well do a reasonable job when we obviously can. */ | 9948 as well do a reasonable job when we obviously can. */ |
10332 if (rounded_size != const0_rtx) | 9949 if (rounded_size != const0_rtx) |
10333 { | 9950 { |
10334 rtx loop_lab, end_loop; | 9951 rtx loop_lab, end_loop; |
10335 bool rotated = CONST_INT_P (rounded_size); | 9952 bool rotated = CONST_INT_P (rounded_size); |
9953 rtx update = GEN_INT (-probe_interval); | |
9954 if (probe_interval > 32768) | |
9955 update = force_reg (Pmode, update); | |
10336 | 9956 |
10337 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop, | 9957 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop, |
10338 last_addr, rotated); | 9958 last_addr, rotated); |
10339 | 9959 |
10340 if (Pmode == SImode) | 9960 if (Pmode == SImode) |
10341 emit_insn (gen_movsi_update_stack (stack_pointer_rtx, | 9961 emit_insn (gen_movsi_update_stack (stack_pointer_rtx, |
10342 stack_pointer_rtx, | 9962 stack_pointer_rtx, |
10343 GEN_INT (-probe_interval), | 9963 update, chain)); |
10344 chain)); | |
10345 else | 9964 else |
10346 emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx, | 9965 emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx, |
10347 stack_pointer_rtx, | 9966 stack_pointer_rtx, |
10348 GEN_INT (-probe_interval), | 9967 update, chain)); |
10349 chain)); | |
10350 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop, | 9968 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop, |
10351 last_addr, rotated); | 9969 last_addr, rotated); |
10352 } | 9970 } |
10353 | 9971 |
10354 /* Now handle residuals. We just have to set operands[1] correctly | 9972 /* Now handle residuals. We just have to set operands[1] correctly |
10355 and let the rest of the expander run. */ | 9973 and let the rest of the expander run. */ |
10356 operands[1] = residual; | 9974 operands[1] = residual; |
10357 if (!CONST_INT_P (residual)) | 9975 } |
10358 operands[1] = force_reg (Pmode, operands[1]); | 9976 |
10359 } | 9977 if (!(CONST_INT_P (operands[1]) |
10360 | 9978 && IN_RANGE (INTVAL (operands[1]), -32767, 32768))) |
10361 if (GET_CODE (operands[1]) != CONST_INT | 9979 { |
10362 || INTVAL (operands[1]) < -32767 | 9980 operands[1] = force_reg (Pmode, operands[1]); |
10363 || INTVAL (operands[1]) > 32768) | |
10364 { | |
10365 neg_op0 = gen_reg_rtx (Pmode); | 9981 neg_op0 = gen_reg_rtx (Pmode); |
10366 if (TARGET_32BIT) | 9982 if (TARGET_32BIT) |
10367 emit_insn (gen_negsi2 (neg_op0, operands[1])); | 9983 emit_insn (gen_negsi2 (neg_op0, operands[1])); |
10368 else | 9984 else |
10369 emit_insn (gen_negdi2 (neg_op0, operands[1])); | 9985 emit_insn (gen_negdi2 (neg_op0, operands[1])); |
10370 } | 9986 } |
10371 else | 9987 else |
10372 neg_op0 = GEN_INT (- INTVAL (operands[1])); | 9988 neg_op0 = GEN_INT (-INTVAL (operands[1])); |
10373 | 9989 |
10374 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack | 9990 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack |
10375 : gen_movdi_di_update_stack)) | 9991 : gen_movdi_di_update_stack)) |
10376 (stack_pointer_rtx, stack_pointer_rtx, neg_op0, | 9992 (stack_pointer_rtx, stack_pointer_rtx, neg_op0, |
10377 chain)); | 9993 chain)); |
10388 MEM_NOTRAP_P (mem) = 1; | 10004 MEM_NOTRAP_P (mem) = 1; |
10389 set_mem_alias_set (mem, get_frame_alias_set ()); | 10005 set_mem_alias_set (mem, get_frame_alias_set ()); |
10390 | 10006 |
10391 emit_move_insn (operands[0], virtual_stack_dynamic_rtx); | 10007 emit_move_insn (operands[0], virtual_stack_dynamic_rtx); |
10392 DONE; | 10008 DONE; |
10393 }") | 10009 }) |
10394 | 10010 |
10395 ;; These patterns say how to save and restore the stack pointer. We need not | 10011 ;; These patterns say how to save and restore the stack pointer. We need not |
10396 ;; save the stack pointer at function level since we are careful to | 10012 ;; save the stack pointer at function level since we are careful to |
10397 ;; preserve the backchain. At block level, we have to restore the backchain | 10013 ;; preserve the backchain. At block level, we have to restore the backchain |
10398 ;; when we restore the stack pointer. | 10014 ;; when we restore the stack pointer. |
10400 ;; For nonlocal gotos, we must save both the stack pointer and its | 10016 ;; For nonlocal gotos, we must save both the stack pointer and its |
10401 ;; backchain and restore both. Note that in the nonlocal case, the | 10017 ;; backchain and restore both. Note that in the nonlocal case, the |
10402 ;; save area is a memory location. | 10018 ;; save area is a memory location. |
10403 | 10019 |
10404 (define_expand "save_stack_function" | 10020 (define_expand "save_stack_function" |
10405 [(match_operand 0 "any_operand" "") | 10021 [(match_operand 0 "any_operand") |
10406 (match_operand 1 "any_operand" "")] | 10022 (match_operand 1 "any_operand")] |
10407 "" | 10023 "" |
10408 "DONE;") | 10024 "DONE;") |
10409 | 10025 |
10410 (define_expand "restore_stack_function" | 10026 (define_expand "restore_stack_function" |
10411 [(match_operand 0 "any_operand" "") | 10027 [(match_operand 0 "any_operand") |
10412 (match_operand 1 "any_operand" "")] | 10028 (match_operand 1 "any_operand")] |
10413 "" | 10029 "" |
10414 "DONE;") | 10030 "DONE;") |
10415 | 10031 |
10416 ;; Adjust stack pointer (op0) to a new value (op1). | 10032 ;; Adjust stack pointer (op0) to a new value (op1). |
10417 ;; First copy old stack backchain to new location, and ensure that the | 10033 ;; First copy old stack backchain to new location, and ensure that the |
10418 ;; scheduler won't reorder the sp assignment before the backchain write. | 10034 ;; scheduler won't reorder the sp assignment before the backchain write. |
10419 (define_expand "restore_stack_block" | 10035 (define_expand "restore_stack_block" |
10420 [(set (match_dup 2) (match_dup 3)) | 10036 [(set (match_dup 2) (match_dup 3)) |
10421 (set (match_dup 4) (match_dup 2)) | 10037 (set (match_dup 4) (match_dup 2)) |
10422 (match_dup 5) | 10038 (match_dup 5) |
10423 (set (match_operand 0 "register_operand" "") | 10039 (set (match_operand 0 "register_operand") |
10424 (match_operand 1 "register_operand" ""))] | 10040 (match_operand 1 "register_operand"))] |
10425 "" | 10041 "" |
10426 " | |
10427 { | 10042 { |
10428 rtvec p; | 10043 rtvec p; |
10429 | 10044 |
10430 operands[1] = force_reg (Pmode, operands[1]); | 10045 operands[1] = force_reg (Pmode, operands[1]); |
10431 operands[2] = gen_reg_rtx (Pmode); | 10046 operands[2] = gen_reg_rtx (Pmode); |
10433 operands[4] = gen_frame_mem (Pmode, operands[1]); | 10048 operands[4] = gen_frame_mem (Pmode, operands[1]); |
10434 p = rtvec_alloc (1); | 10049 p = rtvec_alloc (1); |
10435 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]), | 10050 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]), |
10436 const0_rtx); | 10051 const0_rtx); |
10437 operands[5] = gen_rtx_PARALLEL (VOIDmode, p); | 10052 operands[5] = gen_rtx_PARALLEL (VOIDmode, p); |
10438 }") | 10053 }) |
10439 | 10054 |
10440 (define_expand "save_stack_nonlocal" | 10055 (define_expand "save_stack_nonlocal" |
10441 [(set (match_dup 3) (match_dup 4)) | 10056 [(set (match_dup 3) (match_dup 4)) |
10442 (set (match_operand 0 "memory_operand" "") (match_dup 3)) | 10057 (set (match_operand 0 "memory_operand") (match_dup 3)) |
10443 (set (match_dup 2) (match_operand 1 "register_operand" ""))] | 10058 (set (match_dup 2) (match_operand 1 "register_operand"))] |
10444 "" | 10059 "" |
10445 " | |
10446 { | 10060 { |
10447 int units_per_word = (TARGET_32BIT) ? 4 : 8; | 10061 int units_per_word = (TARGET_32BIT) ? 4 : 8; |
10448 | 10062 |
10449 /* Copy the backchain to the first word, sp to the second. */ | 10063 /* Copy the backchain to the first word, sp to the second. */ |
10450 operands[0] = adjust_address_nv (operands[0], Pmode, 0); | 10064 operands[0] = adjust_address_nv (operands[0], Pmode, 0); |
10451 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word); | 10065 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word); |
10452 operands[3] = gen_reg_rtx (Pmode); | 10066 operands[3] = gen_reg_rtx (Pmode); |
10453 operands[4] = gen_frame_mem (Pmode, operands[1]); | 10067 operands[4] = gen_frame_mem (Pmode, operands[1]); |
10454 }") | 10068 }) |
10455 | 10069 |
10456 (define_expand "restore_stack_nonlocal" | 10070 (define_expand "restore_stack_nonlocal" |
10457 [(set (match_dup 2) (match_operand 1 "memory_operand" "")) | 10071 [(set (match_dup 2) (match_operand 1 "memory_operand")) |
10458 (set (match_dup 3) (match_dup 4)) | 10072 (set (match_dup 3) (match_dup 4)) |
10459 (set (match_dup 5) (match_dup 2)) | 10073 (set (match_dup 5) (match_dup 2)) |
10460 (match_dup 6) | 10074 (match_dup 6) |
10461 (set (match_operand 0 "register_operand" "") (match_dup 3))] | 10075 (set (match_operand 0 "register_operand") (match_dup 3))] |
10462 "" | 10076 "" |
10463 " | |
10464 { | 10077 { |
10465 int units_per_word = (TARGET_32BIT) ? 4 : 8; | 10078 int units_per_word = (TARGET_32BIT) ? 4 : 8; |
10466 rtvec p; | 10079 rtvec p; |
10467 | 10080 |
10468 /* Restore the backchain from the first word, sp from the second. */ | 10081 /* Restore the backchain from the first word, sp from the second. */ |
10473 operands[5] = gen_frame_mem (Pmode, operands[3]); | 10086 operands[5] = gen_frame_mem (Pmode, operands[3]); |
10474 p = rtvec_alloc (1); | 10087 p = rtvec_alloc (1); |
10475 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]), | 10088 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]), |
10476 const0_rtx); | 10089 const0_rtx); |
10477 operands[6] = gen_rtx_PARALLEL (VOIDmode, p); | 10090 operands[6] = gen_rtx_PARALLEL (VOIDmode, p); |
10478 }") | 10091 }) |
10479 | 10092 |
10480 ;; TOC register handling. | 10093 ;; TOC register handling. |
10481 | 10094 |
10482 ;; Code to initialize the TOC register... | 10095 ;; Code to initialize the TOC register... |
10483 | 10096 |
10484 (define_insn "load_toc_aix_si" | 10097 (define_insn "load_toc_aix_si" |
10485 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r") | 10098 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r") |
10486 (unspec:SI [(const_int 0)] UNSPEC_TOC)) | 10099 (unspec:SI [(const_int 0)] UNSPEC_TOC)) |
10487 (use (reg:SI 2))])] | 10100 (use (reg:SI 2))])] |
10488 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT" | 10101 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT" |
10489 "* | |
10490 { | 10102 { |
10491 char buf[30]; | 10103 char buf[30]; |
10492 extern int need_toc_init; | 10104 extern int need_toc_init; |
10493 need_toc_init = 1; | 10105 need_toc_init = 1; |
10494 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1); | 10106 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1); |
10495 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); | 10107 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); |
10496 operands[2] = gen_rtx_REG (Pmode, 2); | 10108 operands[2] = gen_rtx_REG (Pmode, 2); |
10497 return \"lwz %0,%1(%2)\"; | 10109 return "lwz %0,%1(%2)"; |
10498 }" | 10110 } |
10499 [(set_attr "type" "load") | 10111 [(set_attr "type" "load") |
10500 (set_attr "update" "no") | 10112 (set_attr "update" "no") |
10501 (set_attr "indexed" "no")]) | 10113 (set_attr "indexed" "no")]) |
10502 | 10114 |
10503 (define_insn "load_toc_aix_di" | 10115 (define_insn "load_toc_aix_di" |
10504 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r") | 10116 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r") |
10505 (unspec:DI [(const_int 0)] UNSPEC_TOC)) | 10117 (unspec:DI [(const_int 0)] UNSPEC_TOC)) |
10506 (use (reg:DI 2))])] | 10118 (use (reg:DI 2))])] |
10507 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT" | 10119 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT" |
10508 "* | |
10509 { | 10120 { |
10510 char buf[30]; | 10121 char buf[30]; |
10511 extern int need_toc_init; | 10122 extern int need_toc_init; |
10512 need_toc_init = 1; | 10123 need_toc_init = 1; |
10513 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", | 10124 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", |
10514 !TARGET_ELF || !TARGET_MINIMAL_TOC); | 10125 !TARGET_ELF || !TARGET_MINIMAL_TOC); |
10515 if (TARGET_ELF) | 10126 if (TARGET_ELF) |
10516 strcat (buf, \"@toc\"); | 10127 strcat (buf, "@toc"); |
10517 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); | 10128 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); |
10518 operands[2] = gen_rtx_REG (Pmode, 2); | 10129 operands[2] = gen_rtx_REG (Pmode, 2); |
10519 return \"ld %0,%1(%2)\"; | 10130 return "ld %0,%1(%2)"; |
10520 }" | 10131 } |
10521 [(set_attr "type" "load") | 10132 [(set_attr "type" "load") |
10522 (set_attr "update" "no") | 10133 (set_attr "update" "no") |
10523 (set_attr "indexed" "no")]) | 10134 (set_attr "indexed" "no")]) |
10524 | 10135 |
10525 (define_insn "load_toc_v4_pic_si" | 10136 (define_insn "load_toc_v4_pic_si" |
10526 [(set (reg:SI LR_REGNO) | 10137 [(set (reg:SI LR_REGNO) |
10527 (unspec:SI [(const_int 0)] UNSPEC_TOC))] | 10138 (unspec:SI [(const_int 0)] UNSPEC_TOC))] |
10528 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT" | 10139 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT" |
10529 "bl _GLOBAL_OFFSET_TABLE_@local-4" | 10140 "bl _GLOBAL_OFFSET_TABLE_@local-4" |
10530 [(set_attr "type" "branch") | 10141 [(set_attr "type" "branch")]) |
10531 (set_attr "length" "4")]) | |
10532 | 10142 |
10533 (define_expand "load_toc_v4_PIC_1" | 10143 (define_expand "load_toc_v4_PIC_1" |
10534 [(parallel [(set (reg:SI LR_REGNO) | 10144 [(parallel [(set (reg:SI LR_REGNO) |
10535 (match_operand:SI 0 "immediate_operand" "s")) | 10145 (match_operand:SI 0 "immediate_operand" "s")) |
10536 (use (unspec [(match_dup 0)] UNSPEC_TOC))])] | 10146 (use (unspec [(match_dup 0)] UNSPEC_TOC))])] |
10542 [(set (reg:SI LR_REGNO) | 10152 [(set (reg:SI LR_REGNO) |
10543 (match_operand:SI 0 "immediate_operand" "s")) | 10153 (match_operand:SI 0 "immediate_operand" "s")) |
10544 (use (unspec [(match_dup 0)] UNSPEC_TOC))] | 10154 (use (unspec [(match_dup 0)] UNSPEC_TOC))] |
10545 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 | 10155 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 |
10546 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" | 10156 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" |
10547 "bcl 20,31,%0\\n%0:" | 10157 "bcl 20,31,%0\n%0:" |
10548 [(set_attr "type" "branch") | 10158 [(set_attr "type" "branch") |
10549 (set_attr "length" "4") | |
10550 (set_attr "cannot_copy" "yes")]) | 10159 (set_attr "cannot_copy" "yes")]) |
10551 | 10160 |
10552 (define_insn "load_toc_v4_PIC_1_476" | 10161 (define_insn "load_toc_v4_PIC_1_476" |
10553 [(set (reg:SI LR_REGNO) | 10162 [(set (reg:SI LR_REGNO) |
10554 (match_operand:SI 0 "immediate_operand" "s")) | 10163 (match_operand:SI 0 "immediate_operand" "s")) |
10555 (use (unspec [(match_dup 0)] UNSPEC_TOC))] | 10164 (use (unspec [(match_dup 0)] UNSPEC_TOC))] |
10556 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 | 10165 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 |
10557 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" | 10166 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" |
10558 "* | |
10559 { | 10167 { |
10560 char name[32]; | 10168 char name[32]; |
10561 static char templ[32]; | 10169 static char templ[32]; |
10562 | 10170 |
10563 get_ppc476_thunk_name (name); | 10171 get_ppc476_thunk_name (name); |
10564 sprintf (templ, \"bl %s\\n%%0:\", name); | 10172 sprintf (templ, "bl %s\n%%0:", name); |
10565 return templ; | 10173 return templ; |
10566 }" | 10174 } |
10567 [(set_attr "type" "branch") | 10175 [(set_attr "type" "branch") |
10568 (set_attr "length" "4") | |
10569 (set_attr "cannot_copy" "yes")]) | 10176 (set_attr "cannot_copy" "yes")]) |
10570 | 10177 |
10571 (define_expand "load_toc_v4_PIC_1b" | 10178 (define_expand "load_toc_v4_PIC_1b" |
10572 [(parallel [(set (reg:SI LR_REGNO) | 10179 [(parallel [(set (reg:SI LR_REGNO) |
10573 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") | 10180 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") |
10574 (label_ref (match_operand 1 "" ""))] | 10181 (label_ref (match_operand 1 ""))] |
10575 UNSPEC_TOCPTR)) | 10182 UNSPEC_TOCPTR)) |
10576 (match_dup 1)])] | 10183 (match_dup 1)])] |
10577 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" | 10184 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" |
10578 "") | 10185 "") |
10579 | 10186 |
10593 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") | 10200 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") |
10594 (label_ref (match_operand 1 "" ""))] | 10201 (label_ref (match_operand 1 "" ""))] |
10595 UNSPEC_TOCPTR)) | 10202 UNSPEC_TOCPTR)) |
10596 (match_dup 1)] | 10203 (match_dup 1)] |
10597 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" | 10204 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" |
10598 "* | |
10599 { | 10205 { |
10600 char name[32]; | 10206 char name[32]; |
10601 static char templ[32]; | 10207 static char templ[32]; |
10602 | 10208 |
10603 get_ppc476_thunk_name (name); | 10209 get_ppc476_thunk_name (name); |
10604 sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name); | 10210 sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name); |
10605 return templ; | 10211 return templ; |
10606 }" | 10212 } |
10607 [(set_attr "type" "branch") | 10213 [(set_attr "type" "branch") |
10608 (set_attr "length" "16")]) | 10214 (set_attr "length" "16")]) |
10609 | 10215 |
10610 (define_insn "load_toc_v4_PIC_2" | 10216 (define_insn "load_toc_v4_PIC_2" |
10611 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") | 10217 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") |
10612 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") | 10218 (mem:SI (plus:SI |
10613 (minus:SI (match_operand:SI 2 "immediate_operand" "s") | 10219 (match_operand:SI 1 "gpc_reg_operand" "b") |
10614 (match_operand:SI 3 "immediate_operand" "s")))))] | 10220 (const |
10221 (minus:SI (match_operand:SI 2 "immediate_operand" "s") | |
10222 (match_operand:SI 3 "immediate_operand" "s"))))))] | |
10615 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" | 10223 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" |
10616 "lwz %0,%2-%3(%1)" | 10224 "lwz %0,%2-%3(%1)" |
10617 [(set_attr "type" "load")]) | 10225 [(set_attr "type" "load")]) |
10618 | 10226 |
10619 (define_insn "load_toc_v4_PIC_3b" | 10227 (define_insn "load_toc_v4_PIC_3b" |
10620 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") | 10228 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") |
10621 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") | 10229 (plus:SI |
10622 (high:SI | 10230 (match_operand:SI 1 "gpc_reg_operand" "b") |
10623 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s") | 10231 (high:SI |
10624 (match_operand:SI 3 "symbol_ref_operand" "s")))))] | 10232 (const |
10233 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s") | |
10234 (match_operand:SI 3 "symbol_ref_operand" "s"))))))] | |
10625 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic" | 10235 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic" |
10626 "addis %0,%1,%2-%3@ha") | 10236 "addis %0,%1,%2-%3@ha") |
10627 | 10237 |
10628 (define_insn "load_toc_v4_PIC_3c" | 10238 (define_insn "load_toc_v4_PIC_3c" |
10629 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") | 10239 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") |
10630 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") | 10240 (lo_sum:SI |
10631 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s") | 10241 (match_operand:SI 1 "gpc_reg_operand" "b") |
10632 (match_operand:SI 3 "symbol_ref_operand" "s"))))] | 10242 (const |
10243 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s") | |
10244 (match_operand:SI 3 "symbol_ref_operand" "s")))))] | |
10633 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic" | 10245 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic" |
10634 "addi %0,%1,%2-%3@l") | 10246 "addi %0,%1,%2-%3@l") |
10635 | 10247 |
10636 ;; If the TOC is shared over a translation unit, as happens with all | 10248 ;; If the TOC is shared over a translation unit, as happens with all |
10637 ;; the kinds of PIC that we support, we need to restore the TOC | 10249 ;; the kinds of PIC that we support, we need to restore the TOC |
10638 ;; pointer only when jumping over units of translation. | 10250 ;; pointer only when jumping over units of translation. |
10639 ;; On Darwin, we need to reload the picbase. | 10251 ;; On Darwin, we need to reload the picbase. |
10640 | 10252 |
10641 (define_expand "builtin_setjmp_receiver" | 10253 (define_expand "builtin_setjmp_receiver" |
10642 [(use (label_ref (match_operand 0 "" "")))] | 10254 [(use (label_ref (match_operand 0 "")))] |
10643 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1) | 10255 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1) |
10644 || (TARGET_TOC && TARGET_MINIMAL_TOC) | 10256 || (TARGET_TOC && TARGET_MINIMAL_TOC) |
10645 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)" | 10257 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)" |
10646 " | |
10647 { | 10258 { |
10648 #if TARGET_MACHO | 10259 #if TARGET_MACHO |
10649 if (DEFAULT_ABI == ABI_DARWIN) | 10260 if (DEFAULT_ABI == ABI_DARWIN) |
10650 { | 10261 { |
10651 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME); | 10262 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME); |
10652 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM); | 10263 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM); |
10653 rtx tmplabrtx; | 10264 rtx tmplabrtx; |
10654 char tmplab[20]; | 10265 char tmplab[20]; |
10655 | 10266 |
10656 crtl->uses_pic_offset_table = 1; | 10267 crtl->uses_pic_offset_table = 1; |
10657 ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\", | 10268 ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR", |
10658 CODE_LABEL_NUMBER (operands[0])); | 10269 CODE_LABEL_NUMBER (operands[0])); |
10659 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab)); | 10270 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab)); |
10660 | 10271 |
10661 emit_insn (gen_load_macho_picbase (tmplabrtx)); | 10272 emit_insn (gen_load_macho_picbase (tmplabrtx)); |
10662 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO)); | 10273 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO)); |
10664 } | 10275 } |
10665 else | 10276 else |
10666 #endif | 10277 #endif |
10667 rs6000_emit_load_toc_table (FALSE); | 10278 rs6000_emit_load_toc_table (FALSE); |
10668 DONE; | 10279 DONE; |
10669 }") | 10280 }) |
10670 | 10281 |
10671 ;; Largetoc support | 10282 ;; Largetoc support |
10672 (define_insn "*largetoc_high" | 10283 (define_insn "*largetoc_high" |
10673 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r") | 10284 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r") |
10674 (high:DI | 10285 (high:DI |
10749 "TARGET_ELF && !TARGET_64BIT && !flag_pic" | 10360 "TARGET_ELF && !TARGET_64BIT && !flag_pic" |
10750 "la %0,%2@l(%1)") | 10361 "la %0,%2@l(%1)") |
10751 | 10362 |
10752 ;; Call and call_value insns | 10363 ;; Call and call_value insns |
10753 (define_expand "call" | 10364 (define_expand "call" |
10754 [(parallel [(call (mem:SI (match_operand 0 "address_operand" "")) | 10365 [(parallel [(call (mem:SI (match_operand 0 "address_operand")) |
10755 (match_operand 1 "" "")) | 10366 (match_operand 1 "")) |
10756 (use (match_operand 2 "" "")) | 10367 (use (match_operand 2 "")) |
10757 (clobber (reg:SI LR_REGNO))])] | 10368 (clobber (reg:SI LR_REGNO))])] |
10758 "" | 10369 "" |
10759 " | |
10760 { | 10370 { |
10761 #if TARGET_MACHO | 10371 #if TARGET_MACHO |
10762 if (MACHOPIC_INDIRECT) | 10372 if (MACHOPIC_INDIRECT) |
10763 operands[0] = machopic_indirect_call_target (operands[0]); | 10373 operands[0] = machopic_indirect_call_target (operands[0]); |
10764 #endif | 10374 #endif |
10789 | 10399 |
10790 default: | 10400 default: |
10791 gcc_unreachable (); | 10401 gcc_unreachable (); |
10792 } | 10402 } |
10793 } | 10403 } |
10794 }") | 10404 }) |
10795 | 10405 |
10796 (define_expand "call_value" | 10406 (define_expand "call_value" |
10797 [(parallel [(set (match_operand 0 "" "") | 10407 [(parallel [(set (match_operand 0 "") |
10798 (call (mem:SI (match_operand 1 "address_operand" "")) | 10408 (call (mem:SI (match_operand 1 "address_operand")) |
10799 (match_operand 2 "" ""))) | 10409 (match_operand 2 ""))) |
10800 (use (match_operand 3 "" "")) | 10410 (use (match_operand 3 "")) |
10801 (clobber (reg:SI LR_REGNO))])] | 10411 (clobber (reg:SI LR_REGNO))])] |
10802 "" | 10412 "" |
10803 " | |
10804 { | 10413 { |
10805 #if TARGET_MACHO | 10414 #if TARGET_MACHO |
10806 if (MACHOPIC_INDIRECT) | 10415 if (MACHOPIC_INDIRECT) |
10807 operands[1] = machopic_indirect_call_target (operands[1]); | 10416 operands[1] = machopic_indirect_call_target (operands[1]); |
10808 #endif | 10417 #endif |
10833 | 10442 |
10834 default: | 10443 default: |
10835 gcc_unreachable (); | 10444 gcc_unreachable (); |
10836 } | 10445 } |
10837 } | 10446 } |
10838 }") | 10447 }) |
10839 | 10448 |
10840 ;; Call to function in current module. No TOC pointer reload needed. | 10449 ;; Call to function in current module. No TOC pointer reload needed. |
10841 ;; Operand2 is nonzero if we are using the V.4 calling sequence and | 10450 ;; Operand2 is nonzero if we are using the V.4 calling sequence and |
10842 ;; either the function was not prototyped, or it was prototyped as a | 10451 ;; either the function was not prototyped, or it was prototyped as a |
10843 ;; variable argument function. It is > 0 if FP registers were passed | 10452 ;; variable argument function. It is > 0 if FP registers were passed |
10847 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s")) | 10456 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s")) |
10848 (match_operand 1 "" "g,g")) | 10457 (match_operand 1 "" "g,g")) |
10849 (use (match_operand:SI 2 "immediate_operand" "O,n")) | 10458 (use (match_operand:SI 2 "immediate_operand" "O,n")) |
10850 (clobber (reg:SI LR_REGNO))] | 10459 (clobber (reg:SI LR_REGNO))] |
10851 "(INTVAL (operands[2]) & CALL_LONG) == 0" | 10460 "(INTVAL (operands[2]) & CALL_LONG) == 0" |
10852 "* | |
10853 { | 10461 { |
10854 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) | 10462 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) |
10855 output_asm_insn (\"crxor 6,6,6\", operands); | 10463 output_asm_insn ("crxor 6,6,6", operands); |
10856 | 10464 |
10857 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) | 10465 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) |
10858 output_asm_insn (\"creqv 6,6,6\", operands); | 10466 output_asm_insn ("creqv 6,6,6", operands); |
10859 | 10467 |
10860 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\"; | 10468 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0"; |
10861 }" | 10469 } |
10862 [(set_attr "type" "branch") | 10470 [(set_attr "type" "branch") |
10863 (set_attr "length" "4,8")]) | 10471 (set_attr "length" "4,8")]) |
10864 | 10472 |
10865 (define_insn "*call_local64" | 10473 (define_insn "*call_local64" |
10866 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s")) | 10474 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s")) |
10867 (match_operand 1 "" "g,g")) | 10475 (match_operand 1 "" "g,g")) |
10868 (use (match_operand:SI 2 "immediate_operand" "O,n")) | 10476 (use (match_operand:SI 2 "immediate_operand" "O,n")) |
10869 (clobber (reg:SI LR_REGNO))] | 10477 (clobber (reg:SI LR_REGNO))] |
10870 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0" | 10478 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0" |
10871 "* | |
10872 { | 10479 { |
10873 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) | 10480 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) |
10874 output_asm_insn (\"crxor 6,6,6\", operands); | 10481 output_asm_insn ("crxor 6,6,6", operands); |
10875 | 10482 |
10876 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) | 10483 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) |
10877 output_asm_insn (\"creqv 6,6,6\", operands); | 10484 output_asm_insn ("creqv 6,6,6", operands); |
10878 | 10485 |
10879 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\"; | 10486 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0"; |
10880 }" | 10487 } |
10881 [(set_attr "type" "branch") | 10488 [(set_attr "type" "branch") |
10882 (set_attr "length" "4,8")]) | 10489 (set_attr "length" "4,8")]) |
10883 | 10490 |
10884 (define_insn "*call_value_local32" | 10491 (define_insn "*call_value_local32" |
10885 [(set (match_operand 0 "" "") | 10492 [(set (match_operand 0 "" "") |
10886 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s")) | 10493 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s")) |
10887 (match_operand 2 "" "g,g"))) | 10494 (match_operand 2 "" "g,g"))) |
10888 (use (match_operand:SI 3 "immediate_operand" "O,n")) | 10495 (use (match_operand:SI 3 "immediate_operand" "O,n")) |
10889 (clobber (reg:SI LR_REGNO))] | 10496 (clobber (reg:SI LR_REGNO))] |
10890 "(INTVAL (operands[3]) & CALL_LONG) == 0" | 10497 "(INTVAL (operands[3]) & CALL_LONG) == 0" |
10891 "* | |
10892 { | 10498 { |
10893 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) | 10499 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) |
10894 output_asm_insn (\"crxor 6,6,6\", operands); | 10500 output_asm_insn ("crxor 6,6,6", operands); |
10895 | 10501 |
10896 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) | 10502 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) |
10897 output_asm_insn (\"creqv 6,6,6\", operands); | 10503 output_asm_insn ("creqv 6,6,6", operands); |
10898 | 10504 |
10899 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\"; | 10505 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1"; |
10900 }" | 10506 } |
10901 [(set_attr "type" "branch") | 10507 [(set_attr "type" "branch") |
10902 (set_attr "length" "4,8")]) | 10508 (set_attr "length" "4,8")]) |
10903 | 10509 |
10904 | 10510 |
10905 (define_insn "*call_value_local64" | 10511 (define_insn "*call_value_local64" |
10907 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s")) | 10513 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s")) |
10908 (match_operand 2 "" "g,g"))) | 10514 (match_operand 2 "" "g,g"))) |
10909 (use (match_operand:SI 3 "immediate_operand" "O,n")) | 10515 (use (match_operand:SI 3 "immediate_operand" "O,n")) |
10910 (clobber (reg:SI LR_REGNO))] | 10516 (clobber (reg:SI LR_REGNO))] |
10911 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0" | 10517 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0" |
10912 "* | |
10913 { | 10518 { |
10914 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) | 10519 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) |
10915 output_asm_insn (\"crxor 6,6,6\", operands); | 10520 output_asm_insn ("crxor 6,6,6", operands); |
10916 | 10521 |
10917 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) | 10522 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) |
10918 output_asm_insn (\"creqv 6,6,6\", operands); | 10523 output_asm_insn ("creqv 6,6,6", operands); |
10919 | 10524 |
10920 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\"; | 10525 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1"; |
10921 }" | 10526 } |
10922 [(set_attr "type" "branch") | 10527 [(set_attr "type" "branch") |
10923 (set_attr "length" "4,8")]) | 10528 (set_attr "length" "4,8")]) |
10924 | 10529 |
10925 | 10530 |
10926 ;; A function pointer under System V is just a normal pointer | 10531 ;; A function pointer under System V is just a normal pointer |
10941 output_asm_insn ("crxor 6,6,6", operands); | 10546 output_asm_insn ("crxor 6,6,6", operands); |
10942 | 10547 |
10943 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) | 10548 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) |
10944 output_asm_insn ("creqv 6,6,6", operands); | 10549 output_asm_insn ("creqv 6,6,6", operands); |
10945 | 10550 |
10946 return "b%T0l"; | 10551 if (rs6000_speculate_indirect_jumps |
10552 || which_alternative == 1 || which_alternative == 3) | |
10553 return "b%T0l"; | |
10554 else | |
10555 return "crset 2\;beq%T0l-"; | |
10947 } | 10556 } |
10948 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") | 10557 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") |
10949 (set_attr "length" "4,4,8,8")]) | 10558 (set_attr_alternative "length" |
10559 [(if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps") | |
10560 (const_int 0)) | |
10561 (const_string "8") | |
10562 (const_string "4")) | |
10563 (const_string "4") | |
10564 (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps") | |
10565 (const_int 0)) | |
10566 (const_string "12") | |
10567 (const_string "8")) | |
10568 (const_string "8")])]) | |
10950 | 10569 |
10951 (define_insn_and_split "*call_nonlocal_sysv<mode>" | 10570 (define_insn_and_split "*call_nonlocal_sysv<mode>" |
10952 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) | 10571 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) |
10953 (match_operand 1 "" "g,g")) | 10572 (match_operand 1 "" "g,g")) |
10954 (use (match_operand:SI 2 "immediate_operand" "O,n")) | 10573 (use (match_operand:SI 2 "immediate_operand" "O,n")) |
11029 output_asm_insn ("crxor 6,6,6", operands); | 10648 output_asm_insn ("crxor 6,6,6", operands); |
11030 | 10649 |
11031 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) | 10650 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) |
11032 output_asm_insn ("creqv 6,6,6", operands); | 10651 output_asm_insn ("creqv 6,6,6", operands); |
11033 | 10652 |
11034 return "b%T1l"; | 10653 if (rs6000_speculate_indirect_jumps |
10654 || which_alternative == 1 || which_alternative == 3) | |
10655 return "b%T1l"; | |
10656 else | |
10657 return "crset 2\;beq%T1l-"; | |
11035 } | 10658 } |
11036 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") | 10659 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") |
11037 (set_attr "length" "4,4,8,8")]) | 10660 (set_attr_alternative "length" |
10661 [(if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps") | |
10662 (const_int 0)) | |
10663 (const_string "8") | |
10664 (const_string "4")) | |
10665 (const_string "4") | |
10666 (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps") | |
10667 (const_int 0)) | |
10668 (const_string "12") | |
10669 (const_string "8")) | |
10670 (const_string "8")])]) | |
11038 | 10671 |
11039 (define_insn_and_split "*call_value_nonlocal_sysv<mode>" | 10672 (define_insn_and_split "*call_value_nonlocal_sysv<mode>" |
11040 [(set (match_operand 0 "" "") | 10673 [(set (match_operand 0 "" "") |
11041 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s")) | 10674 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s")) |
11042 (match_operand 2 "" "g,g"))) | 10675 (match_operand 2 "" "g,g"))) |
11111 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s")) | 10744 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s")) |
11112 (match_operand 1 "" "g")) | 10745 (match_operand 1 "" "g")) |
11113 (clobber (reg:P LR_REGNO))] | 10746 (clobber (reg:P LR_REGNO))] |
11114 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" | 10747 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" |
11115 "bl %z0" | 10748 "bl %z0" |
11116 [(set_attr "type" "branch") | 10749 [(set_attr "type" "branch")]) |
11117 (set_attr "length" "4")]) | |
11118 | 10750 |
11119 (define_insn "*call_value_local_aix<mode>" | 10751 (define_insn "*call_value_local_aix<mode>" |
11120 [(set (match_operand 0 "" "") | 10752 [(set (match_operand 0 "" "") |
11121 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s")) | 10753 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s")) |
11122 (match_operand 2 "" "g"))) | 10754 (match_operand 2 "" "g"))) |
11123 (clobber (reg:P LR_REGNO))] | 10755 (clobber (reg:P LR_REGNO))] |
11124 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" | 10756 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" |
11125 "bl %z1" | 10757 "bl %z1" |
11126 [(set_attr "type" "branch") | 10758 [(set_attr "type" "branch")]) |
11127 (set_attr "length" "4")]) | |
11128 | 10759 |
11129 ;; Call to AIX abi function which may be in another module. | 10760 ;; Call to AIX abi function which may be in another module. |
11130 ;; Restore the TOC pointer (r2) after the call. | 10761 ;; Restore the TOC pointer (r2) after the call. |
11131 | 10762 |
11132 (define_insn "*call_nonlocal_aix<mode>" | 10763 (define_insn "*call_nonlocal_aix<mode>" |
11157 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) | 10788 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) |
11158 (match_operand 1 "" "g,g")) | 10789 (match_operand 1 "" "g,g")) |
11159 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>")) | 10790 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>")) |
11160 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) | 10791 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) |
11161 (clobber (reg:P LR_REGNO))] | 10792 (clobber (reg:P LR_REGNO))] |
11162 "DEFAULT_ABI == ABI_AIX" | 10793 "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps" |
11163 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)" | 10794 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)" |
11164 [(set_attr "type" "jmpreg") | 10795 [(set_attr "type" "jmpreg") |
11165 (set_attr "length" "12")]) | 10796 (set_attr "length" "12")]) |
10797 | |
10798 (define_insn "*call_indirect_aix<mode>_nospec" | |
10799 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) | |
10800 (match_operand 1 "" "g,g")) | |
10801 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>")) | |
10802 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) | |
10803 (clobber (reg:P LR_REGNO))] | |
10804 "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps" | |
10805 "crset 2\;<ptrload> 2,%2\;beq%T0l-\;<ptrload> 2,%3(1)" | |
10806 [(set_attr "type" "jmpreg") | |
10807 (set_attr "length" "16")]) | |
11166 | 10808 |
11167 (define_insn "*call_value_indirect_aix<mode>" | 10809 (define_insn "*call_value_indirect_aix<mode>" |
11168 [(set (match_operand 0 "" "") | 10810 [(set (match_operand 0 "" "") |
11169 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) | 10811 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) |
11170 (match_operand 2 "" "g,g"))) | 10812 (match_operand 2 "" "g,g"))) |
11171 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>")) | 10813 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>")) |
11172 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) | 10814 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) |
11173 (clobber (reg:P LR_REGNO))] | 10815 (clobber (reg:P LR_REGNO))] |
11174 "DEFAULT_ABI == ABI_AIX" | 10816 "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps" |
11175 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)" | 10817 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)" |
11176 [(set_attr "type" "jmpreg") | 10818 [(set_attr "type" "jmpreg") |
11177 (set_attr "length" "12")]) | 10819 (set_attr "length" "12")]) |
10820 | |
10821 (define_insn "*call_value_indirect_aix<mode>_nospec" | |
10822 [(set (match_operand 0 "" "") | |
10823 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) | |
10824 (match_operand 2 "" "g,g"))) | |
10825 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>")) | |
10826 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) | |
10827 (clobber (reg:P LR_REGNO))] | |
10828 "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps" | |
10829 "crset 2\;<ptrload> 2,%3\;beq%T1l-\;<ptrload> 2,%4(1)" | |
10830 [(set_attr "type" "jmpreg") | |
10831 (set_attr "length" "16")]) | |
11178 | 10832 |
11179 ;; Call to indirect functions with the ELFv2 ABI. | 10833 ;; Call to indirect functions with the ELFv2 ABI. |
11180 ;; Operand0 is the addresss of the function to call | 10834 ;; Operand0 is the addresss of the function to call |
11181 ;; Operand2 is the offset of the stack location holding the current TOC pointer | 10835 ;; Operand2 is the offset of the stack location holding the current TOC pointer |
11182 | 10836 |
11183 (define_insn "*call_indirect_elfv2<mode>" | 10837 (define_insn "*call_indirect_elfv2<mode>" |
11184 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) | 10838 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) |
11185 (match_operand 1 "" "g,g")) | 10839 (match_operand 1 "" "g,g")) |
11186 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) | 10840 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) |
11187 (clobber (reg:P LR_REGNO))] | 10841 (clobber (reg:P LR_REGNO))] |
11188 "DEFAULT_ABI == ABI_ELFv2" | 10842 "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps" |
11189 "b%T0l\;<ptrload> 2,%2(1)" | 10843 "b%T0l\;<ptrload> 2,%2(1)" |
11190 [(set_attr "type" "jmpreg") | 10844 [(set_attr "type" "jmpreg") |
11191 (set_attr "length" "8")]) | 10845 (set_attr "length" "8")]) |
10846 | |
10847 ;; Variant with deliberate misprediction. | |
10848 (define_insn "*call_indirect_elfv2<mode>_nospec" | |
10849 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) | |
10850 (match_operand 1 "" "g,g")) | |
10851 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) | |
10852 (clobber (reg:P LR_REGNO))] | |
10853 "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps" | |
10854 "crset 2\;beq%T0l-\;<ptrload> 2,%2(1)" | |
10855 [(set_attr "type" "jmpreg") | |
10856 (set_attr "length" "12")]) | |
11192 | 10857 |
11193 (define_insn "*call_value_indirect_elfv2<mode>" | 10858 (define_insn "*call_value_indirect_elfv2<mode>" |
11194 [(set (match_operand 0 "" "") | 10859 [(set (match_operand 0 "" "") |
11195 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) | 10860 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) |
11196 (match_operand 2 "" "g,g"))) | 10861 (match_operand 2 "" "g,g"))) |
11197 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) | 10862 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) |
11198 (clobber (reg:P LR_REGNO))] | 10863 (clobber (reg:P LR_REGNO))] |
11199 "DEFAULT_ABI == ABI_ELFv2" | 10864 "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps" |
11200 "b%T1l\;<ptrload> 2,%3(1)" | 10865 "b%T1l\;<ptrload> 2,%3(1)" |
11201 [(set_attr "type" "jmpreg") | 10866 [(set_attr "type" "jmpreg") |
11202 (set_attr "length" "8")]) | 10867 (set_attr "length" "8")]) |
11203 | 10868 |
10869 ; Variant with deliberate misprediction. | |
10870 (define_insn "*call_value_indirect_elfv2<mode>_nospec" | |
10871 [(set (match_operand 0 "" "") | |
10872 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) | |
10873 (match_operand 2 "" "g,g"))) | |
10874 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) | |
10875 (clobber (reg:P LR_REGNO))] | |
10876 "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps" | |
10877 "crset 2\;beq%T1l-\;<ptrload> 2,%3(1)" | |
10878 [(set_attr "type" "jmpreg") | |
10879 (set_attr "length" "12")]) | |
11204 | 10880 |
11205 ;; Call subroutine returning any type. | 10881 ;; Call subroutine returning any type. |
11206 (define_expand "untyped_call" | 10882 (define_expand "untyped_call" |
11207 [(parallel [(call (match_operand 0 "" "") | 10883 [(parallel [(call (match_operand 0 "") |
11208 (const_int 0)) | 10884 (const_int 0)) |
11209 (match_operand 1 "" "") | 10885 (match_operand 1 "") |
11210 (match_operand 2 "" "")])] | 10886 (match_operand 2 "")])] |
11211 "" | 10887 "" |
11212 " | |
11213 { | 10888 { |
11214 int i; | 10889 int i; |
11215 | 10890 |
11216 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx)); | 10891 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx)); |
11217 | 10892 |
11226 claiming that all hard registers are used and clobbered at this | 10901 claiming that all hard registers are used and clobbered at this |
11227 point. */ | 10902 point. */ |
11228 emit_insn (gen_blockage ()); | 10903 emit_insn (gen_blockage ()); |
11229 | 10904 |
11230 DONE; | 10905 DONE; |
11231 }") | 10906 }) |
11232 | 10907 |
11233 ;; sibling call patterns | 10908 ;; sibling call patterns |
11234 (define_expand "sibcall" | 10909 (define_expand "sibcall" |
11235 [(parallel [(call (mem:SI (match_operand 0 "address_operand" "")) | 10910 [(parallel [(call (mem:SI (match_operand 0 "address_operand")) |
11236 (match_operand 1 "" "")) | 10911 (match_operand 1 "")) |
11237 (use (match_operand 2 "" "")) | 10912 (use (match_operand 2 "")) |
11238 (simple_return)])] | 10913 (simple_return)])] |
11239 "" | 10914 "" |
11240 " | |
11241 { | 10915 { |
11242 #if TARGET_MACHO | 10916 #if TARGET_MACHO |
11243 if (MACHOPIC_INDIRECT) | 10917 if (MACHOPIC_INDIRECT) |
11244 operands[0] = machopic_indirect_call_target (operands[0]); | 10918 operands[0] = machopic_indirect_call_target (operands[0]); |
11245 #endif | 10919 #endif |
11252 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) | 10926 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) |
11253 { | 10927 { |
11254 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]); | 10928 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]); |
11255 DONE; | 10929 DONE; |
11256 } | 10930 } |
11257 }") | 10931 }) |
11258 | 10932 |
11259 (define_expand "sibcall_value" | 10933 (define_expand "sibcall_value" |
11260 [(parallel [(set (match_operand 0 "register_operand" "") | 10934 [(parallel [(set (match_operand 0 "register_operand") |
11261 (call (mem:SI (match_operand 1 "address_operand" "")) | 10935 (call (mem:SI (match_operand 1 "address_operand")) |
11262 (match_operand 2 "" ""))) | 10936 (match_operand 2 ""))) |
11263 (use (match_operand 3 "" "")) | 10937 (use (match_operand 3 "")) |
11264 (simple_return)])] | 10938 (simple_return)])] |
11265 "" | 10939 "" |
11266 " | |
11267 { | 10940 { |
11268 #if TARGET_MACHO | 10941 #if TARGET_MACHO |
11269 if (MACHOPIC_INDIRECT) | 10942 if (MACHOPIC_INDIRECT) |
11270 operands[1] = machopic_indirect_call_target (operands[1]); | 10943 operands[1] = machopic_indirect_call_target (operands[1]); |
11271 #endif | 10944 #endif |
11278 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) | 10951 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) |
11279 { | 10952 { |
11280 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]); | 10953 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]); |
11281 DONE; | 10954 DONE; |
11282 } | 10955 } |
11283 }") | 10956 }) |
11284 | 10957 |
11285 (define_insn "*sibcall_local32" | 10958 (define_insn "*sibcall_local32" |
11286 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s")) | 10959 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s")) |
11287 (match_operand 1 "" "g,g")) | 10960 (match_operand 1 "" "g,g")) |
11288 (use (match_operand:SI 2 "immediate_operand" "O,n")) | 10961 (use (match_operand:SI 2 "immediate_operand" "O,n")) |
11289 (simple_return)] | 10962 (simple_return)] |
11290 "(INTVAL (operands[2]) & CALL_LONG) == 0" | 10963 "(INTVAL (operands[2]) & CALL_LONG) == 0" |
11291 "* | |
11292 { | 10964 { |
11293 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) | 10965 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) |
11294 output_asm_insn (\"crxor 6,6,6\", operands); | 10966 output_asm_insn ("crxor 6,6,6", operands); |
11295 | 10967 |
11296 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) | 10968 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) |
11297 output_asm_insn (\"creqv 6,6,6\", operands); | 10969 output_asm_insn ("creqv 6,6,6", operands); |
11298 | 10970 |
11299 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\"; | 10971 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0"; |
11300 }" | 10972 } |
11301 [(set_attr "type" "branch") | 10973 [(set_attr "type" "branch") |
11302 (set_attr "length" "4,8")]) | 10974 (set_attr "length" "4,8")]) |
11303 | 10975 |
11304 (define_insn "*sibcall_local64" | 10976 (define_insn "*sibcall_local64" |
11305 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s")) | 10977 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s")) |
11306 (match_operand 1 "" "g,g")) | 10978 (match_operand 1 "" "g,g")) |
11307 (use (match_operand:SI 2 "immediate_operand" "O,n")) | 10979 (use (match_operand:SI 2 "immediate_operand" "O,n")) |
11308 (simple_return)] | 10980 (simple_return)] |
11309 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0" | 10981 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0" |
11310 "* | |
11311 { | 10982 { |
11312 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) | 10983 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) |
11313 output_asm_insn (\"crxor 6,6,6\", operands); | 10984 output_asm_insn ("crxor 6,6,6", operands); |
11314 | 10985 |
11315 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) | 10986 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) |
11316 output_asm_insn (\"creqv 6,6,6\", operands); | 10987 output_asm_insn ("creqv 6,6,6", operands); |
11317 | 10988 |
11318 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\"; | 10989 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0"; |
11319 }" | 10990 } |
11320 [(set_attr "type" "branch") | 10991 [(set_attr "type" "branch") |
11321 (set_attr "length" "4,8")]) | 10992 (set_attr "length" "4,8")]) |
11322 | 10993 |
11323 (define_insn "*sibcall_value_local32" | 10994 (define_insn "*sibcall_value_local32" |
11324 [(set (match_operand 0 "" "") | 10995 [(set (match_operand 0 "" "") |
11325 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s")) | 10996 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s")) |
11326 (match_operand 2 "" "g,g"))) | 10997 (match_operand 2 "" "g,g"))) |
11327 (use (match_operand:SI 3 "immediate_operand" "O,n")) | 10998 (use (match_operand:SI 3 "immediate_operand" "O,n")) |
11328 (simple_return)] | 10999 (simple_return)] |
11329 "(INTVAL (operands[3]) & CALL_LONG) == 0" | 11000 "(INTVAL (operands[3]) & CALL_LONG) == 0" |
11330 "* | |
11331 { | 11001 { |
11332 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) | 11002 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) |
11333 output_asm_insn (\"crxor 6,6,6\", operands); | 11003 output_asm_insn ("crxor 6,6,6", operands); |
11334 | 11004 |
11335 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) | 11005 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) |
11336 output_asm_insn (\"creqv 6,6,6\", operands); | 11006 output_asm_insn ("creqv 6,6,6", operands); |
11337 | 11007 |
11338 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\"; | 11008 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1"; |
11339 }" | 11009 } |
11340 [(set_attr "type" "branch") | 11010 [(set_attr "type" "branch") |
11341 (set_attr "length" "4,8")]) | 11011 (set_attr "length" "4,8")]) |
11342 | 11012 |
11343 (define_insn "*sibcall_value_local64" | 11013 (define_insn "*sibcall_value_local64" |
11344 [(set (match_operand 0 "" "") | 11014 [(set (match_operand 0 "" "") |
11345 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s")) | 11015 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s")) |
11346 (match_operand 2 "" "g,g"))) | 11016 (match_operand 2 "" "g,g"))) |
11347 (use (match_operand:SI 3 "immediate_operand" "O,n")) | 11017 (use (match_operand:SI 3 "immediate_operand" "O,n")) |
11348 (simple_return)] | 11018 (simple_return)] |
11349 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0" | 11019 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0" |
11350 "* | |
11351 { | 11020 { |
11352 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) | 11021 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) |
11353 output_asm_insn (\"crxor 6,6,6\", operands); | 11022 output_asm_insn ("crxor 6,6,6", operands); |
11354 | 11023 |
11355 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) | 11024 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) |
11356 output_asm_insn (\"creqv 6,6,6\", operands); | 11025 output_asm_insn ("creqv 6,6,6", operands); |
11357 | 11026 |
11358 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\"; | 11027 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1"; |
11359 }" | 11028 } |
11360 [(set_attr "type" "branch") | 11029 [(set_attr "type" "branch") |
11361 (set_attr "length" "4,8")]) | 11030 (set_attr "length" "4,8")]) |
11362 | 11031 |
11363 (define_insn "*sibcall_nonlocal_sysv<mode>" | 11032 (define_insn "*sibcall_nonlocal_sysv<mode>" |
11364 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c")) | 11033 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c")) |
11366 (use (match_operand 2 "immediate_operand" "O,n,O,n")) | 11035 (use (match_operand 2 "immediate_operand" "O,n,O,n")) |
11367 (simple_return)] | 11036 (simple_return)] |
11368 "(DEFAULT_ABI == ABI_DARWIN | 11037 "(DEFAULT_ABI == ABI_DARWIN |
11369 || DEFAULT_ABI == ABI_V4) | 11038 || DEFAULT_ABI == ABI_V4) |
11370 && (INTVAL (operands[2]) & CALL_LONG) == 0" | 11039 && (INTVAL (operands[2]) & CALL_LONG) == 0" |
11371 "* | |
11372 { | 11040 { |
11373 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) | 11041 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) |
11374 output_asm_insn (\"crxor 6,6,6\", operands); | 11042 output_asm_insn ("crxor 6,6,6", operands); |
11375 | 11043 |
11376 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) | 11044 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) |
11377 output_asm_insn (\"creqv 6,6,6\", operands); | 11045 output_asm_insn ("creqv 6,6,6", operands); |
11378 | 11046 |
11379 if (which_alternative >= 2) | 11047 if (which_alternative >= 2) |
11380 return \"b%T0\"; | 11048 { |
11049 if (rs6000_speculate_indirect_jumps) | |
11050 return "b%T0"; | |
11051 else | |
11052 /* Can use CR0 since it is volatile across sibcalls. */ | |
11053 return "crset 2\;beq%T0-\;b $"; | |
11054 } | |
11381 else if (DEFAULT_ABI == ABI_V4 && flag_pic) | 11055 else if (DEFAULT_ABI == ABI_V4 && flag_pic) |
11382 { | 11056 { |
11383 gcc_assert (!TARGET_SECURE_PLT); | 11057 gcc_assert (!TARGET_SECURE_PLT); |
11384 return \"b %z0@plt\"; | 11058 return "b %z0@plt"; |
11385 } | 11059 } |
11386 else | 11060 else |
11387 return \"b %z0\"; | 11061 return "b %z0"; |
11388 }" | 11062 } |
11389 [(set_attr "type" "branch") | 11063 [(set_attr "type" "branch") |
11390 (set_attr "length" "4,8,4,8")]) | 11064 (set_attr_alternative "length" |
11065 [(const_string "4") | |
11066 (const_string "8") | |
11067 (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps") | |
11068 (const_int 0)) | |
11069 (const_string "12") | |
11070 (const_string "4")) | |
11071 (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps") | |
11072 (const_int 0)) | |
11073 (const_string "16") | |
11074 (const_string "8"))])]) | |
11391 | 11075 |
11392 (define_insn "*sibcall_value_nonlocal_sysv<mode>" | 11076 (define_insn "*sibcall_value_nonlocal_sysv<mode>" |
11393 [(set (match_operand 0 "" "") | 11077 [(set (match_operand 0 "" "") |
11394 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c")) | 11078 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c")) |
11395 (match_operand 2 "" ""))) | 11079 (match_operand 2 "" ""))) |
11396 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n")) | 11080 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n")) |
11397 (simple_return)] | 11081 (simple_return)] |
11398 "(DEFAULT_ABI == ABI_DARWIN | 11082 "(DEFAULT_ABI == ABI_DARWIN |
11399 || DEFAULT_ABI == ABI_V4) | 11083 || DEFAULT_ABI == ABI_V4) |
11400 && (INTVAL (operands[3]) & CALL_LONG) == 0" | 11084 && (INTVAL (operands[3]) & CALL_LONG) == 0" |
11401 "* | |
11402 { | 11085 { |
11403 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) | 11086 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) |
11404 output_asm_insn (\"crxor 6,6,6\", operands); | 11087 output_asm_insn ("crxor 6,6,6", operands); |
11405 | 11088 |
11406 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) | 11089 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) |
11407 output_asm_insn (\"creqv 6,6,6\", operands); | 11090 output_asm_insn ("creqv 6,6,6", operands); |
11408 | 11091 |
11409 if (which_alternative >= 2) | 11092 if (which_alternative >= 2) |
11410 return \"b%T1\"; | 11093 { |
11094 if (rs6000_speculate_indirect_jumps) | |
11095 return "b%T1"; | |
11096 else | |
11097 /* Can use CR0 since it is volatile across sibcalls. */ | |
11098 return "crset 2\;beq%T1-\;b $"; | |
11099 } | |
11411 else if (DEFAULT_ABI == ABI_V4 && flag_pic) | 11100 else if (DEFAULT_ABI == ABI_V4 && flag_pic) |
11412 { | 11101 { |
11413 gcc_assert (!TARGET_SECURE_PLT); | 11102 gcc_assert (!TARGET_SECURE_PLT); |
11414 return \"b %z1@plt\"; | 11103 return "b %z1@plt"; |
11415 } | 11104 } |
11416 else | 11105 else |
11417 return \"b %z1\"; | 11106 return "b %z1"; |
11418 }" | 11107 } |
11419 [(set_attr "type" "branch") | 11108 [(set_attr "type" "branch") |
11420 (set_attr "length" "4,8,4,8")]) | 11109 (set_attr_alternative "length" |
11110 [(const_string "4") | |
11111 (const_string "8") | |
11112 (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps") | |
11113 (const_int 0)) | |
11114 (const_string "12") | |
11115 (const_string "4")) | |
11116 (if_then_else (eq (symbol_ref "rs6000_speculate_indirect_jumps") | |
11117 (const_int 0)) | |
11118 (const_string "16") | |
11119 (const_string "8"))])]) | |
11421 | 11120 |
11422 ;; AIX ABI sibling call patterns. | 11121 ;; AIX ABI sibling call patterns. |
11423 | 11122 |
11424 (define_insn "*sibcall_aix<mode>" | 11123 (define_insn "*sibcall_aix<mode>" |
11425 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c")) | 11124 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c")) |
11427 (simple_return)] | 11126 (simple_return)] |
11428 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" | 11127 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" |
11429 "@ | 11128 "@ |
11430 b %z0 | 11129 b %z0 |
11431 b%T0" | 11130 b%T0" |
11432 [(set_attr "type" "branch") | 11131 [(set_attr "type" "branch")]) |
11433 (set_attr "length" "4")]) | |
11434 | 11132 |
11435 (define_insn "*sibcall_value_aix<mode>" | 11133 (define_insn "*sibcall_value_aix<mode>" |
11436 [(set (match_operand 0 "" "") | 11134 [(set (match_operand 0 "" "") |
11437 (call (mem:SI (match_operand:P 1 "call_operand" "s,c")) | 11135 (call (mem:SI (match_operand:P 1 "call_operand" "s,c")) |
11438 (match_operand 2 "" "g,g"))) | 11136 (match_operand 2 "" "g,g"))) |
11439 (simple_return)] | 11137 (simple_return)] |
11440 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" | 11138 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" |
11441 "@ | 11139 "@ |
11442 b %z1 | 11140 b %z1 |
11443 b%T1" | 11141 b%T1" |
11444 [(set_attr "type" "branch") | 11142 [(set_attr "type" "branch")]) |
11445 (set_attr "length" "4")]) | |
11446 | 11143 |
11447 <<<<<<< local | 11144 <<<<<<< local |
11448 ======= | 11145 ======= |
11449 (define_insn "*sibcall_value_nonlocal_aix32" | 11146 (define_insn "*sibcall_value_nonlocal_aix32" |
11450 [(set (match_operand 0 "" "") | 11147 [(set (match_operand 0 "" "") |
11596 ;; all of memory. This blocks insns from being moved across this point. | 11293 ;; all of memory. This blocks insns from being moved across this point. |
11597 | 11294 |
11598 (define_insn "blockage" | 11295 (define_insn "blockage" |
11599 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)] | 11296 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)] |
11600 "" | 11297 "" |
11601 "") | 11298 "" |
11299 [(set_attr "length" "0")]) | |
11602 | 11300 |
11603 (define_expand "probe_stack_address" | 11301 (define_expand "probe_stack_address" |
11604 [(use (match_operand 0 "address_operand"))] | 11302 [(use (match_operand 0 "address_operand"))] |
11605 "" | 11303 "" |
11606 { | 11304 { |
11628 (const_string "yes") | 11326 (const_string "yes") |
11629 (const_string "no"))) | 11327 (const_string "no"))) |
11630 (set (attr "indexed") | 11328 (set (attr "indexed") |
11631 (if_then_else (match_operand 0 "indexed_address_mem") | 11329 (if_then_else (match_operand 0 "indexed_address_mem") |
11632 (const_string "yes") | 11330 (const_string "yes") |
11633 (const_string "no"))) | 11331 (const_string "no")))]) |
11634 (set_attr "length" "4")]) | |
11635 | 11332 |
11636 (define_insn "probe_stack_range<P:mode>" | 11333 (define_insn "probe_stack_range<P:mode>" |
11637 [(set (match_operand:P 0 "register_operand" "=&r") | 11334 [(set (match_operand:P 0 "register_operand" "=&r") |
11638 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0") | 11335 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0") |
11639 (match_operand:P 2 "register_operand" "r") | 11336 (match_operand:P 2 "register_operand" "r") |
11649 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc | 11346 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc |
11650 ;; insns, and branches. | 11347 ;; insns, and branches. |
11651 | 11348 |
11652 (define_expand "cbranch<mode>4" | 11349 (define_expand "cbranch<mode>4" |
11653 [(use (match_operator 0 "comparison_operator" | 11350 [(use (match_operator 0 "comparison_operator" |
11654 [(match_operand:GPR 1 "gpc_reg_operand" "") | 11351 [(match_operand:GPR 1 "gpc_reg_operand") |
11655 (match_operand:GPR 2 "reg_or_short_operand" "")])) | 11352 (match_operand:GPR 2 "reg_or_short_operand")])) |
11656 (use (match_operand 3 ""))] | 11353 (use (match_operand 3))] |
11657 "" | 11354 "" |
11658 " | |
11659 { | 11355 { |
11660 /* Take care of the possibility that operands[2] might be negative but | 11356 /* Take care of the possibility that operands[2] might be negative but |
11661 this might be a logical operation. That insn doesn't exist. */ | 11357 this might be a logical operation. That insn doesn't exist. */ |
11662 if (GET_CODE (operands[2]) == CONST_INT | 11358 if (GET_CODE (operands[2]) == CONST_INT |
11663 && INTVAL (operands[2]) < 0) | 11359 && INTVAL (operands[2]) < 0) |
11668 operands[1], operands[2]); | 11364 operands[1], operands[2]); |
11669 } | 11365 } |
11670 | 11366 |
11671 rs6000_emit_cbranch (<MODE>mode, operands); | 11367 rs6000_emit_cbranch (<MODE>mode, operands); |
11672 DONE; | 11368 DONE; |
11673 }") | 11369 }) |
11674 | 11370 |
11675 (define_expand "cbranch<mode>4" | 11371 (define_expand "cbranch<mode>4" |
11676 [(use (match_operator 0 "comparison_operator" | 11372 [(use (match_operator 0 "comparison_operator" |
11677 [(match_operand:FP 1 "gpc_reg_operand" "") | 11373 [(match_operand:FP 1 "gpc_reg_operand") |
11678 (match_operand:FP 2 "gpc_reg_operand" "")])) | 11374 (match_operand:FP 2 "gpc_reg_operand")])) |
11679 (use (match_operand 3 ""))] | 11375 (use (match_operand 3))] |
11680 "" | 11376 "" |
11681 " | |
11682 { | 11377 { |
11683 rs6000_emit_cbranch (<MODE>mode, operands); | 11378 rs6000_emit_cbranch (<MODE>mode, operands); |
11684 DONE; | 11379 DONE; |
11685 }") | 11380 }) |
11686 | 11381 |
11687 (define_expand "cstore<mode>4_signed" | 11382 (define_expand "cstore<mode>4_signed" |
11688 [(use (match_operator 1 "signed_comparison_operator" | 11383 [(use (match_operator 1 "signed_comparison_operator" |
11689 [(match_operand:P 2 "gpc_reg_operand") | 11384 [(match_operand:P 2 "gpc_reg_operand") |
11690 (match_operand:P 3 "gpc_reg_operand")])) | 11385 (match_operand:P 3 "gpc_reg_operand")])) |
11907 [(match_operand:GPR 2 "gpc_reg_operand") | 11602 [(match_operand:GPR 2 "gpc_reg_operand") |
11908 (match_operand:GPR 3 "reg_or_short_operand")])) | 11603 (match_operand:GPR 3 "reg_or_short_operand")])) |
11909 (clobber (match_operand:GPR 0 "gpc_reg_operand"))] | 11604 (clobber (match_operand:GPR 0 "gpc_reg_operand"))] |
11910 "" | 11605 "" |
11911 { | 11606 { |
11912 /* Use ISEL if the user asked for it. */ | |
11913 if (TARGET_ISEL) | |
11914 rs6000_emit_sISEL (<MODE>mode, operands); | |
11915 | |
11916 /* Expanding EQ and NE directly to some machine instructions does not help | 11607 /* Expanding EQ and NE directly to some machine instructions does not help |
11917 but does hurt combine. So don't. */ | 11608 but does hurt combine. So don't. */ |
11918 else if (GET_CODE (operands[1]) == EQ) | 11609 if (GET_CODE (operands[1]) == EQ) |
11919 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3])); | 11610 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3])); |
11920 else if (<MODE>mode == Pmode | 11611 else if (<MODE>mode == Pmode |
11921 && GET_CODE (operands[1]) == NE) | 11612 && GET_CODE (operands[1]) == NE) |
11922 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3])); | 11613 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3])); |
11923 else if (GET_CODE (operands[1]) == NE) | 11614 else if (GET_CODE (operands[1]) == NE) |
11925 rtx tmp = gen_reg_rtx (<MODE>mode); | 11616 rtx tmp = gen_reg_rtx (<MODE>mode); |
11926 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3])); | 11617 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3])); |
11927 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx)); | 11618 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx)); |
11928 } | 11619 } |
11929 | 11620 |
11930 /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu | 11621 /* If ISEL is fast, expand to it. */ |
11622 else if (TARGET_ISEL) | |
11623 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx); | |
11624 | |
11625 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu | |
11931 etc. combinations magically work out just right. */ | 11626 etc. combinations magically work out just right. */ |
11932 else if (<MODE>mode == Pmode | 11627 else if (<MODE>mode == Pmode |
11933 && unsigned_comparison_operator (operands[1], VOIDmode)) | 11628 && unsigned_comparison_operator (operands[1], VOIDmode)) |
11934 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1], | 11629 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1], |
11935 operands[2], operands[3])); | 11630 operands[2], operands[3])); |
12092 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear: | 11787 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear: |
12093 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available. | 11788 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available. |
12094 | 11789 |
12095 (define_peephole2 | 11790 (define_peephole2 |
12096 [(set (match_operand:SI 0 "register_operand") | 11791 [(set (match_operand:SI 0 "register_operand") |
12097 (match_operand:SI 1 "logical_const_operand" "")) | 11792 (match_operand:SI 1 "logical_const_operand")) |
12098 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator" | 11793 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator" |
12099 [(match_dup 0) | 11794 [(match_dup 0) |
12100 (match_operand:SI 2 "logical_const_operand" "")])) | 11795 (match_operand:SI 2 "logical_const_operand")])) |
12101 (set (match_operand:CC 4 "cc_reg_operand" "") | 11796 (set (match_operand:CC 4 "cc_reg_operand") |
12102 (compare:CC (match_operand:SI 5 "gpc_reg_operand" "") | 11797 (compare:CC (match_operand:SI 5 "gpc_reg_operand") |
12103 (match_dup 0))) | 11798 (match_dup 0))) |
12104 (set (pc) | 11799 (set (pc) |
12105 (if_then_else (match_operator 6 "equality_operator" | 11800 (if_then_else (match_operator 6 "equality_operator" |
12106 [(match_dup 4) (const_int 0)]) | 11801 [(match_dup 4) (const_int 0)]) |
12107 (match_operand 7 "" "") | 11802 (match_operand 7 "") |
12108 (match_operand 8 "" "")))] | 11803 (match_operand 8 "")))] |
12109 "peep2_reg_dead_p (3, operands[0]) | 11804 "peep2_reg_dead_p (3, operands[0]) |
12110 && peep2_reg_dead_p (4, operands[4]) | 11805 && peep2_reg_dead_p (4, operands[4]) |
12111 && REGNO (operands[0]) != REGNO (operands[5])" | 11806 && REGNO (operands[0]) != REGNO (operands[5])" |
12112 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9))) | 11807 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9))) |
12113 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10))) | 11808 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10))) |
12126 | 11821 |
12127 operands[9] = GEN_INT (xorv); | 11822 operands[9] = GEN_INT (xorv); |
12128 operands[10] = GEN_INT (sextc); | 11823 operands[10] = GEN_INT (sextc); |
12129 }) | 11824 }) |
12130 | 11825 |
12131 ;; The following two insns don't exist as single insns, but if we provide | |
12132 ;; them, we can swap an add and compare, which will enable us to overlap more | |
12133 ;; of the required delay between a compare and branch. We generate code for | |
12134 ;; them by splitting. | |
12135 | |
12136 (define_insn "" | |
12137 [(set (match_operand:CC 3 "cc_reg_operand" "=y") | |
12138 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r") | |
12139 (match_operand:SI 2 "short_cint_operand" "i"))) | |
12140 (set (match_operand:SI 0 "gpc_reg_operand" "=r") | |
12141 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))] | |
12142 "" | |
12143 "#" | |
12144 [(set_attr "length" "8")]) | |
12145 | |
12146 (define_insn "" | |
12147 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y") | |
12148 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r") | |
12149 (match_operand:SI 2 "u_short_cint_operand" "i"))) | |
12150 (set (match_operand:SI 0 "gpc_reg_operand" "=r") | |
12151 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))] | |
12152 "" | |
12153 "#" | |
12154 [(set_attr "length" "8")]) | |
12155 | |
12156 (define_split | |
12157 [(set (match_operand:CC 3 "cc_reg_operand" "") | |
12158 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "") | |
12159 (match_operand:SI 2 "short_cint_operand" ""))) | |
12160 (set (match_operand:SI 0 "gpc_reg_operand" "") | |
12161 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))] | |
12162 "" | |
12163 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2))) | |
12164 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))]) | |
12165 | |
12166 (define_split | |
12167 [(set (match_operand:CCUNS 3 "cc_reg_operand" "") | |
12168 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "") | |
12169 (match_operand:SI 2 "u_short_cint_operand" ""))) | |
12170 (set (match_operand:SI 0 "gpc_reg_operand" "") | |
12171 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))] | |
12172 "" | |
12173 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2))) | |
12174 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))]) | |
12175 | |
12176 ;; Only need to compare second words if first words equal | 11826 ;; Only need to compare second words if first words equal |
12177 (define_insn "*cmp<mode>_internal1" | 11827 (define_insn "*cmp<mode>_internal1" |
12178 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") | 11828 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") |
12179 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d") | 11829 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d") |
12180 (match_operand:IBM128 2 "gpc_reg_operand" "d")))] | 11830 (match_operand:IBM128 2 "gpc_reg_operand" "d")))] |
12181 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode) | 11831 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode) |
12182 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" | 11832 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" |
12183 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2" | 11833 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2" |
12184 [(set_attr "type" "fpcompare") | 11834 [(set_attr "type" "fpcompare") |
12185 (set_attr "length" "12")]) | 11835 (set_attr "length" "12")]) |
12186 | 11836 |
12187 (define_insn_and_split "*cmp<mode>_internal2" | 11837 (define_insn_and_split "*cmp<mode>_internal2" |
12196 (clobber (match_scratch:DF 8 "=d")) | 11846 (clobber (match_scratch:DF 8 "=d")) |
12197 (clobber (match_scratch:DF 9 "=d")) | 11847 (clobber (match_scratch:DF 9 "=d")) |
12198 (clobber (match_scratch:DF 10 "=d")) | 11848 (clobber (match_scratch:DF 10 "=d")) |
12199 (clobber (match_scratch:GPR 11 "=b"))] | 11849 (clobber (match_scratch:GPR 11 "=b"))] |
12200 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode) | 11850 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode) |
12201 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" | 11851 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" |
12202 "#" | 11852 "#" |
12203 "&& reload_completed" | 11853 "&& reload_completed" |
12204 [(set (match_dup 3) (match_dup 14)) | 11854 [(set (match_dup 3) (match_dup 14)) |
12205 (set (match_dup 4) (match_dup 15)) | 11855 (set (match_dup 4) (match_dup 15)) |
12206 (set (match_dup 9) (abs:DF (match_dup 5))) | 11856 (set (match_dup 9) (abs:DF (match_dup 5))) |
12251 ;; Note that this is probably faster if we can put an insn between the | 11901 ;; Note that this is probably faster if we can put an insn between the |
12252 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most | 11902 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most |
12253 ;; cases the insns below which don't use an intermediate CR field will | 11903 ;; cases the insns below which don't use an intermediate CR field will |
12254 ;; be used instead. | 11904 ;; be used instead. |
12255 (define_insn "" | 11905 (define_insn "" |
12256 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") | 11906 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") |
12257 (match_operator:SI 1 "scc_comparison_operator" | 11907 (match_operator:GPR 1 "scc_comparison_operator" |
12258 [(match_operand 2 "cc_reg_operand" "y") | 11908 [(match_operand 2 "cc_reg_operand" "y") |
12259 (const_int 0)]))] | 11909 (const_int 0)]))] |
12260 "" | 11910 "" |
12261 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1" | 11911 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1" |
12262 [(set (attr "type") | 11912 [(set (attr "type") |
12263 (cond [(match_test "TARGET_MFCRF") | 11913 (cond [(match_test "TARGET_MFCRF") |
12264 (const_string "mfcrf") | 11914 (const_string "mfcrf") |
12265 ] | 11915 ] |
12266 (const_string "mfcr"))) | 11916 (const_string "mfcr"))) |
12267 (set_attr "length" "8")]) | 11917 (set_attr "length" "8")]) |
12268 | 11918 |
12269 ;; Same as above, but get the OV/ORDERED bit. | 11919 (define_insn_and_split "" |
12270 (define_insn "move_from_CR_ov_bit" | |
12271 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") | |
12272 (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")] | |
12273 UNSPEC_MV_CR_OV))] | |
12274 "TARGET_ISEL" | |
12275 "mfcr %0\;rlwinm %0,%0,%t1,1" | |
12276 [(set_attr "type" "mfcr") | |
12277 (set_attr "length" "8")]) | |
12278 | |
12279 (define_insn "" | |
12280 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") | |
12281 (match_operator:DI 1 "scc_comparison_operator" | |
12282 [(match_operand 2 "cc_reg_operand" "y") | |
12283 (const_int 0)]))] | |
12284 "TARGET_POWERPC64" | |
12285 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1" | |
12286 [(set (attr "type") | |
12287 (cond [(match_test "TARGET_MFCRF") | |
12288 (const_string "mfcrf") | |
12289 ] | |
12290 (const_string "mfcr"))) | |
12291 (set_attr "length" "8")]) | |
12292 | |
12293 (define_insn "" | |
12294 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") | 11920 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") |
12295 (compare:CC (match_operator:SI 1 "scc_comparison_operator" | 11921 (compare:CC (match_operator:SI 1 "scc_comparison_operator" |
12296 [(match_operand 2 "cc_reg_operand" "y,y") | 11922 [(match_operand 2 "cc_reg_operand" "y,y") |
12297 (const_int 0)]) | 11923 (const_int 0)]) |
12298 (const_int 0))) | 11924 (const_int 0))) |
12300 (match_op_dup 1 [(match_dup 2) (const_int 0)]))] | 11926 (match_op_dup 1 [(match_dup 2) (const_int 0)]))] |
12301 "TARGET_32BIT" | 11927 "TARGET_32BIT" |
12302 "@ | 11928 "@ |
12303 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1 | 11929 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1 |
12304 #" | 11930 #" |
12305 [(set_attr "type" "shift") | 11931 "&& reload_completed" |
12306 (set_attr "dot" "yes") | |
12307 (set_attr "length" "8,16")]) | |
12308 | |
12309 (define_split | |
12310 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") | |
12311 (compare:CC (match_operator:SI 1 "scc_comparison_operator" | |
12312 [(match_operand 2 "cc_reg_operand" "") | |
12313 (const_int 0)]) | |
12314 (const_int 0))) | |
12315 (set (match_operand:SI 3 "gpc_reg_operand" "") | |
12316 (match_op_dup 1 [(match_dup 2) (const_int 0)]))] | |
12317 "TARGET_32BIT && reload_completed" | |
12318 [(set (match_dup 3) | 11932 [(set (match_dup 3) |
12319 (match_op_dup 1 [(match_dup 2) (const_int 0)])) | 11933 (match_op_dup 1 [(match_dup 2) (const_int 0)])) |
12320 (set (match_dup 0) | 11934 (set (match_dup 0) |
12321 (compare:CC (match_dup 3) | 11935 (compare:CC (match_dup 3) |
12322 (const_int 0)))] | 11936 (const_int 0)))] |
12323 "") | 11937 "" |
11938 [(set_attr "type" "shift") | |
11939 (set_attr "dot" "yes") | |
11940 (set_attr "length" "8,16")]) | |
12324 | 11941 |
12325 (define_insn "" | 11942 (define_insn "" |
12326 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") | 11943 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") |
12327 (ashift:SI (match_operator:SI 1 "scc_comparison_operator" | 11944 (ashift:SI (match_operator:SI 1 "scc_comparison_operator" |
12328 [(match_operand 2 "cc_reg_operand" "y") | 11945 [(match_operand 2 "cc_reg_operand" "y") |
12329 (const_int 0)]) | 11946 (const_int 0)]) |
12330 (match_operand:SI 3 "const_int_operand" "n")))] | 11947 (match_operand:SI 3 "const_int_operand" "n")))] |
12331 "" | 11948 "" |
12332 "* | |
12333 { | 11949 { |
12334 int is_bit = ccr_bit (operands[1], 1); | 11950 int is_bit = ccr_bit (operands[1], 1); |
12335 int put_bit = 31 - (INTVAL (operands[3]) & 31); | 11951 int put_bit = 31 - (INTVAL (operands[3]) & 31); |
12336 int count; | 11952 int count; |
12337 | 11953 |
12341 count = 32 - (put_bit - is_bit); | 11957 count = 32 - (put_bit - is_bit); |
12342 | 11958 |
12343 operands[4] = GEN_INT (count); | 11959 operands[4] = GEN_INT (count); |
12344 operands[5] = GEN_INT (put_bit); | 11960 operands[5] = GEN_INT (put_bit); |
12345 | 11961 |
12346 return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\"; | 11962 return "mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5"; |
12347 }" | 11963 } |
12348 [(set (attr "type") | 11964 [(set (attr "type") |
12349 (cond [(match_test "TARGET_MFCRF") | 11965 (cond [(match_test "TARGET_MFCRF") |
12350 (const_string "mfcrf") | 11966 (const_string "mfcrf") |
12351 ] | 11967 ] |
12352 (const_string "mfcr"))) | 11968 (const_string "mfcr"))) |
12362 (const_int 0))) | 11978 (const_int 0))) |
12363 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r") | 11979 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r") |
12364 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)]) | 11980 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)]) |
12365 (match_dup 3)))] | 11981 (match_dup 3)))] |
12366 "" | 11982 "" |
12367 "* | |
12368 { | 11983 { |
12369 int is_bit = ccr_bit (operands[1], 1); | 11984 int is_bit = ccr_bit (operands[1], 1); |
12370 int put_bit = 31 - (INTVAL (operands[3]) & 31); | 11985 int put_bit = 31 - (INTVAL (operands[3]) & 31); |
12371 int count; | 11986 int count; |
12372 | 11987 |
12373 /* Force split for non-cc0 compare. */ | 11988 /* Force split for non-cc0 compare. */ |
12374 if (which_alternative == 1) | 11989 if (which_alternative == 1) |
12375 return \"#\"; | 11990 return "#"; |
12376 | 11991 |
12377 if (is_bit >= put_bit) | 11992 if (is_bit >= put_bit) |
12378 count = is_bit - put_bit; | 11993 count = is_bit - put_bit; |
12379 else | 11994 else |
12380 count = 32 - (put_bit - is_bit); | 11995 count = 32 - (put_bit - is_bit); |
12381 | 11996 |
12382 operands[5] = GEN_INT (count); | 11997 operands[5] = GEN_INT (count); |
12383 operands[6] = GEN_INT (put_bit); | 11998 operands[6] = GEN_INT (put_bit); |
12384 | 11999 |
12385 return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\"; | 12000 return "mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6"; |
12386 }" | 12001 } |
12387 [(set_attr "type" "shift") | 12002 [(set_attr "type" "shift") |
12388 (set_attr "dot" "yes") | 12003 (set_attr "dot" "yes") |
12389 (set_attr "length" "8,16")]) | 12004 (set_attr "length" "8,16")]) |
12390 | 12005 |
12391 (define_split | 12006 (define_split |
12407 (compare:CC (match_dup 4) | 12022 (compare:CC (match_dup 4) |
12408 (const_int 0)))] | 12023 (const_int 0)))] |
12409 "") | 12024 "") |
12410 | 12025 |
12411 | 12026 |
12027 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu]) | |
12028 (define_code_attr UNS [(eq "CC") | |
12029 (ne "CC") | |
12030 (lt "CC") (ltu "CCUNS") | |
12031 (gt "CC") (gtu "CCUNS") | |
12032 (le "CC") (leu "CCUNS") | |
12033 (ge "CC") (geu "CCUNS")]) | |
12034 (define_code_attr UNSu_ [(eq "") | |
12035 (ne "") | |
12036 (lt "") (ltu "u_") | |
12037 (gt "") (gtu "u_") | |
12038 (le "") (leu "u_") | |
12039 (ge "") (geu "u_")]) | |
12040 (define_code_attr UNSIK [(eq "I") | |
12041 (ne "I") | |
12042 (lt "I") (ltu "K") | |
12043 (gt "I") (gtu "K") | |
12044 (le "I") (leu "K") | |
12045 (ge "I") (geu "K")]) | |
12046 | |
12047 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel" | |
12048 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") | |
12049 (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r") | |
12050 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>"))) | |
12051 (clobber (match_scratch:GPR 3 "=r")) | |
12052 (clobber (match_scratch:GPR 4 "=r")) | |
12053 (clobber (match_scratch:<UNS> 5 "=y"))] | |
12054 "TARGET_ISEL | |
12055 && !(<CODE> == EQ && operands[2] == const0_rtx) | |
12056 && !(<CODE> == NE && operands[2] == const0_rtx | |
12057 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)" | |
12058 "#" | |
12059 "&& 1" | |
12060 [(pc)] | |
12061 { | |
12062 rtx_code code = <CODE>; | |
12063 if (CONST_INT_P (operands[2]) && code != EQ && code != NE) | |
12064 { | |
12065 HOST_WIDE_INT val = INTVAL (operands[2]); | |
12066 if (code == LT && val != -0x8000) | |
12067 { | |
12068 code = LE; | |
12069 val--; | |
12070 } | |
12071 if (code == GT && val != 0x7fff) | |
12072 { | |
12073 code = GE; | |
12074 val++; | |
12075 } | |
12076 if (code == LTU && val != 0) | |
12077 { | |
12078 code = LEU; | |
12079 val--; | |
12080 } | |
12081 if (code == GTU && val != 0xffff) | |
12082 { | |
12083 code = GEU; | |
12084 val++; | |
12085 } | |
12086 operands[2] = GEN_INT (val); | |
12087 } | |
12088 | |
12089 if (code == NE || code == LE || code == GE || code == LEU || code == GEU) | |
12090 operands[3] = const0_rtx; | |
12091 else | |
12092 { | |
12093 if (GET_CODE (operands[3]) == SCRATCH) | |
12094 operands[3] = gen_reg_rtx (<GPR:MODE>mode); | |
12095 emit_move_insn (operands[3], const0_rtx); | |
12096 } | |
12097 | |
12098 if (GET_CODE (operands[4]) == SCRATCH) | |
12099 operands[4] = gen_reg_rtx (<GPR:MODE>mode); | |
12100 emit_move_insn (operands[4], const1_rtx); | |
12101 | |
12102 if (GET_CODE (operands[5]) == SCRATCH) | |
12103 operands[5] = gen_reg_rtx (<UNS>mode); | |
12104 | |
12105 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]); | |
12106 emit_insn (gen_rtx_SET (operands[5], c1)); | |
12107 | |
12108 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx); | |
12109 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]); | |
12110 emit_move_insn (operands[0], x); | |
12111 | |
12112 DONE; | |
12113 } | |
12114 [(set (attr "cost") | |
12115 (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ) | |
12116 || <CODE> == NE | |
12117 || <CODE> == LE || <CODE> == GE | |
12118 || <CODE> == LEU || <CODE> == GEU") | |
12119 (const_string "9") | |
12120 (const_string "10")))]) | |
12121 | |
12412 (define_mode_attr scc_eq_op2 [(SI "rKLI") | 12122 (define_mode_attr scc_eq_op2 [(SI "rKLI") |
12413 (DI "rKJI")]) | 12123 (DI "rKJI")]) |
12414 | 12124 |
12415 (define_insn_and_split "eq<mode>3" | 12125 (define_expand "eq<mode>3" |
12126 [(parallel [ | |
12127 (set (match_operand:GPR 0 "gpc_reg_operand" "=r") | |
12128 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") | |
12129 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>"))) | |
12130 (clobber (match_scratch:GPR 3 "=r")) | |
12131 (clobber (match_scratch:GPR 4 "=r"))])] | |
12132 "" | |
12133 { | |
12134 if (TARGET_ISEL && operands[2] != const0_rtx) | |
12135 { | |
12136 emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1], | |
12137 operands[2])); | |
12138 DONE; | |
12139 } | |
12140 }) | |
12141 | |
12142 (define_insn_and_split "*eq<mode>3" | |
12416 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") | 12143 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") |
12417 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") | 12144 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") |
12418 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>"))) | 12145 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>"))) |
12419 (clobber (match_scratch:GPR 3 "=r")) | 12146 (clobber (match_scratch:GPR 3 "=r")) |
12420 (clobber (match_scratch:GPR 4 "=r"))] | 12147 (clobber (match_scratch:GPR 4 "=r"))] |
12421 "" | 12148 "!(TARGET_ISEL && operands[2] != const0_rtx)" |
12422 "#" | 12149 "#" |
12423 "" | 12150 "&& 1" |
12424 [(set (match_dup 4) | 12151 [(set (match_dup 4) |
12425 (clz:GPR (match_dup 3))) | 12152 (clz:GPR (match_dup 3))) |
12426 (set (match_dup 0) | 12153 (set (match_dup 0) |
12427 (lshiftrt:GPR (match_dup 4) | 12154 (lshiftrt:GPR (match_dup 4) |
12428 (match_dup 5)))] | 12155 (match_dup 5)))] |
12438 [(set (attr "length") | 12165 [(set (attr "length") |
12439 (if_then_else (match_test "operands[2] == const0_rtx") | 12166 (if_then_else (match_test "operands[2] == const0_rtx") |
12440 (const_string "8") | 12167 (const_string "8") |
12441 (const_string "12")))]) | 12168 (const_string "12")))]) |
12442 | 12169 |
12443 (define_insn_and_split "ne<mode>3" | 12170 (define_expand "ne<mode>3" |
12171 [(parallel [ | |
12172 (set (match_operand:P 0 "gpc_reg_operand" "=r") | |
12173 (ne:P (match_operand:P 1 "gpc_reg_operand" "r") | |
12174 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))) | |
12175 (clobber (match_scratch:P 3 "=r")) | |
12176 (clobber (match_scratch:P 4 "=r")) | |
12177 (clobber (reg:P CA_REGNO))])] | |
12178 "" | |
12179 { | |
12180 if (TARGET_ISEL && operands[2] != const0_rtx) | |
12181 { | |
12182 emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1], | |
12183 operands[2])); | |
12184 DONE; | |
12185 } | |
12186 }) | |
12187 | |
12188 (define_insn_and_split "*ne<mode>3" | |
12444 [(set (match_operand:P 0 "gpc_reg_operand" "=r") | 12189 [(set (match_operand:P 0 "gpc_reg_operand" "=r") |
12445 (ne:P (match_operand:P 1 "gpc_reg_operand" "r") | 12190 (ne:P (match_operand:P 1 "gpc_reg_operand" "r") |
12446 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))) | 12191 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))) |
12447 (clobber (match_scratch:P 3 "=r")) | 12192 (clobber (match_scratch:P 3 "=r")) |
12448 (clobber (match_scratch:P 4 "=r")) | 12193 (clobber (match_scratch:P 4 "=r")) |
12449 (clobber (reg:P CA_REGNO))] | 12194 (clobber (reg:P CA_REGNO))] |
12450 "!TARGET_ISEL" | 12195 "!(TARGET_ISEL && operands[2] != const0_rtx)" |
12451 "#" | 12196 "#" |
12452 "" | 12197 "&& 1" |
12453 [(parallel [(set (match_dup 4) | 12198 [(parallel [(set (match_dup 4) |
12454 (plus:P (match_dup 3) | 12199 (plus:P (match_dup 3) |
12455 (const_int -1))) | 12200 (const_int -1))) |
12456 (set (reg:P CA_REGNO) | 12201 (set (reg:P CA_REGNO) |
12457 (ne:P (match_dup 3) | 12202 (ne:P (match_dup 3) |
12700 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r") | 12445 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r") |
12701 (match_operand:SI 2 "scc_eq_operand" "rKLI"))) | 12446 (match_operand:SI 2 "scc_eq_operand" "rKLI"))) |
12702 (clobber (match_scratch:SI 3 "=r")) | 12447 (clobber (match_scratch:SI 3 "=r")) |
12703 (clobber (match_scratch:SI 4 "=r")) | 12448 (clobber (match_scratch:SI 4 "=r")) |
12704 (clobber (match_scratch:EXTSI 5 "=r"))] | 12449 (clobber (match_scratch:EXTSI 5 "=r"))] |
12705 "" | 12450 "!TARGET_ISEL" |
12706 "#" | 12451 "#" |
12707 "" | 12452 "&& 1" |
12708 [(set (match_dup 4) | 12453 [(set (match_dup 4) |
12709 (clz:SI (match_dup 3))) | 12454 (clz:SI (match_dup 3))) |
12710 (set (match_dup 5) | 12455 (set (match_dup 5) |
12711 (zero_extend:EXTSI | 12456 (zero_extend:EXTSI |
12712 (lshiftrt:SI (match_dup 4) | 12457 (lshiftrt:SI (match_dup 4) |
12726 [(set (attr "length") | 12471 [(set (attr "length") |
12727 (if_then_else (match_test "operands[2] == const0_rtx") | 12472 (if_then_else (match_test "operands[2] == const0_rtx") |
12728 (const_string "12") | 12473 (const_string "12") |
12729 (const_string "16")))]) | 12474 (const_string "16")))]) |
12730 | 12475 |
12731 ;; Define both directions of branch and return. If we need a reload | 12476 ;; Conditional branches. |
12732 ;; register, we'd rather use CR0 since it is much easier to copy a | 12477 ;; These either are a single bc insn, or a bc around a b. |
12733 ;; register CC value to there. | 12478 |
12734 | 12479 (define_insn "*cbranch" |
12735 (define_insn "" | |
12736 [(set (pc) | 12480 [(set (pc) |
12737 (if_then_else (match_operator 1 "branch_comparison_operator" | 12481 (if_then_else (match_operator 1 "branch_comparison_operator" |
12738 [(match_operand 2 "cc_reg_operand" "y") | 12482 [(match_operand 2 "cc_reg_operand" "y") |
12739 (const_int 0)]) | 12483 (const_int 0)]) |
12740 (label_ref (match_operand 0)) | 12484 (label_ref (match_operand 0)) |
12741 (pc)))] | 12485 (pc)))] |
12742 "" | 12486 "" |
12743 { | 12487 { |
12744 return output_cbranch (operands[1], "%l0", 0, insn); | 12488 return output_cbranch (operands[1], "%l0", 0, insn); |
12745 } | 12489 } |
12746 [(set_attr "type" "branch")]) | 12490 [(set_attr "type" "branch") |
12747 | 12491 (set (attr "length") |
12748 (define_insn "" | 12492 (if_then_else (and (ge (minus (match_dup 0) (pc)) |
12493 (const_int -32768)) | |
12494 (lt (minus (match_dup 0) (pc)) | |
12495 (const_int 32764))) | |
12496 (const_int 4) | |
12497 (const_int 8)))]) | |
12498 | |
12499 ;; Conditional return. | |
12500 (define_insn "*creturn" | |
12749 [(set (pc) | 12501 [(set (pc) |
12750 (if_then_else (match_operator 0 "branch_comparison_operator" | 12502 (if_then_else (match_operator 0 "branch_comparison_operator" |
12751 [(match_operand 1 "cc_reg_operand" "y") | 12503 [(match_operand 1 "cc_reg_operand" "y") |
12752 (const_int 0)]) | 12504 (const_int 0)]) |
12753 (any_return) | 12505 (any_return) |
12754 (pc)))] | 12506 (pc)))] |
12755 "<return_pred>" | 12507 "<return_pred>" |
12756 { | 12508 { |
12757 return output_cbranch (operands[0], NULL, 0, insn); | 12509 return output_cbranch (operands[0], NULL, 0, insn); |
12758 } | 12510 } |
12759 [(set_attr "type" "jmpreg") | 12511 [(set_attr "type" "jmpreg")]) |
12760 (set_attr "length" "4")]) | |
12761 | 12512 |
12762 ;; Logic on condition register values. | 12513 ;; Logic on condition register values. |
12763 | 12514 |
12764 ; This pattern matches things like | 12515 ; This pattern matches things like |
12765 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0)) | 12516 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0)) |
12766 ; (eq:SI (reg:CCFP 68) (const_int 0))) | 12517 ; (eq:SI (reg:CCFP 68) (const_int 0))) |
12767 ; (const_int 1))) | 12518 ; (const_int 1))) |
12768 ; which are generated by the branch logic. | 12519 ; which are generated by the branch logic. |
12769 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB) | 12520 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB) |
12770 | 12521 |
12771 (define_insn "*cceq_ior_compare" | 12522 (define_insn "cceq_ior_compare" |
12772 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") | 12523 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") |
12773 (compare:CCEQ (match_operator:SI 1 "boolean_operator" | 12524 (compare:CCEQ (match_operator:SI 1 "boolean_operator" |
12774 [(match_operator:SI 2 | 12525 [(match_operator:SI 2 |
12775 "branch_positive_comparison_operator" | 12526 "branch_positive_comparison_operator" |
12776 [(match_operand 3 | 12527 [(match_operand 3 |
12782 "cc_reg_operand" "0,y") | 12533 "cc_reg_operand" "0,y") |
12783 (const_int 0)])]) | 12534 (const_int 0)])]) |
12784 (const_int 1)))] | 12535 (const_int 1)))] |
12785 "" | 12536 "" |
12786 "cr%q1 %E0,%j2,%j4" | 12537 "cr%q1 %E0,%j2,%j4" |
12787 [(set_attr "type" "cr_logical,delayed_cr")]) | 12538 [(set_attr "type" "cr_logical") |
12539 (set_attr "cr_logical_3op" "no,yes")]) | |
12788 | 12540 |
12789 ; Why is the constant -1 here, but 1 in the previous pattern? | 12541 ; Why is the constant -1 here, but 1 in the previous pattern? |
12790 ; Because ~1 has all but the low bit set. | 12542 ; Because ~1 has all but the low bit set. |
12791 (define_insn "" | 12543 (define_insn "cceq_ior_compare_complement" |
12792 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") | 12544 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") |
12793 (compare:CCEQ (match_operator:SI 1 "boolean_or_operator" | 12545 (compare:CCEQ (match_operator:SI 1 "boolean_operator" |
12794 [(not:SI (match_operator:SI 2 | 12546 [(not:SI (match_operator:SI 2 |
12795 "branch_positive_comparison_operator" | 12547 "branch_positive_comparison_operator" |
12796 [(match_operand 3 | 12548 [(match_operand 3 |
12797 "cc_reg_operand" "y,y") | 12549 "cc_reg_operand" "y,y") |
12798 (const_int 0)])) | 12550 (const_int 0)])) |
12802 "cc_reg_operand" "0,y") | 12554 "cc_reg_operand" "0,y") |
12803 (const_int 0)])]) | 12555 (const_int 0)])]) |
12804 (const_int -1)))] | 12556 (const_int -1)))] |
12805 "" | 12557 "" |
12806 "cr%q1 %E0,%j2,%j4" | 12558 "cr%q1 %E0,%j2,%j4" |
12807 [(set_attr "type" "cr_logical,delayed_cr")]) | 12559 [(set_attr "type" "cr_logical") |
12560 (set_attr "cr_logical_3op" "no,yes")]) | |
12808 | 12561 |
12809 (define_insn "*cceq_rev_compare" | 12562 (define_insn "*cceq_rev_compare" |
12810 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") | 12563 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") |
12811 (compare:CCEQ (match_operator:SI 1 | 12564 (compare:CCEQ (match_operator:SI 1 |
12812 "branch_positive_comparison_operator" | 12565 "branch_positive_comparison_operator" |
12814 "cc_reg_operand" "0,y") | 12567 "cc_reg_operand" "0,y") |
12815 (const_int 0)]) | 12568 (const_int 0)]) |
12816 (const_int 0)))] | 12569 (const_int 0)))] |
12817 "" | 12570 "" |
12818 "crnot %E0,%j1" | 12571 "crnot %E0,%j1" |
12819 [(set_attr "type" "cr_logical,delayed_cr")]) | 12572 [(set_attr "type" "cr_logical") |
12573 (set_attr "cr_logical_3op" "no,yes")]) | |
12820 | 12574 |
12821 ;; If we are comparing the result of two comparisons, this can be done | 12575 ;; If we are comparing the result of two comparisons, this can be done |
12822 ;; using creqv or crxor. | 12576 ;; using creqv or crxor. |
12823 | 12577 |
12824 (define_insn_and_split "" | 12578 (define_insn_and_split "" |
12832 "" | 12586 "" |
12833 "#" | 12587 "#" |
12834 "" | 12588 "" |
12835 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3)) | 12589 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3)) |
12836 (match_dup 5)))] | 12590 (match_dup 5)))] |
12837 " | |
12838 { | 12591 { |
12839 int positive_1, positive_2; | 12592 int positive_1, positive_2; |
12840 | 12593 |
12841 positive_1 = branch_positive_comparison_operator (operands[1], | 12594 positive_1 = branch_positive_comparison_operator (operands[1], |
12842 GET_MODE (operands[1])); | 12595 GET_MODE (operands[1])); |
12868 } | 12621 } |
12869 else | 12622 else |
12870 { | 12623 { |
12871 operands[5] = const1_rtx; | 12624 operands[5] = const1_rtx; |
12872 } | 12625 } |
12873 }") | 12626 }) |
12874 | 12627 |
12875 ;; Unconditional branch and return. | 12628 ;; Unconditional branch and return. |
12876 | 12629 |
12877 (define_insn "jump" | 12630 (define_insn "jump" |
12878 [(set (pc) | 12631 [(set (pc) |
12886 "<return_pred>" | 12639 "<return_pred>" |
12887 "blr" | 12640 "blr" |
12888 [(set_attr "type" "jmpreg")]) | 12641 [(set_attr "type" "jmpreg")]) |
12889 | 12642 |
12890 (define_expand "indirect_jump" | 12643 (define_expand "indirect_jump" |
12891 [(set (pc) (match_operand 0 "register_operand"))]) | 12644 [(set (pc) (match_operand 0 "register_operand"))] |
12645 "" | |
12646 { | |
12647 if (!rs6000_speculate_indirect_jumps) { | |
12648 rtx ccreg = gen_reg_rtx (CCmode); | |
12649 if (Pmode == DImode) | |
12650 emit_jump_insn (gen_indirect_jumpdi_nospec (operands[0], ccreg)); | |
12651 else | |
12652 emit_jump_insn (gen_indirect_jumpsi_nospec (operands[0], ccreg)); | |
12653 DONE; | |
12654 } | |
12655 }) | |
12892 | 12656 |
12893 (define_insn "*indirect_jump<mode>" | 12657 (define_insn "*indirect_jump<mode>" |
12894 [(set (pc) | 12658 [(set (pc) |
12895 (match_operand:P 0 "register_operand" "c,*l"))] | 12659 (match_operand:P 0 "register_operand" "c,*l"))] |
12896 "" | 12660 "rs6000_speculate_indirect_jumps" |
12897 "b%T0" | 12661 "b%T0" |
12898 [(set_attr "type" "jmpreg")]) | 12662 [(set_attr "type" "jmpreg")]) |
12663 | |
12664 (define_insn "indirect_jump<mode>_nospec" | |
12665 [(set (pc) (match_operand:P 0 "register_operand" "c,*l")) | |
12666 (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))] | |
12667 "!rs6000_speculate_indirect_jumps" | |
12668 "crset %E1\;beq%T0- %1\;b $" | |
12669 [(set_attr "type" "jmpreg") | |
12670 (set_attr "length" "12")]) | |
12899 | 12671 |
12900 ;; Table jump for switch statements: | 12672 ;; Table jump for switch statements: |
12901 (define_expand "tablejump" | 12673 (define_expand "tablejump" |
12902 [(use (match_operand 0)) | 12674 [(use (match_operand 0)) |
12903 (use (label_ref (match_operand 1)))] | 12675 (use (label_ref (match_operand 1)))] |
12904 "" | 12676 "" |
12905 { | 12677 { |
12906 if (TARGET_32BIT) | 12678 if (rs6000_speculate_indirect_jumps) |
12907 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1])); | 12679 { |
12680 if (TARGET_32BIT) | |
12681 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1])); | |
12682 else | |
12683 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1])); | |
12684 } | |
12908 else | 12685 else |
12909 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1])); | 12686 { |
12687 rtx ccreg = gen_reg_rtx (CCmode); | |
12688 rtx jump; | |
12689 if (TARGET_32BIT) | |
12690 jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg); | |
12691 else | |
12692 jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg); | |
12693 emit_jump_insn (jump); | |
12694 } | |
12910 DONE; | 12695 DONE; |
12911 }) | 12696 }) |
12912 | 12697 |
12913 (define_expand "tablejumpsi" | 12698 (define_expand "tablejumpsi" |
12914 [(set (match_dup 3) | 12699 [(set (match_dup 3) |
12915 (plus:SI (match_operand:SI 0) | 12700 (plus:SI (match_operand:SI 0) |
12916 (match_dup 2))) | 12701 (match_dup 2))) |
12917 (parallel [(set (pc) | 12702 (parallel [(set (pc) |
12918 (match_dup 3)) | 12703 (match_dup 3)) |
12919 (use (label_ref (match_operand 1)))])] | 12704 (use (label_ref (match_operand 1)))])] |
12920 "TARGET_32BIT" | 12705 "TARGET_32BIT && rs6000_speculate_indirect_jumps" |
12921 { | 12706 { |
12922 operands[0] = force_reg (SImode, operands[0]); | 12707 operands[0] = force_reg (SImode, operands[0]); |
12923 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1])); | 12708 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1])); |
12924 operands[3] = gen_reg_rtx (SImode); | 12709 operands[3] = gen_reg_rtx (SImode); |
12710 }) | |
12711 | |
12712 (define_expand "tablejumpsi_nospec" | |
12713 [(set (match_dup 4) | |
12714 (plus:SI (match_operand:SI 0) | |
12715 (match_dup 3))) | |
12716 (parallel [(set (pc) | |
12717 (match_dup 4)) | |
12718 (use (label_ref (match_operand 1))) | |
12719 (clobber (match_operand 2))])] | |
12720 "TARGET_32BIT && !rs6000_speculate_indirect_jumps" | |
12721 { | |
12722 operands[0] = force_reg (SImode, operands[0]); | |
12723 operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1])); | |
12724 operands[4] = gen_reg_rtx (SImode); | |
12925 }) | 12725 }) |
12926 | 12726 |
12927 (define_expand "tablejumpdi" | 12727 (define_expand "tablejumpdi" |
12928 [(set (match_dup 4) | 12728 [(set (match_dup 4) |
12929 (sign_extend:DI (match_operand:SI 0 "lwa_operand"))) | 12729 (sign_extend:DI (match_operand:SI 0 "lwa_operand"))) |
12931 (plus:DI (match_dup 4) | 12731 (plus:DI (match_dup 4) |
12932 (match_dup 2))) | 12732 (match_dup 2))) |
12933 (parallel [(set (pc) | 12733 (parallel [(set (pc) |
12934 (match_dup 3)) | 12734 (match_dup 3)) |
12935 (use (label_ref (match_operand 1)))])] | 12735 (use (label_ref (match_operand 1)))])] |
12936 "TARGET_64BIT" | 12736 "TARGET_64BIT && rs6000_speculate_indirect_jumps" |
12937 { | 12737 { |
12938 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1])); | 12738 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1])); |
12939 operands[3] = gen_reg_rtx (DImode); | 12739 operands[3] = gen_reg_rtx (DImode); |
12940 operands[4] = gen_reg_rtx (DImode); | 12740 operands[4] = gen_reg_rtx (DImode); |
12741 }) | |
12742 | |
12743 (define_expand "tablejumpdi_nospec" | |
12744 [(set (match_dup 5) | |
12745 (sign_extend:DI (match_operand:SI 0 "lwa_operand"))) | |
12746 (set (match_dup 4) | |
12747 (plus:DI (match_dup 5) | |
12748 (match_dup 3))) | |
12749 (parallel [(set (pc) | |
12750 (match_dup 4)) | |
12751 (use (label_ref (match_operand 1))) | |
12752 (clobber (match_operand 2))])] | |
12753 "TARGET_64BIT && !rs6000_speculate_indirect_jumps" | |
12754 { | |
12755 operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1])); | |
12756 operands[4] = gen_reg_rtx (DImode); | |
12757 operands[5] = gen_reg_rtx (DImode); | |
12941 }) | 12758 }) |
12942 | 12759 |
12943 (define_insn "*tablejump<mode>_internal1" | 12760 (define_insn "*tablejump<mode>_internal1" |
12944 [(set (pc) | 12761 [(set (pc) |
12945 (match_operand:P 0 "register_operand" "c,*l")) | 12762 (match_operand:P 0 "register_operand" "c,*l")) |
12946 (use (label_ref (match_operand 1)))] | 12763 (use (label_ref (match_operand 1)))] |
12947 "" | 12764 "rs6000_speculate_indirect_jumps" |
12948 "b%T0" | 12765 "b%T0" |
12949 [(set_attr "type" "jmpreg")]) | 12766 [(set_attr "type" "jmpreg")]) |
12950 | 12767 |
12768 (define_insn "*tablejump<mode>_internal1_nospec" | |
12769 [(set (pc) | |
12770 (match_operand:P 0 "register_operand" "c,*l")) | |
12771 (use (label_ref (match_operand 1))) | |
12772 (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))] | |
12773 "!rs6000_speculate_indirect_jumps" | |
12774 "crset %E2\;beq%T0- %2\;b $" | |
12775 [(set_attr "type" "jmpreg") | |
12776 (set_attr "length" "12")]) | |
12777 | |
12951 (define_insn "nop" | 12778 (define_insn "nop" |
12952 [(unspec [(const_int 0)] UNSPEC_NOP)] | 12779 [(unspec [(const_int 0)] UNSPEC_NOP)] |
12953 "" | 12780 "" |
12954 "nop") | 12781 "nop") |
12955 | 12782 |
12956 (define_insn "group_ending_nop" | 12783 (define_insn "group_ending_nop" |
12957 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)] | 12784 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)] |
12958 "" | 12785 "" |
12959 { | 12786 { |
12960 if (rs6000_cpu_attr == CPU_POWER6) | 12787 if (rs6000_tune == PROCESSOR_POWER6) |
12961 return "ori 1,1,0"; | 12788 return "ori 1,1,0"; |
12962 return "ori 2,2,0"; | 12789 return "ori 2,2,0"; |
12963 }) | 12790 }) |
12791 | |
12792 (define_insn "speculation_barrier" | |
12793 [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)] | |
12794 "" | |
12795 "ori 31,31,0") | |
12964 | 12796 |
12965 ;; Define the subtract-one-and-jump insns, starting with the template | 12797 ;; Define the subtract-one-and-jump insns, starting with the template |
12966 ;; so loop.c knows what to generate. | 12798 ;; so loop.c knows what to generate. |
12967 | 12799 |
12968 (define_expand "doloop_end" | 12800 (define_expand "doloop_end" |
13005 ;; For the length attribute to be calculated correctly, the | 12837 ;; For the length attribute to be calculated correctly, the |
13006 ;; label MUST be operand 0. | 12838 ;; label MUST be operand 0. |
13007 ;; rs6000_legitimate_combined_insn prevents combine creating any of | 12839 ;; rs6000_legitimate_combined_insn prevents combine creating any of |
13008 ;; the ctr<mode> insns. | 12840 ;; the ctr<mode> insns. |
13009 | 12841 |
13010 (define_insn "ctr<mode>_internal1" | 12842 (define_code_iterator eqne [eq ne]) |
12843 (define_code_attr bd [(eq "bdz") (ne "bdnz")]) | |
12844 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")]) | |
12845 | |
12846 (define_insn "<bd>_<mode>" | |
13011 [(set (pc) | 12847 [(set (pc) |
13012 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b") | 12848 (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b") |
13013 (const_int 1)) | 12849 (const_int 1)) |
13014 (label_ref (match_operand 0)) | 12850 (label_ref (match_operand 0)) |
13015 (pc))) | 12851 (pc))) |
13016 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l") | 12852 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l") |
13017 (plus:P (match_dup 1) | 12853 (plus:P (match_dup 1) |
13021 "" | 12857 "" |
13022 { | 12858 { |
13023 if (which_alternative != 0) | 12859 if (which_alternative != 0) |
13024 return "#"; | 12860 return "#"; |
13025 else if (get_attr_length (insn) == 4) | 12861 else if (get_attr_length (insn) == 4) |
13026 return "bdnz %l0"; | 12862 return "<bd> %l0"; |
13027 else | 12863 else |
13028 return "bdz $+8\;b %l0"; | 12864 return "<bd_neg> $+8\;b %l0"; |
13029 } | 12865 } |
13030 [(set_attr "type" "branch") | 12866 [(set_attr "type" "branch") |
13031 (set_attr "length" "*,16,20,20")]) | 12867 (set_attr_alternative "length" |
13032 | 12868 [(if_then_else (and (ge (minus (match_dup 0) (pc)) |
13033 ;; Similar but use EQ | 12869 (const_int -32768)) |
13034 | 12870 (lt (minus (match_dup 0) (pc)) |
13035 (define_insn "ctr<mode>_internal2" | 12871 (const_int 32764))) |
13036 [(set (pc) | 12872 (const_int 4) |
13037 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b") | 12873 (const_int 8)) |
13038 (const_int 1)) | 12874 (const_string "16") |
13039 (label_ref (match_operand 0)) | 12875 (const_string "20") |
13040 (pc))) | 12876 (const_string "20")])]) |
13041 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l") | 12877 |
13042 (plus:P (match_dup 1) | 12878 ;; Now the splitter if we could not allocate the CTR register |
13043 (const_int -1))) | |
13044 (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) | |
13045 (clobber (match_scratch:P 4 "=X,X,&r,r"))] | |
13046 "" | |
13047 { | |
13048 if (which_alternative != 0) | |
13049 return "#"; | |
13050 else if (get_attr_length (insn) == 4) | |
13051 return "bdz %l0"; | |
13052 else | |
13053 return "bdnz $+8\;b %l0"; | |
13054 } | |
13055 [(set_attr "type" "branch") | |
13056 (set_attr "length" "*,16,20,20")]) | |
13057 | |
13058 ;; Now the splitters if we could not allocate the CTR register | |
13059 | |
13060 (define_split | |
13061 [(set (pc) | |
13062 (if_then_else (match_operator 2 "comparison_operator" | |
13063 [(match_operand:P 1 "gpc_reg_operand") | |
13064 (const_int 1)]) | |
13065 (match_operand 5) | |
13066 (match_operand 6))) | |
13067 (set (match_operand:P 0 "int_reg_operand") | |
13068 (plus:P (match_dup 1) | |
13069 (const_int -1))) | |
13070 (clobber (match_scratch:CC 3)) | |
13071 (clobber (match_scratch:P 4))] | |
13072 "reload_completed" | |
13073 [(set (match_dup 3) | |
13074 (compare:CC (match_dup 1) | |
13075 (const_int 1))) | |
13076 (set (match_dup 0) | |
13077 (plus:P (match_dup 1) | |
13078 (const_int -1))) | |
13079 (set (pc) | |
13080 (if_then_else (match_dup 7) | |
13081 (match_dup 5) | |
13082 (match_dup 6)))] | |
13083 { | |
13084 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3], | |
13085 const0_rtx); | |
13086 }) | |
13087 | |
13088 (define_split | 12879 (define_split |
13089 [(set (pc) | 12880 [(set (pc) |
13090 (if_then_else (match_operator 2 "comparison_operator" | 12881 (if_then_else (match_operator 2 "comparison_operator" |
13091 [(match_operand:P 1 "gpc_reg_operand") | 12882 [(match_operand:P 1 "gpc_reg_operand") |
13092 (const_int 1)]) | 12883 (const_int 1)]) |
13095 (set (match_operand:P 0 "nonimmediate_operand") | 12886 (set (match_operand:P 0 "nonimmediate_operand") |
13096 (plus:P (match_dup 1) | 12887 (plus:P (match_dup 1) |
13097 (const_int -1))) | 12888 (const_int -1))) |
13098 (clobber (match_scratch:CC 3)) | 12889 (clobber (match_scratch:CC 3)) |
13099 (clobber (match_scratch:P 4))] | 12890 (clobber (match_scratch:P 4))] |
13100 "reload_completed && !gpc_reg_operand (operands[0], SImode)" | 12891 "reload_completed" |
13101 [(set (match_dup 3) | 12892 [(set (pc) |
13102 (compare:CC (match_dup 1) | |
13103 (const_int 1))) | |
13104 (set (match_dup 4) | |
13105 (plus:P (match_dup 1) | |
13106 (const_int -1))) | |
13107 (set (match_dup 0) | |
13108 (match_dup 4)) | |
13109 (set (pc) | |
13110 (if_then_else (match_dup 7) | 12893 (if_then_else (match_dup 7) |
13111 (match_dup 5) | 12894 (match_dup 5) |
13112 (match_dup 6)))] | 12895 (match_dup 6)))] |
13113 { | 12896 { |
13114 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3], | 12897 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3], |
13115 const0_rtx); | 12898 const0_rtx); |
13116 }) | 12899 emit_insn (gen_rtx_SET (operands[3], |
12900 gen_rtx_COMPARE (CCmode, operands[1], const1_rtx))); | |
12901 if (gpc_reg_operand (operands[0], <MODE>mode)) | |
12902 emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx)); | |
12903 else | |
12904 { | |
12905 emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx)); | |
12906 emit_move_insn (operands[0], operands[4]); | |
12907 } | |
12908 /* No DONE so branch comes from the pattern. */ | |
12909 }) | |
12910 | |
12911 ;; patterns for bdnzt/bdnzf/bdzt/bdzf | |
12912 ;; Note that in the case of long branches we have to decompose this into | |
12913 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition | |
12914 ;; and the CR bit, which means there is no way to conveniently invert the | |
12915 ;; comparison as is done with plain bdnz/bdz. | |
12916 | |
12917 (define_insn "<bd>tf_<mode>" | |
12918 [(set (pc) | |
12919 (if_then_else | |
12920 (and | |
12921 (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b") | |
12922 (const_int 1)) | |
12923 (match_operator 3 "branch_comparison_operator" | |
12924 [(match_operand 4 "cc_reg_operand" "y,y,y,y") | |
12925 (const_int 0)])) | |
12926 (label_ref (match_operand 0)) | |
12927 (pc))) | |
12928 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l") | |
12929 (plus:P (match_dup 1) | |
12930 (const_int -1))) | |
12931 (clobber (match_scratch:P 5 "=X,X,&r,r")) | |
12932 (clobber (match_scratch:CC 6 "=X,&y,&y,&y")) | |
12933 (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))] | |
12934 "" | |
12935 { | |
12936 if (which_alternative != 0) | |
12937 return "#"; | |
12938 else if (get_attr_length (insn) == 4) | |
12939 { | |
12940 if (branch_positive_comparison_operator (operands[3], | |
12941 GET_MODE (operands[3]))) | |
12942 return "<bd>t %j3,%l0"; | |
12943 else | |
12944 return "<bd>f %j3,%l0"; | |
12945 } | |
12946 else | |
12947 { | |
12948 static char seq[96]; | |
12949 char *bcs = output_cbranch (operands[3], "$+8", 1, insn); | |
12950 sprintf(seq, "<bd_neg> $+12\;%s;b %%l0", bcs); | |
12951 return seq; | |
12952 } | |
12953 } | |
12954 [(set_attr "type" "branch") | |
12955 (set_attr_alternative "length" | |
12956 [(if_then_else (and (ge (minus (match_dup 0) (pc)) | |
12957 (const_int -32768)) | |
12958 (lt (minus (match_dup 0) (pc)) | |
12959 (const_int 32764))) | |
12960 (const_int 4) | |
12961 (const_int 8)) | |
12962 (const_string "16") | |
12963 (const_string "20") | |
12964 (const_string "20")])]) | |
12965 | |
12966 ;; Now the splitter if we could not allocate the CTR register | |
12967 (define_split | |
12968 [(set (pc) | |
12969 (if_then_else | |
12970 (and | |
12971 (match_operator 1 "comparison_operator" | |
12972 [(match_operand:P 0 "gpc_reg_operand") | |
12973 (const_int 1)]) | |
12974 (match_operator 3 "branch_comparison_operator" | |
12975 [(match_operand 2 "cc_reg_operand") | |
12976 (const_int 0)])) | |
12977 (match_operand 4) | |
12978 (match_operand 5))) | |
12979 (set (match_operand:P 6 "int_reg_operand") | |
12980 (plus:P (match_dup 0) | |
12981 (const_int -1))) | |
12982 (clobber (match_scratch:P 7)) | |
12983 (clobber (match_scratch:CC 8)) | |
12984 (clobber (match_scratch:CCEQ 9))] | |
12985 "reload_completed" | |
12986 [(pc)] | |
12987 { | |
12988 rtx ctr = operands[0]; | |
12989 rtx ctrcmp = operands[1]; | |
12990 rtx ccin = operands[2]; | |
12991 rtx cccmp = operands[3]; | |
12992 rtx dst1 = operands[4]; | |
12993 rtx dst2 = operands[5]; | |
12994 rtx ctrout = operands[6]; | |
12995 rtx ctrtmp = operands[7]; | |
12996 enum rtx_code cmpcode = GET_CODE (ctrcmp); | |
12997 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp)); | |
12998 if (!ispos) | |
12999 cmpcode = reverse_condition (cmpcode); | |
13000 /* Generate crand/crandc here. */ | |
13001 emit_insn (gen_rtx_SET (operands[8], | |
13002 gen_rtx_COMPARE (CCmode, ctr, const1_rtx))); | |
13003 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx); | |
13004 | |
13005 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp); | |
13006 if (ispos) | |
13007 emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc, | |
13008 operands[8], cccmp, ccin)); | |
13009 else | |
13010 emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc, | |
13011 operands[8], cccmp, ccin)); | |
13012 if (gpc_reg_operand (operands[0], <MODE>mode)) | |
13013 emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx)); | |
13014 else | |
13015 { | |
13016 emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx)); | |
13017 emit_move_insn (ctrout, ctrtmp); | |
13018 } | |
13019 rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx); | |
13020 emit_jump_insn (gen_rtx_SET (pc_rtx, | |
13021 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp, | |
13022 dst1, dst2))); | |
13023 DONE; | |
13024 }) | |
13025 | |
13117 | 13026 |
13118 (define_insn "trap" | 13027 (define_insn "trap" |
13119 [(trap_if (const_int 1) (const_int 0))] | 13028 [(trap_if (const_int 1) (const_int 0))] |
13120 "" | 13029 "" |
13121 "trap" | 13030 "trap" |
13155 [(set (match_operand:SI 1 "gpc_reg_operand" "=r") | 13064 [(set (match_operand:SI 1 "gpc_reg_operand" "=r") |
13156 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y") | 13065 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y") |
13157 (match_operand 3 "immediate_operand" "n")] | 13066 (match_operand 3 "immediate_operand" "n")] |
13158 UNSPEC_MOVESI_FROM_CR))])] | 13067 UNSPEC_MOVESI_FROM_CR))])] |
13159 "TARGET_MFCRF" | 13068 "TARGET_MFCRF" |
13160 "* | |
13161 { | 13069 { |
13162 int mask = 0; | 13070 int mask = 0; |
13163 int i; | 13071 int i; |
13164 for (i = 0; i < XVECLEN (operands[0], 0); i++) | 13072 for (i = 0; i < XVECLEN (operands[0], 0); i++) |
13165 { | 13073 { |
13166 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1)); | 13074 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1)); |
13167 operands[4] = GEN_INT (mask); | 13075 operands[4] = GEN_INT (mask); |
13168 output_asm_insn (\"mfcr %1,%4\", operands); | 13076 output_asm_insn ("mfcr %1,%4", operands); |
13169 } | 13077 } |
13170 return \"\"; | 13078 return ""; |
13171 }" | 13079 } |
13172 [(set_attr "type" "mfcrf")]) | 13080 [(set_attr "type" "mfcrf")]) |
13173 | 13081 |
13174 ;; Don't include the volatile CRs since their values are not used wrt CR save | 13082 ;; Don't include the volatile CRs since their values are not used wrt CR save |
13175 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the | 13083 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the |
13176 ;; prologue past an insn (early exit test) that defines a register used in the | 13084 ;; prologue past an insn (early exit test) that defines a register used in the |
13224 (use (reg:P 11)) | 13132 (use (reg:P 11)) |
13225 (set (match_operand:P 2 "memory_operand" "=m") | 13133 (set (match_operand:P 2 "memory_operand" "=m") |
13226 (match_operand:P 3 "gpc_reg_operand" "r"))])] | 13134 (match_operand:P 3 "gpc_reg_operand" "r"))])] |
13227 "" | 13135 "" |
13228 "bl %1" | 13136 "bl %1" |
13229 [(set_attr "type" "branch") | 13137 [(set_attr "type" "branch")]) |
13230 (set_attr "length" "4")]) | |
13231 | 13138 |
13232 (define_insn "*save_gpregs_<mode>_r12" | 13139 (define_insn "*save_gpregs_<mode>_r12" |
13233 [(match_parallel 0 "any_parallel_operand" | 13140 [(match_parallel 0 "any_parallel_operand" |
13234 [(clobber (reg:P LR_REGNO)) | 13141 [(clobber (reg:P LR_REGNO)) |
13235 (use (match_operand:P 1 "symbol_ref_operand" "s")) | 13142 (use (match_operand:P 1 "symbol_ref_operand" "s")) |
13236 (use (reg:P 12)) | 13143 (use (reg:P 12)) |
13237 (set (match_operand:P 2 "memory_operand" "=m") | 13144 (set (match_operand:P 2 "memory_operand" "=m") |
13238 (match_operand:P 3 "gpc_reg_operand" "r"))])] | 13145 (match_operand:P 3 "gpc_reg_operand" "r"))])] |
13239 "" | 13146 "" |
13240 "bl %1" | 13147 "bl %1" |
13241 [(set_attr "type" "branch") | 13148 [(set_attr "type" "branch")]) |
13242 (set_attr "length" "4")]) | |
13243 | 13149 |
13244 (define_insn "*save_gpregs_<mode>_r1" | 13150 (define_insn "*save_gpregs_<mode>_r1" |
13245 [(match_parallel 0 "any_parallel_operand" | 13151 [(match_parallel 0 "any_parallel_operand" |
13246 [(clobber (reg:P LR_REGNO)) | 13152 [(clobber (reg:P LR_REGNO)) |
13247 (use (match_operand:P 1 "symbol_ref_operand" "s")) | 13153 (use (match_operand:P 1 "symbol_ref_operand" "s")) |
13248 (use (reg:P 1)) | 13154 (use (reg:P 1)) |
13249 (set (match_operand:P 2 "memory_operand" "=m") | 13155 (set (match_operand:P 2 "memory_operand" "=m") |
13250 (match_operand:P 3 "gpc_reg_operand" "r"))])] | 13156 (match_operand:P 3 "gpc_reg_operand" "r"))])] |
13251 "" | 13157 "" |
13252 "bl %1" | 13158 "bl %1" |
13253 [(set_attr "type" "branch") | 13159 [(set_attr "type" "branch")]) |
13254 (set_attr "length" "4")]) | |
13255 | 13160 |
13256 (define_insn "*save_fpregs_<mode>_r11" | 13161 (define_insn "*save_fpregs_<mode>_r11" |
13257 [(match_parallel 0 "any_parallel_operand" | 13162 [(match_parallel 0 "any_parallel_operand" |
13258 [(clobber (reg:P LR_REGNO)) | 13163 [(clobber (reg:P LR_REGNO)) |
13259 (use (match_operand:P 1 "symbol_ref_operand" "s")) | 13164 (use (match_operand:P 1 "symbol_ref_operand" "s")) |
13260 (use (reg:P 11)) | 13165 (use (reg:P 11)) |
13261 (set (match_operand:DF 2 "memory_operand" "=m") | 13166 (set (match_operand:DF 2 "memory_operand" "=m") |
13262 (match_operand:DF 3 "gpc_reg_operand" "d"))])] | 13167 (match_operand:DF 3 "gpc_reg_operand" "d"))])] |
13263 "" | 13168 "" |
13264 "bl %1" | 13169 "bl %1" |
13265 [(set_attr "type" "branch") | 13170 [(set_attr "type" "branch")]) |
13266 (set_attr "length" "4")]) | |
13267 | 13171 |
13268 (define_insn "*save_fpregs_<mode>_r12" | 13172 (define_insn "*save_fpregs_<mode>_r12" |
13269 [(match_parallel 0 "any_parallel_operand" | 13173 [(match_parallel 0 "any_parallel_operand" |
13270 [(clobber (reg:P LR_REGNO)) | 13174 [(clobber (reg:P LR_REGNO)) |
13271 (use (match_operand:P 1 "symbol_ref_operand" "s")) | 13175 (use (match_operand:P 1 "symbol_ref_operand" "s")) |
13272 (use (reg:P 12)) | 13176 (use (reg:P 12)) |
13273 (set (match_operand:DF 2 "memory_operand" "=m") | 13177 (set (match_operand:DF 2 "memory_operand" "=m") |
13274 (match_operand:DF 3 "gpc_reg_operand" "d"))])] | 13178 (match_operand:DF 3 "gpc_reg_operand" "d"))])] |
13275 "" | 13179 "" |
13276 "bl %1" | 13180 "bl %1" |
13277 [(set_attr "type" "branch") | 13181 [(set_attr "type" "branch")]) |
13278 (set_attr "length" "4")]) | |
13279 | 13182 |
13280 (define_insn "*save_fpregs_<mode>_r1" | 13183 (define_insn "*save_fpregs_<mode>_r1" |
13281 [(match_parallel 0 "any_parallel_operand" | 13184 [(match_parallel 0 "any_parallel_operand" |
13282 [(clobber (reg:P LR_REGNO)) | 13185 [(clobber (reg:P LR_REGNO)) |
13283 (use (match_operand:P 1 "symbol_ref_operand" "s")) | 13186 (use (match_operand:P 1 "symbol_ref_operand" "s")) |
13284 (use (reg:P 1)) | 13187 (use (reg:P 1)) |
13285 (set (match_operand:DF 2 "memory_operand" "=m") | 13188 (set (match_operand:DF 2 "memory_operand" "=m") |
13286 (match_operand:DF 3 "gpc_reg_operand" "d"))])] | 13189 (match_operand:DF 3 "gpc_reg_operand" "d"))])] |
13287 "" | 13190 "" |
13288 "bl %1" | 13191 "bl %1" |
13289 [(set_attr "type" "branch") | 13192 [(set_attr "type" "branch")]) |
13290 (set_attr "length" "4")]) | |
13291 | 13193 |
13292 ; This is to explain that changes to the stack pointer should | 13194 ; This is to explain that changes to the stack pointer should |
13293 ; not be moved over loads from or stores to stack memory. | 13195 ; not be moved over loads from or stores to stack memory. |
13294 (define_insn "stack_tie" | 13196 (define_insn "stack_tie" |
13295 [(match_parallel 0 "tie_operand" | 13197 [(match_parallel 0 "tie_operand" |
13325 ; On some processors, doing the mtcrf one CC register at a time is | 13227 ; On some processors, doing the mtcrf one CC register at a time is |
13326 ; faster (like on the 604e). On others, doing them all at once is | 13228 ; faster (like on the 604e). On others, doing them all at once is |
13327 ; faster; for instance, on the 601 and 750. | 13229 ; faster; for instance, on the 601 and 750. |
13328 | 13230 |
13329 (define_expand "movsi_to_cr_one" | 13231 (define_expand "movsi_to_cr_one" |
13330 [(set (match_operand:CC 0 "cc_reg_operand" "") | 13232 [(set (match_operand:CC 0 "cc_reg_operand") |
13331 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "") | 13233 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand") |
13332 (match_dup 2)] UNSPEC_MOVESI_TO_CR))] | 13234 (match_dup 2)] UNSPEC_MOVESI_TO_CR))] |
13333 "" | 13235 "" |
13334 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));") | 13236 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));") |
13335 | 13237 |
13336 (define_insn "*movsi_to_cr" | 13238 (define_insn "*movsi_to_cr" |
13338 [(set (match_operand:CC 1 "cc_reg_operand" "=y") | 13240 [(set (match_operand:CC 1 "cc_reg_operand" "=y") |
13339 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r") | 13241 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r") |
13340 (match_operand 3 "immediate_operand" "n")] | 13242 (match_operand 3 "immediate_operand" "n")] |
13341 UNSPEC_MOVESI_TO_CR))])] | 13243 UNSPEC_MOVESI_TO_CR))])] |
13342 "" | 13244 "" |
13343 "* | |
13344 { | 13245 { |
13345 int mask = 0; | 13246 int mask = 0; |
13346 int i; | 13247 int i; |
13347 for (i = 0; i < XVECLEN (operands[0], 0); i++) | 13248 for (i = 0; i < XVECLEN (operands[0], 0); i++) |
13348 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1)); | 13249 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1)); |
13349 operands[4] = GEN_INT (mask); | 13250 operands[4] = GEN_INT (mask); |
13350 return \"mtcrf %4,%2\"; | 13251 return "mtcrf %4,%2"; |
13351 }" | 13252 } |
13352 [(set_attr "type" "mtcr")]) | 13253 [(set_attr "type" "mtcr")]) |
13353 | 13254 |
13354 (define_insn "*mtcrfsi" | 13255 (define_insn "*mtcrfsi" |
13355 [(set (match_operand:CC 0 "cc_reg_operand" "=y") | 13256 [(set (match_operand:CC 0 "cc_reg_operand" "=y") |
13356 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") | 13257 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") |
13376 [(set_attr "type" "load") | 13277 [(set_attr "type" "load") |
13377 (set_attr "update" "yes") | 13278 (set_attr "update" "yes") |
13378 (set_attr "indexed" "yes") | 13279 (set_attr "indexed" "yes") |
13379 (set_attr "cell_micro" "always")]) | 13280 (set_attr "cell_micro" "always")]) |
13380 | 13281 |
13381 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall | 13282 ; FIXME: "any_parallel_operand" is a bit flexible... |
13382 ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible... | |
13383 | 13283 |
13384 ; The following comment applies to: | 13284 ; The following comment applies to: |
13385 ; save_gpregs_* | 13285 ; save_gpregs_* |
13386 ; save_fpregs_* | 13286 ; save_fpregs_* |
13387 ; restore_gpregs* | 13287 ; restore_gpregs* |
13403 (use (reg:P 11)) | 13303 (use (reg:P 11)) |
13404 (set (match_operand:P 2 "gpc_reg_operand" "=r") | 13304 (set (match_operand:P 2 "gpc_reg_operand" "=r") |
13405 (match_operand:P 3 "memory_operand" "m"))])] | 13305 (match_operand:P 3 "memory_operand" "m"))])] |
13406 "" | 13306 "" |
13407 "bl %1" | 13307 "bl %1" |
13408 [(set_attr "type" "branch") | 13308 [(set_attr "type" "branch")]) |
13409 (set_attr "length" "4")]) | |
13410 | 13309 |
13411 (define_insn "*restore_gpregs_<mode>_r12" | 13310 (define_insn "*restore_gpregs_<mode>_r12" |
13412 [(match_parallel 0 "any_parallel_operand" | 13311 [(match_parallel 0 "any_parallel_operand" |
13413 [(clobber (reg:P LR_REGNO)) | 13312 [(clobber (reg:P LR_REGNO)) |
13414 (use (match_operand:P 1 "symbol_ref_operand" "s")) | 13313 (use (match_operand:P 1 "symbol_ref_operand" "s")) |
13415 (use (reg:P 12)) | 13314 (use (reg:P 12)) |
13416 (set (match_operand:P 2 "gpc_reg_operand" "=r") | 13315 (set (match_operand:P 2 "gpc_reg_operand" "=r") |
13417 (match_operand:P 3 "memory_operand" "m"))])] | 13316 (match_operand:P 3 "memory_operand" "m"))])] |
13418 "" | 13317 "" |
13419 "bl %1" | 13318 "bl %1" |
13420 [(set_attr "type" "branch") | 13319 [(set_attr "type" "branch")]) |
13421 (set_attr "length" "4")]) | |
13422 | 13320 |
13423 (define_insn "*restore_gpregs_<mode>_r1" | 13321 (define_insn "*restore_gpregs_<mode>_r1" |
13424 [(match_parallel 0 "any_parallel_operand" | 13322 [(match_parallel 0 "any_parallel_operand" |
13425 [(clobber (reg:P LR_REGNO)) | 13323 [(clobber (reg:P LR_REGNO)) |
13426 (use (match_operand:P 1 "symbol_ref_operand" "s")) | 13324 (use (match_operand:P 1 "symbol_ref_operand" "s")) |
13427 (use (reg:P 1)) | 13325 (use (reg:P 1)) |
13428 (set (match_operand:P 2 "gpc_reg_operand" "=r") | 13326 (set (match_operand:P 2 "gpc_reg_operand" "=r") |
13429 (match_operand:P 3 "memory_operand" "m"))])] | 13327 (match_operand:P 3 "memory_operand" "m"))])] |
13430 "" | 13328 "" |
13431 "bl %1" | 13329 "bl %1" |
13432 [(set_attr "type" "branch") | 13330 [(set_attr "type" "branch")]) |
13433 (set_attr "length" "4")]) | |
13434 | 13331 |
13435 (define_insn "*return_and_restore_gpregs_<mode>_r11" | 13332 (define_insn "*return_and_restore_gpregs_<mode>_r11" |
13436 [(match_parallel 0 "any_parallel_operand" | 13333 [(match_parallel 0 "any_parallel_operand" |
13437 [(return) | 13334 [(return) |
13438 (clobber (reg:P LR_REGNO)) | 13335 (clobber (reg:P LR_REGNO)) |
13440 (use (reg:P 11)) | 13337 (use (reg:P 11)) |
13441 (set (match_operand:P 2 "gpc_reg_operand" "=r") | 13338 (set (match_operand:P 2 "gpc_reg_operand" "=r") |
13442 (match_operand:P 3 "memory_operand" "m"))])] | 13339 (match_operand:P 3 "memory_operand" "m"))])] |
13443 "" | 13340 "" |
13444 "b %1" | 13341 "b %1" |
13445 [(set_attr "type" "branch") | 13342 [(set_attr "type" "branch")]) |
13446 (set_attr "length" "4")]) | |
13447 | 13343 |
13448 (define_insn "*return_and_restore_gpregs_<mode>_r12" | 13344 (define_insn "*return_and_restore_gpregs_<mode>_r12" |
13449 [(match_parallel 0 "any_parallel_operand" | 13345 [(match_parallel 0 "any_parallel_operand" |
13450 [(return) | 13346 [(return) |
13451 (clobber (reg:P LR_REGNO)) | 13347 (clobber (reg:P LR_REGNO)) |
13453 (use (reg:P 12)) | 13349 (use (reg:P 12)) |
13454 (set (match_operand:P 2 "gpc_reg_operand" "=r") | 13350 (set (match_operand:P 2 "gpc_reg_operand" "=r") |
13455 (match_operand:P 3 "memory_operand" "m"))])] | 13351 (match_operand:P 3 "memory_operand" "m"))])] |
13456 "" | 13352 "" |
13457 "b %1" | 13353 "b %1" |
13458 [(set_attr "type" "branch") | 13354 [(set_attr "type" "branch")]) |
13459 (set_attr "length" "4")]) | |
13460 | 13355 |
13461 (define_insn "*return_and_restore_gpregs_<mode>_r1" | 13356 (define_insn "*return_and_restore_gpregs_<mode>_r1" |
13462 [(match_parallel 0 "any_parallel_operand" | 13357 [(match_parallel 0 "any_parallel_operand" |
13463 [(return) | 13358 [(return) |
13464 (clobber (reg:P LR_REGNO)) | 13359 (clobber (reg:P LR_REGNO)) |
13466 (use (reg:P 1)) | 13361 (use (reg:P 1)) |
13467 (set (match_operand:P 2 "gpc_reg_operand" "=r") | 13362 (set (match_operand:P 2 "gpc_reg_operand" "=r") |
13468 (match_operand:P 3 "memory_operand" "m"))])] | 13363 (match_operand:P 3 "memory_operand" "m"))])] |
13469 "" | 13364 "" |
13470 "b %1" | 13365 "b %1" |
13471 [(set_attr "type" "branch") | 13366 [(set_attr "type" "branch")]) |
13472 (set_attr "length" "4")]) | |
13473 | 13367 |
13474 (define_insn "*return_and_restore_fpregs_<mode>_r11" | 13368 (define_insn "*return_and_restore_fpregs_<mode>_r11" |
13475 [(match_parallel 0 "any_parallel_operand" | 13369 [(match_parallel 0 "any_parallel_operand" |
13476 [(return) | 13370 [(return) |
13477 (clobber (reg:P LR_REGNO)) | 13371 (clobber (reg:P LR_REGNO)) |
13479 (use (reg:P 11)) | 13373 (use (reg:P 11)) |
13480 (set (match_operand:DF 2 "gpc_reg_operand" "=d") | 13374 (set (match_operand:DF 2 "gpc_reg_operand" "=d") |
13481 (match_operand:DF 3 "memory_operand" "m"))])] | 13375 (match_operand:DF 3 "memory_operand" "m"))])] |
13482 "" | 13376 "" |
13483 "b %1" | 13377 "b %1" |
13484 [(set_attr "type" "branch") | 13378 [(set_attr "type" "branch")]) |
13485 (set_attr "length" "4")]) | |
13486 | 13379 |
13487 (define_insn "*return_and_restore_fpregs_<mode>_r12" | 13380 (define_insn "*return_and_restore_fpregs_<mode>_r12" |
13488 [(match_parallel 0 "any_parallel_operand" | 13381 [(match_parallel 0 "any_parallel_operand" |
13489 [(return) | 13382 [(return) |
13490 (clobber (reg:P LR_REGNO)) | 13383 (clobber (reg:P LR_REGNO)) |
13492 (use (reg:P 12)) | 13385 (use (reg:P 12)) |
13493 (set (match_operand:DF 2 "gpc_reg_operand" "=d") | 13386 (set (match_operand:DF 2 "gpc_reg_operand" "=d") |
13494 (match_operand:DF 3 "memory_operand" "m"))])] | 13387 (match_operand:DF 3 "memory_operand" "m"))])] |
13495 "" | 13388 "" |
13496 "b %1" | 13389 "b %1" |
13497 [(set_attr "type" "branch") | 13390 [(set_attr "type" "branch")]) |
13498 (set_attr "length" "4")]) | |
13499 | 13391 |
13500 (define_insn "*return_and_restore_fpregs_<mode>_r1" | 13392 (define_insn "*return_and_restore_fpregs_<mode>_r1" |
13501 [(match_parallel 0 "any_parallel_operand" | 13393 [(match_parallel 0 "any_parallel_operand" |
13502 [(return) | 13394 [(return) |
13503 (clobber (reg:P LR_REGNO)) | 13395 (clobber (reg:P LR_REGNO)) |
13505 (use (reg:P 1)) | 13397 (use (reg:P 1)) |
13506 (set (match_operand:DF 2 "gpc_reg_operand" "=d") | 13398 (set (match_operand:DF 2 "gpc_reg_operand" "=d") |
13507 (match_operand:DF 3 "memory_operand" "m"))])] | 13399 (match_operand:DF 3 "memory_operand" "m"))])] |
13508 "" | 13400 "" |
13509 "b %1" | 13401 "b %1" |
13510 [(set_attr "type" "branch") | 13402 [(set_attr "type" "branch")]) |
13511 (set_attr "length" "4")]) | |
13512 | 13403 |
13513 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11" | 13404 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11" |
13514 [(match_parallel 0 "any_parallel_operand" | 13405 [(match_parallel 0 "any_parallel_operand" |
13515 [(return) | 13406 [(return) |
13516 (use (match_operand:P 1 "symbol_ref_operand" "s")) | 13407 (use (match_operand:P 1 "symbol_ref_operand" "s")) |
13517 (use (reg:P 11)) | 13408 (use (reg:P 11)) |
13518 (set (match_operand:DF 2 "gpc_reg_operand" "=d") | 13409 (set (match_operand:DF 2 "gpc_reg_operand" "=d") |
13519 (match_operand:DF 3 "memory_operand" "m"))])] | 13410 (match_operand:DF 3 "memory_operand" "m"))])] |
13520 "" | 13411 "" |
13521 "b %1" | 13412 "b %1" |
13522 [(set_attr "type" "branch") | 13413 [(set_attr "type" "branch")]) |
13523 (set_attr "length" "4")]) | |
13524 | 13414 |
13525 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1" | 13415 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1" |
13526 [(match_parallel 0 "any_parallel_operand" | 13416 [(match_parallel 0 "any_parallel_operand" |
13527 [(return) | 13417 [(return) |
13528 (use (match_operand:P 1 "symbol_ref_operand" "s")) | 13418 (use (match_operand:P 1 "symbol_ref_operand" "s")) |
13529 (use (reg:P 1)) | 13419 (use (reg:P 1)) |
13530 (set (match_operand:DF 2 "gpc_reg_operand" "=d") | 13420 (set (match_operand:DF 2 "gpc_reg_operand" "=d") |
13531 (match_operand:DF 3 "memory_operand" "m"))])] | 13421 (match_operand:DF 3 "memory_operand" "m"))])] |
13532 "" | 13422 "" |
13533 "b %1" | 13423 "b %1" |
13534 [(set_attr "type" "branch") | 13424 [(set_attr "type" "branch")]) |
13535 (set_attr "length" "4")]) | |
13536 | 13425 |
13537 ; This is used in compiling the unwind routines. | 13426 ; This is used in compiling the unwind routines. |
13538 (define_expand "eh_return" | 13427 (define_expand "eh_return" |
13539 [(use (match_operand 0 "general_operand" ""))] | 13428 [(use (match_operand 0 "general_operand"))] |
13540 "" | 13429 "" |
13541 " | |
13542 { | 13430 { |
13543 if (TARGET_32BIT) | 13431 if (TARGET_32BIT) |
13544 emit_insn (gen_eh_set_lr_si (operands[0])); | 13432 emit_insn (gen_eh_set_lr_si (operands[0])); |
13545 else | 13433 else |
13546 emit_insn (gen_eh_set_lr_di (operands[0])); | 13434 emit_insn (gen_eh_set_lr_di (operands[0])); |
13547 DONE; | 13435 DONE; |
13548 }") | 13436 }) |
13549 | 13437 |
13550 ; We can't expand this before we know where the link register is stored. | 13438 ; We can't expand this before we know where the link register is stored. |
13551 (define_insn "eh_set_lr_<mode>" | 13439 (define_insn "eh_set_lr_<mode>" |
13552 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] | 13440 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] |
13553 UNSPECV_EH_RR) | 13441 UNSPECV_EH_RR) |
13554 (clobber (match_scratch:P 1 "=&b"))] | 13442 (clobber (match_scratch:P 1 "=&b"))] |
13555 "" | 13443 "" |
13556 "#") | 13444 "#") |
13557 | 13445 |
13558 (define_split | 13446 (define_split |
13559 [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR) | 13447 [(unspec_volatile [(match_operand 0 "register_operand")] UNSPECV_EH_RR) |
13560 (clobber (match_scratch 1 ""))] | 13448 (clobber (match_scratch 1))] |
13561 "reload_completed" | 13449 "reload_completed" |
13562 [(const_int 0)] | 13450 [(const_int 0)] |
13563 " | |
13564 { | 13451 { |
13565 rs6000_emit_eh_reg_restore (operands[0], operands[1]); | 13452 rs6000_emit_eh_reg_restore (operands[0], operands[1]); |
13566 DONE; | 13453 DONE; |
13567 }") | 13454 }) |
13568 | 13455 |
13569 (define_insn "prefetch" | 13456 (define_insn "prefetch" |
13570 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a") | 13457 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a") |
13571 (match_operand:SI 1 "const_int_operand" "n") | 13458 (match_operand:SI 1 "const_int_operand" "n") |
13572 (match_operand:SI 2 "const_int_operand" "n"))] | 13459 (match_operand:SI 2 "const_int_operand" "n"))] |
13573 "" | 13460 "" |
13574 "* | 13461 { |
13575 { | 13462 |
13576 if (GET_CODE (operands[0]) == REG) | 13463 |
13577 return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\"; | 13464 /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7). |
13578 return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\"; | 13465 AIX does not support the dcbtstt and dcbtt extended mnemonics. |
13579 }" | 13466 The AIX assembler does not support the three operand form of dcbt |
13467 and dcbtst on Power 7 (-mpwr7). */ | |
13468 int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE; | |
13469 | |
13470 if (REG_P (operands[0])) | |
13471 { | |
13472 if (INTVAL (operands[1]) == 0) | |
13473 return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16"; | |
13474 else | |
13475 return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16"; | |
13476 } | |
13477 else | |
13478 { | |
13479 if (INTVAL (operands[1]) == 0) | |
13480 return inst_select ? "dcbt %a0" : "dcbt %a0,16"; | |
13481 else | |
13482 return inst_select ? "dcbtst %a0" : "dcbtst %a0,16"; | |
13483 } | |
13484 } | |
13580 [(set_attr "type" "load")]) | 13485 [(set_attr "type" "load")]) |
13581 | 13486 |
13582 ;; Handle -fsplit-stack. | 13487 ;; Handle -fsplit-stack. |
13583 | 13488 |
13584 (define_expand "split_stack_prologue" | 13489 (define_expand "split_stack_prologue" |
13621 | 13526 |
13622 ;; A return instruction which the middle-end doesn't see. | 13527 ;; A return instruction which the middle-end doesn't see. |
13623 ;; Use r0 to stop regrename twiddling with lr restore insns emitted | 13528 ;; Use r0 to stop regrename twiddling with lr restore insns emitted |
13624 ;; after the call to __morestack. | 13529 ;; after the call to __morestack. |
13625 (define_insn "split_stack_return" | 13530 (define_insn "split_stack_return" |
13626 [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)] | 13531 [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)] |
13627 "" | 13532 "" |
13628 "blr" | 13533 "blr" |
13629 [(set_attr "type" "jmpreg")]) | 13534 [(set_attr "type" "jmpreg")]) |
13630 | 13535 |
13631 ;; If there are operand 0 bytes available on the stack, jump to | 13536 ;; If there are operand 0 bytes available on the stack, jump to |
13658 | 13563 |
13659 ;; Builtin fma support. Handle | 13564 ;; Builtin fma support. Handle |
13660 ;; Note that the conditions for expansion are in the FMA_F iterator. | 13565 ;; Note that the conditions for expansion are in the FMA_F iterator. |
13661 | 13566 |
13662 (define_expand "fma<mode>4" | 13567 (define_expand "fma<mode>4" |
13663 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "") | 13568 [(set (match_operand:FMA_F 0 "gpc_reg_operand") |
13664 (fma:FMA_F | 13569 (fma:FMA_F |
13665 (match_operand:FMA_F 1 "gpc_reg_operand" "") | 13570 (match_operand:FMA_F 1 "gpc_reg_operand") |
13666 (match_operand:FMA_F 2 "gpc_reg_operand" "") | 13571 (match_operand:FMA_F 2 "gpc_reg_operand") |
13667 (match_operand:FMA_F 3 "gpc_reg_operand" "")))] | 13572 (match_operand:FMA_F 3 "gpc_reg_operand")))] |
13668 "" | 13573 "" |
13669 "") | 13574 "") |
13670 | 13575 |
13671 (define_insn "*fma<mode>4_fpr" | 13576 (define_insn "*fma<mode>4_fpr" |
13672 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>") | 13577 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>") |
13673 (fma:SFDF | 13578 (fma:SFDF |
13674 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>") | 13579 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>") |
13675 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0") | 13580 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0") |
13676 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))] | 13581 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))] |
13677 "TARGET_<MODE>_FPR" | 13582 "TARGET_HARD_FLOAT" |
13678 "@ | 13583 "@ |
13679 fmadd<Ftrad> %0,%1,%2,%3 | 13584 fmadd<Ftrad> %0,%1,%2,%3 |
13680 xsmadda<Fvsx> %x0,%x1,%x2 | 13585 xsmadda<Fvsx> %x0,%x1,%x2 |
13681 xsmaddm<Fvsx> %x0,%x1,%x3" | 13586 xsmaddm<Fvsx> %x0,%x1,%x3" |
13682 [(set_attr "type" "fp") | 13587 [(set_attr "type" "fp")]) |
13683 (set_attr "fp_type" "fp_maddsub_<Fs>")]) | |
13684 | 13588 |
13685 ; Altivec only has fma and nfms. | 13589 ; Altivec only has fma and nfms. |
13686 (define_expand "fms<mode>4" | 13590 (define_expand "fms<mode>4" |
13687 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "") | 13591 [(set (match_operand:FMA_F 0 "gpc_reg_operand") |
13688 (fma:FMA_F | 13592 (fma:FMA_F |
13689 (match_operand:FMA_F 1 "gpc_reg_operand" "") | 13593 (match_operand:FMA_F 1 "gpc_reg_operand") |
13690 (match_operand:FMA_F 2 "gpc_reg_operand" "") | 13594 (match_operand:FMA_F 2 "gpc_reg_operand") |
13691 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" ""))))] | 13595 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))] |
13692 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" | 13596 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" |
13693 "") | 13597 "") |
13694 | 13598 |
13695 (define_insn "*fms<mode>4_fpr" | 13599 (define_insn "*fms<mode>4_fpr" |
13696 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>") | 13600 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>") |
13697 (fma:SFDF | 13601 (fma:SFDF |
13698 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>") | 13602 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>") |
13699 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0") | 13603 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0") |
13700 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))] | 13604 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))] |
13701 "TARGET_<MODE>_FPR" | 13605 "TARGET_HARD_FLOAT" |
13702 "@ | 13606 "@ |
13703 fmsub<Ftrad> %0,%1,%2,%3 | 13607 fmsub<Ftrad> %0,%1,%2,%3 |
13704 xsmsuba<Fvsx> %x0,%x1,%x2 | 13608 xsmsuba<Fvsx> %x0,%x1,%x2 |
13705 xsmsubm<Fvsx> %x0,%x1,%x3" | 13609 xsmsubm<Fvsx> %x0,%x1,%x3" |
13706 [(set_attr "type" "fp") | 13610 [(set_attr "type" "fp")]) |
13707 (set_attr "fp_type" "fp_maddsub_<Fs>")]) | |
13708 | 13611 |
13709 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c. | 13612 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c. |
13710 (define_expand "fnma<mode>4" | 13613 (define_expand "fnma<mode>4" |
13711 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "") | 13614 [(set (match_operand:FMA_F 0 "gpc_reg_operand") |
13712 (neg:FMA_F | 13615 (neg:FMA_F |
13713 (fma:FMA_F | 13616 (fma:FMA_F |
13714 (match_operand:FMA_F 1 "gpc_reg_operand" "") | 13617 (match_operand:FMA_F 1 "gpc_reg_operand") |
13715 (match_operand:FMA_F 2 "gpc_reg_operand" "") | 13618 (match_operand:FMA_F 2 "gpc_reg_operand") |
13716 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))] | 13619 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))] |
13717 "!HONOR_SIGNED_ZEROS (<MODE>mode)" | 13620 "!HONOR_SIGNED_ZEROS (<MODE>mode)" |
13718 "") | 13621 "") |
13719 | 13622 |
13720 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c. | 13623 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c. |
13721 (define_expand "fnms<mode>4" | 13624 (define_expand "fnms<mode>4" |
13722 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "") | 13625 [(set (match_operand:FMA_F 0 "gpc_reg_operand") |
13723 (neg:FMA_F | 13626 (neg:FMA_F |
13724 (fma:FMA_F | 13627 (fma:FMA_F |
13725 (match_operand:FMA_F 1 "gpc_reg_operand" "") | 13628 (match_operand:FMA_F 1 "gpc_reg_operand") |
13726 (match_operand:FMA_F 2 "gpc_reg_operand" "") | 13629 (match_operand:FMA_F 2 "gpc_reg_operand") |
13727 (match_operand:FMA_F 3 "gpc_reg_operand" ""))))] | 13630 (match_operand:FMA_F 3 "gpc_reg_operand"))))] |
13728 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" | 13631 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" |
13729 "") | 13632 "") |
13730 | 13633 |
13731 ; Not an official optab name, but used from builtins. | 13634 ; Not an official optab name, but used from builtins. |
13732 (define_expand "nfma<mode>4" | 13635 (define_expand "nfma<mode>4" |
13733 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "") | 13636 [(set (match_operand:FMA_F 0 "gpc_reg_operand") |
13734 (neg:FMA_F | 13637 (neg:FMA_F |
13735 (fma:FMA_F | 13638 (fma:FMA_F |
13736 (match_operand:FMA_F 1 "gpc_reg_operand" "") | 13639 (match_operand:FMA_F 1 "gpc_reg_operand") |
13737 (match_operand:FMA_F 2 "gpc_reg_operand" "") | 13640 (match_operand:FMA_F 2 "gpc_reg_operand") |
13738 (match_operand:FMA_F 3 "gpc_reg_operand" ""))))] | 13641 (match_operand:FMA_F 3 "gpc_reg_operand"))))] |
13739 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" | 13642 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" |
13740 "") | 13643 "") |
13741 | 13644 |
13742 (define_insn "*nfma<mode>4_fpr" | 13645 (define_insn "*nfma<mode>4_fpr" |
13743 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>") | 13646 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>") |
13744 (neg:SFDF | 13647 (neg:SFDF |
13745 (fma:SFDF | 13648 (fma:SFDF |
13746 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>") | 13649 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>") |
13747 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0") | 13650 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0") |
13748 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))] | 13651 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))] |
13749 "TARGET_<MODE>_FPR" | 13652 "TARGET_HARD_FLOAT" |
13750 "@ | 13653 "@ |
13751 fnmadd<Ftrad> %0,%1,%2,%3 | 13654 fnmadd<Ftrad> %0,%1,%2,%3 |
13752 xsnmadda<Fvsx> %x0,%x1,%x2 | 13655 xsnmadda<Fvsx> %x0,%x1,%x2 |
13753 xsnmaddm<Fvsx> %x0,%x1,%x3" | 13656 xsnmaddm<Fvsx> %x0,%x1,%x3" |
13754 [(set_attr "type" "fp") | 13657 [(set_attr "type" "fp")]) |
13755 (set_attr "fp_type" "fp_maddsub_<Fs>")]) | |
13756 | 13658 |
13757 ; Not an official optab name, but used from builtins. | 13659 ; Not an official optab name, but used from builtins. |
13758 (define_expand "nfms<mode>4" | 13660 (define_expand "nfms<mode>4" |
13759 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "") | 13661 [(set (match_operand:FMA_F 0 "gpc_reg_operand") |
13760 (neg:FMA_F | 13662 (neg:FMA_F |
13761 (fma:FMA_F | 13663 (fma:FMA_F |
13762 (match_operand:FMA_F 1 "gpc_reg_operand" "") | 13664 (match_operand:FMA_F 1 "gpc_reg_operand") |
13763 (match_operand:FMA_F 2 "gpc_reg_operand" "") | 13665 (match_operand:FMA_F 2 "gpc_reg_operand") |
13764 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))] | 13666 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))] |
13765 "" | 13667 "" |
13766 "") | 13668 "") |
13767 | 13669 |
13768 (define_insn "*nfmssf4_fpr" | 13670 (define_insn "*nfmssf4_fpr" |
13769 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>") | 13671 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>") |
13771 (fma:SFDF | 13673 (fma:SFDF |
13772 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>") | 13674 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>") |
13773 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0") | 13675 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0") |
13774 (neg:SFDF | 13676 (neg:SFDF |
13775 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))] | 13677 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))] |
13776 "TARGET_<MODE>_FPR" | 13678 "TARGET_HARD_FLOAT" |
13777 "@ | 13679 "@ |
13778 fnmsub<Ftrad> %0,%1,%2,%3 | 13680 fnmsub<Ftrad> %0,%1,%2,%3 |
13779 xsnmsuba<Fvsx> %x0,%x1,%x2 | 13681 xsnmsuba<Fvsx> %x0,%x1,%x2 |
13780 xsnmsubm<Fvsx> %x0,%x1,%x3" | 13682 xsnmsubm<Fvsx> %x0,%x1,%x3" |
13781 [(set_attr "type" "fp") | 13683 [(set_attr "type" "fp")]) |
13782 (set_attr "fp_type" "fp_maddsub_<Fs>")]) | |
13783 | 13684 |
13784 | 13685 |
13785 (define_expand "rs6000_get_timebase" | 13686 (define_expand "rs6000_get_timebase" |
13786 [(use (match_operand:DI 0 "gpc_reg_operand" ""))] | 13687 [(use (match_operand:DI 0 "gpc_reg_operand"))] |
13787 "" | 13688 "" |
13788 { | 13689 { |
13789 if (TARGET_POWERPC64) | 13690 if (TARGET_POWERPC64) |
13790 emit_insn (gen_rs6000_mftb_di (operands[0])); | 13691 emit_insn (gen_rs6000_mftb_di (operands[0])); |
13791 else | 13692 else |
13847 else | 13748 else |
13848 return "mftb %0"; | 13749 return "mftb %0"; |
13849 }) | 13750 }) |
13850 | 13751 |
13851 | 13752 |
13753 ;; The ISA 3.0 mffsl instruction is a lower latency instruction | |
13754 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR. | |
13755 (define_insn "rs6000_mffsl_hw" | |
13756 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") | |
13757 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))] | |
13758 "TARGET_HARD_FLOAT" | |
13759 "mffsl %0") | |
13760 | |
13761 (define_expand "rs6000_mffsl" | |
13762 [(set (match_operand:DF 0 "gpc_reg_operand") | |
13763 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))] | |
13764 "TARGET_HARD_FLOAT" | |
13765 { | |
13766 /* If the low latency mffsl instruction (ISA 3.0) is available use it, | |
13767 otherwise fall back to the older mffs instruction to emulate the mffsl | |
13768 instruction. */ | |
13769 | |
13770 if (!TARGET_P9_MISC) | |
13771 { | |
13772 rtx tmp_di = gen_reg_rtx (DImode); | |
13773 rtx tmp_df = gen_reg_rtx (DFmode); | |
13774 | |
13775 /* The mffs instruction reads the entire FPSCR. Emulate the mffsl | |
13776 instruction using the mffs instruction and masking off the bits | |
13777 the mmsl instruciton actually reads. */ | |
13778 emit_insn (gen_rs6000_mffs (tmp_df)); | |
13779 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0); | |
13780 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0x70007f0ffLL))); | |
13781 | |
13782 operands[0] = simplify_gen_subreg (DFmode, tmp_di, DImode, 0); | |
13783 DONE; | |
13784 } | |
13785 | |
13786 emit_insn (gen_rs6000_mffsl_hw (operands[0])); | |
13787 DONE; | |
13788 }) | |
13789 | |
13852 (define_insn "rs6000_mffs" | 13790 (define_insn "rs6000_mffs" |
13853 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") | 13791 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") |
13854 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))] | 13792 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))] |
13855 "TARGET_HARD_FLOAT" | 13793 "TARGET_HARD_FLOAT" |
13856 "mffs %0") | 13794 "mffs %0") |
13860 (match_operand:DF 1 "gpc_reg_operand" "d")] | 13798 (match_operand:DF 1 "gpc_reg_operand" "d")] |
13861 UNSPECV_MTFSF)] | 13799 UNSPECV_MTFSF)] |
13862 "TARGET_HARD_FLOAT" | 13800 "TARGET_HARD_FLOAT" |
13863 "mtfsf %0,%1") | 13801 "mtfsf %0,%1") |
13864 | 13802 |
13803 (define_insn "rs6000_mtfsf_hi" | |
13804 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n") | |
13805 (match_operand:DF 1 "gpc_reg_operand" "d")] | |
13806 UNSPECV_MTFSF_HI)] | |
13807 "TARGET_HARD_FLOAT" | |
13808 "mtfsf %0,%1,0,1") | |
13809 | |
13865 | 13810 |
13866 ;; Power8 fusion support for fusing an addis instruction with a D-form load of | 13811 ;; Power8 fusion support for fusing an addis instruction with a D-form load of |
13867 ;; a GPR. The addis instruction must be adjacent to the load, and use the same | 13812 ;; a GPR. The addis instruction must be adjacent to the load, and use the same |
13868 ;; register that is being loaded. The fused ops must be physically adjacent. | 13813 ;; register that is being loaded. The fused ops must be physically adjacent. |
13869 | 13814 |
13870 ;; There are two parts to addis fusion. The support for fused TOCs occur | 13815 ;; On Power8 GPR loads, we try to use the register that is being load. The |
13871 ;; before register allocation, and is meant to reduce the lifetime for the | 13816 ;; peephole2 then gathers any other fused possibilities that it can find after |
13872 ;; tempoary register that holds the ADDIS result. On Power8 GPR loads, we try | 13817 ;; register allocation. If power9 fusion is selected, we also fuse floating |
13873 ;; to use the register that is being load. The peephole2 then gathers any | 13818 ;; point loads/stores. |
13874 ;; other fused possibilities that it can find after register allocation. If | 13819 |
13875 ;; power9 fusion is selected, we also fuse floating point loads/stores. | |
13876 | |
13877 ;; Fused TOC support: Replace simple GPR loads with a fused form. This is done | |
13878 ;; before register allocation, so that we can avoid allocating a temporary base | |
13879 ;; register that won't be used, and that we try to load into base registers, | |
13880 ;; and not register 0. If we can't get a fused GPR load, generate a P9 fusion | |
13881 ;; (addis followed by load) even on power8. | |
13882 | |
13883 (define_split | |
13884 [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "") | |
13885 (match_operand:INT1 1 "toc_fusion_mem_raw" ""))] | |
13886 "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()" | |
13887 [(parallel [(set (match_dup 0) (match_dup 2)) | |
13888 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS) | |
13889 (use (match_dup 3)) | |
13890 (clobber (scratch:DI))])] | |
13891 { | |
13892 operands[2] = fusion_wrap_memory_address (operands[1]); | |
13893 operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER); | |
13894 }) | |
13895 | |
13896 (define_insn "*toc_fusionload_<mode>" | |
13897 [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r") | |
13898 (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG")) | |
13899 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS) | |
13900 (use (match_operand:DI 2 "base_reg_operand" "r,r")) | |
13901 (clobber (match_scratch:DI 3 "=X,&b"))] | |
13902 "TARGET_TOC_FUSION_INT" | |
13903 { | |
13904 if (base_reg_operand (operands[0], <MODE>mode)) | |
13905 return emit_fusion_gpr_load (operands[0], operands[1]); | |
13906 | |
13907 return emit_fusion_p9_load (operands[0], operands[1], operands[3]); | |
13908 } | |
13909 [(set_attr "type" "load") | |
13910 (set_attr "length" "8")]) | |
13911 | |
13912 (define_insn "*toc_fusionload_di" | |
13913 [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d") | |
13914 (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG")) | |
13915 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS) | |
13916 (use (match_operand:DI 2 "base_reg_operand" "r,r,r")) | |
13917 (clobber (match_scratch:DI 3 "=X,&b,&b"))] | |
13918 "TARGET_TOC_FUSION_INT && TARGET_POWERPC64 | |
13919 && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))" | |
13920 { | |
13921 if (base_reg_operand (operands[0], DImode)) | |
13922 return emit_fusion_gpr_load (operands[0], operands[1]); | |
13923 | |
13924 return emit_fusion_p9_load (operands[0], operands[1], operands[3]); | |
13925 } | |
13926 [(set_attr "type" "load") | |
13927 (set_attr "length" "8")]) | |
13928 | |
13929 | |
13930 ;; Find cases where the addis that feeds into a load instruction is either used | 13820 ;; Find cases where the addis that feeds into a load instruction is either used |
13931 ;; once or is the same as the target register, and replace it with the fusion | 13821 ;; once or is the same as the target register, and replace it with the fusion |
13932 ;; insn | 13822 ;; insn |
13933 | 13823 |
13934 (define_peephole2 | 13824 (define_peephole2 |
13935 [(set (match_operand:P 0 "base_reg_operand" "") | 13825 [(set (match_operand:P 0 "base_reg_operand") |
13936 (match_operand:P 1 "fusion_gpr_addis" "")) | 13826 (match_operand:P 1 "fusion_gpr_addis")) |
13937 (set (match_operand:INT1 2 "base_reg_operand" "") | 13827 (set (match_operand:INT1 2 "base_reg_operand") |
13938 (match_operand:INT1 3 "fusion_gpr_mem_load" ""))] | 13828 (match_operand:INT1 3 "fusion_gpr_mem_load"))] |
13939 "TARGET_P8_FUSION | 13829 "TARGET_P8_FUSION |
13940 && fusion_gpr_load_p (operands[0], operands[1], operands[2], | 13830 && fusion_gpr_load_p (operands[0], operands[1], operands[2], |
13941 operands[3])" | 13831 operands[3])" |
13942 [(const_int 0)] | 13832 [(const_int 0)] |
13943 { | 13833 { |
13946 }) | 13836 }) |
13947 | 13837 |
13948 ;; Fusion insn, created by the define_peephole2 above (and eventually by | 13838 ;; Fusion insn, created by the define_peephole2 above (and eventually by |
13949 ;; reload) | 13839 ;; reload) |
13950 | 13840 |
13951 (define_insn "fusion_gpr_load_<mode>" | 13841 (define_insn "*fusion_gpr_load_<mode>" |
13952 [(set (match_operand:INT1 0 "base_reg_operand" "=b") | 13842 [(set (match_operand:INT1 0 "base_reg_operand" "=b") |
13953 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")] | 13843 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")] |
13954 UNSPEC_FUSION_GPR))] | 13844 UNSPEC_FUSION_GPR))] |
13955 "TARGET_P8_FUSION" | 13845 "TARGET_P8_FUSION" |
13956 { | 13846 { |
13961 | 13851 |
13962 | 13852 |
13963 ;; ISA 3.0 (power9) fusion support | 13853 ;; ISA 3.0 (power9) fusion support |
13964 ;; Merge addis with floating load/store to FPRs (or GPRs). | 13854 ;; Merge addis with floating load/store to FPRs (or GPRs). |
13965 (define_peephole2 | 13855 (define_peephole2 |
13966 [(set (match_operand:P 0 "base_reg_operand" "") | 13856 [(set (match_operand:P 0 "base_reg_operand") |
13967 (match_operand:P 1 "fusion_gpr_addis" "")) | 13857 (match_operand:P 1 "fusion_gpr_addis")) |
13968 (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "") | 13858 (set (match_operand:SFDF 2 "p9_fusion_reg_operand") |
13969 (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))] | 13859 (match_operand:SFDF 3 "fusion_offsettable_mem_operand"))] |
13970 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0]) | 13860 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0]) |
13971 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])" | 13861 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])" |
13972 [(const_int 0)] | 13862 [(const_int 0)] |
13973 { | 13863 { |
13974 expand_fusion_p9_load (operands); | 13864 expand_fusion_p9_load (operands); |
13975 DONE; | 13865 DONE; |
13976 }) | 13866 }) |
13977 | 13867 |
13978 (define_peephole2 | 13868 (define_peephole2 |
13979 [(set (match_operand:P 0 "base_reg_operand" "") | 13869 [(set (match_operand:P 0 "base_reg_operand") |
13980 (match_operand:P 1 "fusion_gpr_addis" "")) | 13870 (match_operand:P 1 "fusion_gpr_addis")) |
13981 (set (match_operand:SFDF 2 "offsettable_mem_operand" "") | 13871 (set (match_operand:SFDF 2 "offsettable_mem_operand") |
13982 (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))] | 13872 (match_operand:SFDF 3 "p9_fusion_reg_operand"))] |
13983 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0]) | 13873 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0]) |
13984 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3]) | 13874 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3]) |
13985 && !rtx_equal_p (operands[0], operands[3])" | 13875 && !rtx_equal_p (operands[0], operands[3])" |
13986 [(const_int 0)] | 13876 [(const_int 0)] |
13987 { | 13877 { |
13988 expand_fusion_p9_store (operands); | 13878 expand_fusion_p9_store (operands); |
13989 DONE; | 13879 DONE; |
13990 }) | 13880 }) |
13991 | 13881 |
13992 (define_peephole2 | 13882 (define_peephole2 |
13993 [(set (match_operand:SDI 0 "int_reg_operand" "") | 13883 [(set (match_operand:SDI 0 "int_reg_operand") |
13994 (match_operand:SDI 1 "upper16_cint_operand" "")) | 13884 (match_operand:SDI 1 "upper16_cint_operand")) |
13995 (set (match_dup 0) | 13885 (set (match_dup 0) |
13996 (ior:SDI (match_dup 0) | 13886 (ior:SDI (match_dup 0) |
13997 (match_operand:SDI 2 "u_short_cint_operand" "")))] | 13887 (match_operand:SDI 2 "u_short_cint_operand")))] |
13998 "TARGET_P9_FUSION" | 13888 "TARGET_P9_FUSION" |
13999 [(set (match_dup 0) | 13889 [(set (match_dup 0) |
14000 (unspec:SDI [(match_dup 1) | 13890 (unspec:SDI [(match_dup 1) |
14001 (match_dup 2)] UNSPEC_FUSION_P9))]) | 13891 (match_dup 2)] UNSPEC_FUSION_P9))]) |
14002 | 13892 |
14003 (define_peephole2 | 13893 (define_peephole2 |
14004 [(set (match_operand:SDI 0 "int_reg_operand" "") | 13894 [(set (match_operand:SDI 0 "int_reg_operand") |
14005 (match_operand:SDI 1 "upper16_cint_operand" "")) | 13895 (match_operand:SDI 1 "upper16_cint_operand")) |
14006 (set (match_operand:SDI 2 "int_reg_operand" "") | 13896 (set (match_operand:SDI 2 "int_reg_operand") |
14007 (ior:SDI (match_dup 0) | 13897 (ior:SDI (match_dup 0) |
14008 (match_operand:SDI 3 "u_short_cint_operand" "")))] | 13898 (match_operand:SDI 3 "u_short_cint_operand")))] |
14009 "TARGET_P9_FUSION | 13899 "TARGET_P9_FUSION |
14010 && !rtx_equal_p (operands[0], operands[2]) | 13900 && !rtx_equal_p (operands[0], operands[2]) |
14011 && peep2_reg_dead_p (2, operands[0])" | 13901 && peep2_reg_dead_p (2, operands[0])" |
14012 [(set (match_dup 2) | 13902 [(set (match_dup 2) |
14013 (unspec:SDI [(match_dup 1) | 13903 (unspec:SDI [(match_dup 1) |
14015 | 13905 |
14016 ;; Fusion insns, created by the define_peephole2 above (and eventually by | 13906 ;; Fusion insns, created by the define_peephole2 above (and eventually by |
14017 ;; reload). Because we want to eventually have secondary_reload generate | 13907 ;; reload). Because we want to eventually have secondary_reload generate |
14018 ;; these, they have to have a single alternative that gives the register | 13908 ;; these, they have to have a single alternative that gives the register |
14019 ;; classes. This means we need to have separate gpr/fpr/altivec versions. | 13909 ;; classes. This means we need to have separate gpr/fpr/altivec versions. |
14020 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load" | 13910 (define_insn "*fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load" |
14021 [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r") | 13911 [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r") |
14022 (unspec:GPR_FUSION | 13912 (unspec:GPR_FUSION |
14023 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")] | 13913 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")] |
14024 UNSPEC_FUSION_P9)) | 13914 UNSPEC_FUSION_P9)) |
14025 (clobber (match_operand:P 2 "base_reg_operand" "=b"))] | 13915 (clobber (match_operand:P 2 "base_reg_operand" "=b"))] |
14033 return emit_fusion_p9_load (operands[0], operands[1], operands[2]); | 13923 return emit_fusion_p9_load (operands[0], operands[1], operands[2]); |
14034 } | 13924 } |
14035 [(set_attr "type" "load") | 13925 [(set_attr "type" "load") |
14036 (set_attr "length" "8")]) | 13926 (set_attr "length" "8")]) |
14037 | 13927 |
14038 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store" | 13928 (define_insn "*fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store" |
14039 [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF") | 13929 [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF") |
14040 (unspec:GPR_FUSION | 13930 (unspec:GPR_FUSION |
14041 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")] | 13931 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")] |
14042 UNSPEC_FUSION_P9)) | 13932 UNSPEC_FUSION_P9)) |
14043 (clobber (match_operand:P 2 "base_reg_operand" "=b"))] | 13933 (clobber (match_operand:P 2 "base_reg_operand" "=b"))] |
14046 return emit_fusion_p9_store (operands[0], operands[1], operands[2]); | 13936 return emit_fusion_p9_store (operands[0], operands[1], operands[2]); |
14047 } | 13937 } |
14048 [(set_attr "type" "store") | 13938 [(set_attr "type" "store") |
14049 (set_attr "length" "8")]) | 13939 (set_attr "length" "8")]) |
14050 | 13940 |
14051 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load" | 13941 (define_insn "*fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load" |
14052 [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb") | 13942 [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb") |
14053 (unspec:FPR_FUSION | 13943 (unspec:FPR_FUSION |
14054 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")] | 13944 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")] |
14055 UNSPEC_FUSION_P9)) | 13945 UNSPEC_FUSION_P9)) |
14056 (clobber (match_operand:P 2 "base_reg_operand" "=b"))] | 13946 (clobber (match_operand:P 2 "base_reg_operand" "=b"))] |
14059 return emit_fusion_p9_load (operands[0], operands[1], operands[2]); | 13949 return emit_fusion_p9_load (operands[0], operands[1], operands[2]); |
14060 } | 13950 } |
14061 [(set_attr "type" "fpload") | 13951 [(set_attr "type" "fpload") |
14062 (set_attr "length" "8")]) | 13952 (set_attr "length" "8")]) |
14063 | 13953 |
14064 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store" | 13954 (define_insn "*fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store" |
14065 [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF") | 13955 [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF") |
14066 (unspec:FPR_FUSION | 13956 (unspec:FPR_FUSION |
14067 [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")] | 13957 [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")] |
14068 UNSPEC_FUSION_P9)) | 13958 UNSPEC_FUSION_P9)) |
14069 (clobber (match_operand:P 2 "base_reg_operand" "=b"))] | 13959 (clobber (match_operand:P 2 "base_reg_operand" "=b"))] |
14079 (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L") | 13969 (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L") |
14080 (match_operand:SDI 2 "u_short_cint_operand" "K")] | 13970 (match_operand:SDI 2 "u_short_cint_operand" "K")] |
14081 UNSPEC_FUSION_P9))] | 13971 UNSPEC_FUSION_P9))] |
14082 "TARGET_P9_FUSION" | 13972 "TARGET_P9_FUSION" |
14083 { | 13973 { |
14084 emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>"); | 13974 emit_fusion_addis (operands[0], operands[1]); |
14085 return "ori %0,%0,%2"; | 13975 return "ori %0,%0,%2"; |
14086 } | 13976 } |
14087 [(set_attr "type" "two") | 13977 [(set_attr "type" "two") |
14088 (set_attr "length" "8")]) | 13978 (set_attr "length" "8")]) |
14089 | 13979 |
14168 (unspec:SI [(match_operand:SI 1 "register_operand" "r") | 14058 (unspec:SI [(match_operand:SI 1 "register_operand" "r") |
14169 (match_operand:SI 2 "register_operand" "r")] | 14059 (match_operand:SI 2 "register_operand" "r")] |
14170 UNSPEC_ADDG6S))] | 14060 UNSPEC_ADDG6S))] |
14171 "TARGET_POPCNTD" | 14061 "TARGET_POPCNTD" |
14172 "addg6s %0,%1,%2" | 14062 "addg6s %0,%1,%2" |
14173 [(set_attr "type" "integer") | 14063 [(set_attr "type" "integer")]) |
14174 (set_attr "length" "4")]) | |
14175 | 14064 |
14176 (define_insn "cdtbcd" | 14065 (define_insn "cdtbcd" |
14177 [(set (match_operand:SI 0 "register_operand" "=r") | 14066 [(set (match_operand:SI 0 "register_operand" "=r") |
14178 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] | 14067 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] |
14179 UNSPEC_CDTBCD))] | 14068 UNSPEC_CDTBCD))] |
14180 "TARGET_POPCNTD" | 14069 "TARGET_POPCNTD" |
14181 "cdtbcd %0,%1" | 14070 "cdtbcd %0,%1" |
14182 [(set_attr "type" "integer") | 14071 [(set_attr "type" "integer")]) |
14183 (set_attr "length" "4")]) | |
14184 | 14072 |
14185 (define_insn "cbcdtd" | 14073 (define_insn "cbcdtd" |
14186 [(set (match_operand:SI 0 "register_operand" "=r") | 14074 [(set (match_operand:SI 0 "register_operand" "=r") |
14187 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] | 14075 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] |
14188 UNSPEC_CBCDTD))] | 14076 UNSPEC_CBCDTD))] |
14189 "TARGET_POPCNTD" | 14077 "TARGET_POPCNTD" |
14190 "cbcdtd %0,%1" | 14078 "cbcdtd %0,%1" |
14191 [(set_attr "type" "integer") | 14079 [(set_attr "type" "integer")]) |
14192 (set_attr "length" "4")]) | |
14193 | 14080 |
14194 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE | 14081 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE |
14195 UNSPEC_DIVEO | 14082 UNSPEC_DIVEU]) |
14196 UNSPEC_DIVEU | |
14197 UNSPEC_DIVEUO]) | |
14198 | 14083 |
14199 (define_int_attr div_extend [(UNSPEC_DIVE "e") | 14084 (define_int_attr div_extend [(UNSPEC_DIVE "e") |
14200 (UNSPEC_DIVEO "eo") | 14085 (UNSPEC_DIVEU "eu")]) |
14201 (UNSPEC_DIVEU "eu") | |
14202 (UNSPEC_DIVEUO "euo")]) | |
14203 | 14086 |
14204 (define_insn "div<div_extend>_<mode>" | 14087 (define_insn "div<div_extend>_<mode>" |
14205 [(set (match_operand:GPR 0 "register_operand" "=r") | 14088 [(set (match_operand:GPR 0 "register_operand" "=r") |
14206 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r") | 14089 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r") |
14207 (match_operand:GPR 2 "register_operand" "r")] | 14090 (match_operand:GPR 2 "register_operand" "r")] |
14219 (IF "DF") | 14102 (IF "DF") |
14220 (TD "DI") | 14103 (TD "DI") |
14221 (KF "DI")]) | 14104 (KF "DI")]) |
14222 | 14105 |
14223 (define_expand "unpack<mode>" | 14106 (define_expand "unpack<mode>" |
14224 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "") | 14107 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand") |
14225 (unspec:<FP128_64> | 14108 (unspec:<FP128_64> |
14226 [(match_operand:FMOVE128 1 "register_operand" "") | 14109 [(match_operand:FMOVE128 1 "register_operand") |
14227 (match_operand:QI 2 "const_0_to_1_operand" "")] | 14110 (match_operand:QI 2 "const_0_to_1_operand")] |
14228 UNSPEC_UNPACK_128BIT))] | 14111 UNSPEC_UNPACK_128BIT))] |
14229 "FLOAT128_2REG_P (<MODE>mode)" | 14112 "FLOAT128_2REG_P (<MODE>mode)" |
14230 "") | 14113 "") |
14231 | 14114 |
14232 (define_insn_and_split "unpack<mode>_dm" | 14115 (define_insn_and_split "unpack<mode>_dm" |
14248 DONE; | 14131 DONE; |
14249 } | 14132 } |
14250 | 14133 |
14251 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno); | 14134 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno); |
14252 } | 14135 } |
14253 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store") | 14136 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")]) |
14254 (set_attr "length" "4")]) | |
14255 | 14137 |
14256 (define_insn_and_split "unpack<mode>_nodm" | 14138 (define_insn_and_split "unpack<mode>_nodm" |
14257 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m") | 14139 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m") |
14258 (unspec:<FP128_64> | 14140 (unspec:<FP128_64> |
14259 [(match_operand:FMOVE128 1 "register_operand" "d,d") | 14141 [(match_operand:FMOVE128 1 "register_operand" "d,d") |
14272 DONE; | 14154 DONE; |
14273 } | 14155 } |
14274 | 14156 |
14275 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno); | 14157 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno); |
14276 } | 14158 } |
14277 [(set_attr "type" "fp,fpstore") | 14159 [(set_attr "type" "fp,fpstore")]) |
14278 (set_attr "length" "4")]) | |
14279 | 14160 |
14280 (define_insn_and_split "pack<mode>" | 14161 (define_insn_and_split "pack<mode>" |
14281 [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d") | 14162 [(set (match_operand:FMOVE128 0 "register_operand" "=&d") |
14282 (unspec:FMOVE128 | 14163 (unspec:FMOVE128 |
14283 [(match_operand:<FP128_64> 1 "register_operand" "0,d") | 14164 [(match_operand:<FP128_64> 1 "register_operand" "d") |
14284 (match_operand:<FP128_64> 2 "register_operand" "d,d")] | 14165 (match_operand:<FP128_64> 2 "register_operand" "d")] |
14285 UNSPEC_PACK_128BIT))] | 14166 UNSPEC_PACK_128BIT))] |
14286 "FLOAT128_2REG_P (<MODE>mode)" | 14167 "FLOAT128_2REG_P (<MODE>mode)" |
14287 "@ | 14168 "#" |
14288 fmr %L0,%2 | 14169 "&& reload_completed" |
14289 #" | |
14290 "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])" | |
14291 [(set (match_dup 3) (match_dup 1)) | 14170 [(set (match_dup 3) (match_dup 1)) |
14292 (set (match_dup 4) (match_dup 2))] | 14171 (set (match_dup 4) (match_dup 2))] |
14293 { | 14172 { |
14294 unsigned dest_hi = REGNO (operands[0]); | 14173 unsigned dest_hi = REGNO (operands[0]); |
14295 unsigned dest_lo = dest_hi + 1; | 14174 unsigned dest_lo = dest_hi + 1; |
14298 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo)); | 14177 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo)); |
14299 | 14178 |
14300 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi); | 14179 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi); |
14301 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo); | 14180 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo); |
14302 } | 14181 } |
14303 [(set_attr "type" "fpsimple,fp") | 14182 [(set_attr "type" "fp") |
14304 (set_attr "length" "4,8")]) | 14183 (set_attr "length" "8")]) |
14305 | 14184 |
14306 (define_insn "unpack<mode>" | 14185 (define_insn "unpack<mode>" |
14307 [(set (match_operand:DI 0 "register_operand" "=wa,wa") | 14186 [(set (match_operand:DI 0 "register_operand" "=wa,wa") |
14308 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa") | 14187 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa") |
14309 (match_operand:QI 2 "const_0_to_1_operand" "O,i")] | 14188 (match_operand:QI 2 "const_0_to_1_operand" "O,i")] |
14357 (mult:IEEE128 | 14236 (mult:IEEE128 |
14358 (match_operand:IEEE128 1 "altivec_register_operand" "v") | 14237 (match_operand:IEEE128 1 "altivec_register_operand" "v") |
14359 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] | 14238 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] |
14360 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" | 14239 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" |
14361 "xsmulqp %0,%1,%2" | 14240 "xsmulqp %0,%1,%2" |
14362 [(set_attr "type" "vecfloat") | 14241 [(set_attr "type" "qmul") |
14363 (set_attr "size" "128")]) | 14242 (set_attr "size" "128")]) |
14364 | 14243 |
14365 (define_insn "div<mode>3" | 14244 (define_insn "div<mode>3" |
14366 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") | 14245 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") |
14367 (div:IEEE128 | 14246 (div:IEEE128 |
14389 { | 14268 { |
14390 if (TARGET_FLOAT128_HW) | 14269 if (TARGET_FLOAT128_HW) |
14391 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1], | 14270 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1], |
14392 operands[2])); | 14271 operands[2])); |
14393 else | 14272 else |
14394 { | 14273 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1], |
14395 rtx tmp = gen_reg_rtx (<MODE>mode); | 14274 operands[2])); |
14396 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1], | |
14397 operands[2], tmp)); | |
14398 } | |
14399 DONE; | 14275 DONE; |
14400 }) | 14276 }) |
14401 | 14277 |
14402 (define_insn "copysign<mode>3_hard" | 14278 (define_insn "copysign<mode>3_hard" |
14403 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") | 14279 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") |
14412 | 14288 |
14413 (define_insn "copysign<mode>3_soft" | 14289 (define_insn "copysign<mode>3_soft" |
14414 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") | 14290 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") |
14415 (unspec:IEEE128 | 14291 (unspec:IEEE128 |
14416 [(match_operand:IEEE128 1 "altivec_register_operand" "v") | 14292 [(match_operand:IEEE128 1 "altivec_register_operand" "v") |
14417 (match_operand:IEEE128 2 "altivec_register_operand" "v") | 14293 (match_operand:IEEE128 2 "altivec_register_operand" "v")] |
14418 (match_operand:IEEE128 3 "altivec_register_operand" "+v")] | 14294 UNSPEC_COPYSIGN)) |
14419 UNSPEC_COPYSIGN))] | 14295 (clobber (match_scratch:IEEE128 3 "=&v"))] |
14420 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" | 14296 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" |
14421 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1" | 14297 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1" |
14422 [(set_attr "type" "veccomplex") | 14298 [(set_attr "type" "veccomplex") |
14423 (set_attr "length" "8")]) | 14299 (set_attr "length" "8")]) |
14424 | 14300 |
14459 (match_operand:IEEE128 1 "altivec_register_operand" "%v") | 14335 (match_operand:IEEE128 1 "altivec_register_operand" "%v") |
14460 (match_operand:IEEE128 2 "altivec_register_operand" "v") | 14336 (match_operand:IEEE128 2 "altivec_register_operand" "v") |
14461 (match_operand:IEEE128 3 "altivec_register_operand" "0")))] | 14337 (match_operand:IEEE128 3 "altivec_register_operand" "0")))] |
14462 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" | 14338 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" |
14463 "xsmaddqp %0,%1,%2" | 14339 "xsmaddqp %0,%1,%2" |
14464 [(set_attr "type" "vecfloat") | 14340 [(set_attr "type" "qmul") |
14465 (set_attr "size" "128")]) | 14341 (set_attr "size" "128")]) |
14466 | 14342 |
14467 (define_insn "*fms<mode>4_hw" | 14343 (define_insn "*fms<mode>4_hw" |
14468 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") | 14344 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") |
14469 (fma:IEEE128 | 14345 (fma:IEEE128 |
14471 (match_operand:IEEE128 2 "altivec_register_operand" "v") | 14347 (match_operand:IEEE128 2 "altivec_register_operand" "v") |
14472 (neg:IEEE128 | 14348 (neg:IEEE128 |
14473 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))] | 14349 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))] |
14474 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" | 14350 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" |
14475 "xsmsubqp %0,%1,%2" | 14351 "xsmsubqp %0,%1,%2" |
14476 [(set_attr "type" "vecfloat") | 14352 [(set_attr "type" "qmul") |
14477 (set_attr "size" "128")]) | 14353 (set_attr "size" "128")]) |
14478 | 14354 |
14479 (define_insn "*nfma<mode>4_hw" | 14355 (define_insn "*nfma<mode>4_hw" |
14480 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") | 14356 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") |
14481 (neg:IEEE128 | 14357 (neg:IEEE128 |
14483 (match_operand:IEEE128 1 "altivec_register_operand" "%v") | 14359 (match_operand:IEEE128 1 "altivec_register_operand" "%v") |
14484 (match_operand:IEEE128 2 "altivec_register_operand" "v") | 14360 (match_operand:IEEE128 2 "altivec_register_operand" "v") |
14485 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))] | 14361 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))] |
14486 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" | 14362 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" |
14487 "xsnmaddqp %0,%1,%2" | 14363 "xsnmaddqp %0,%1,%2" |
14488 [(set_attr "type" "vecfloat") | 14364 [(set_attr "type" "qmul") |
14489 (set_attr "size" "128")]) | 14365 (set_attr "size" "128")]) |
14490 | 14366 |
14491 (define_insn "*nfms<mode>4_hw" | 14367 (define_insn "*nfms<mode>4_hw" |
14492 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") | 14368 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") |
14493 (neg:IEEE128 | 14369 (neg:IEEE128 |
14496 (match_operand:IEEE128 2 "altivec_register_operand" "v") | 14372 (match_operand:IEEE128 2 "altivec_register_operand" "v") |
14497 (neg:IEEE128 | 14373 (neg:IEEE128 |
14498 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))] | 14374 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))] |
14499 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" | 14375 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" |
14500 "xsnmsubqp %0,%1,%2" | 14376 "xsnmsubqp %0,%1,%2" |
14501 [(set_attr "type" "vecfloat") | 14377 [(set_attr "type" "qmul") |
14502 (set_attr "size" "128")]) | 14378 (set_attr "size" "128")]) |
14503 | 14379 |
14504 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw" | 14380 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw" |
14505 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") | 14381 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") |
14506 (float_extend:IEEE128 | 14382 (float_extend:IEEE128 |
14575 } | 14451 } |
14576 [(set_attr "type" "vecfloat") | 14452 [(set_attr "type" "vecfloat") |
14577 (set_attr "length" "8")]) | 14453 (set_attr "length" "8")]) |
14578 | 14454 |
14579 ;; Conversion between IEEE 128-bit and integer types | 14455 ;; Conversion between IEEE 128-bit and integer types |
14580 (define_insn "fix_<mode>di2_hw" | 14456 |
14581 [(set (match_operand:DI 0 "altivec_register_operand" "=v") | 14457 ;; The fix function for DImode and SImode was declared earlier as a |
14582 (fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))] | 14458 ;; define_expand. It calls into rs6000_expand_float128_convert if we don't |
14583 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" | 14459 ;; have IEEE 128-bit hardware support. QImode and HImode are not provided |
14584 "xscvqpsdz %0,%1" | 14460 ;; unless we have the IEEE 128-bit hardware. |
14461 ;; | |
14462 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have | |
14463 ;; to provide a GPR target that used direct move and a conversion in the GPR | |
14464 ;; which works around QImode/HImode not being allowed in vector registers in | |
14465 ;; ISA 2.07 (power8). | |
14466 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw" | |
14467 [(set (match_operand:SDI 0 "altivec_register_operand" "=v") | |
14468 (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))] | |
14469 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" | |
14470 "xscvqp<su><wd>z %0,%1" | |
14585 [(set_attr "type" "vecfloat") | 14471 [(set_attr "type" "vecfloat") |
14586 (set_attr "size" "128")]) | 14472 (set_attr "size" "128")]) |
14587 | 14473 |
14588 (define_insn "fixuns_<mode>di2_hw" | 14474 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2" |
14589 [(set (match_operand:DI 0 "altivec_register_operand" "=v") | 14475 [(set (match_operand:QHI 0 "altivec_register_operand" "=v") |
14590 (unsigned_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))] | 14476 (any_fix:QHI |
14591 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" | 14477 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] |
14592 "xscvqpudz %0,%1" | 14478 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" |
14479 "xscvqp<su>wz %0,%1" | |
14593 [(set_attr "type" "vecfloat") | 14480 [(set_attr "type" "vecfloat") |
14594 (set_attr "size" "128")]) | 14481 (set_attr "size" "128")]) |
14595 | 14482 |
14596 (define_insn "fix_<mode>si2_hw" | 14483 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit |
14597 [(set (match_operand:SI 0 "altivec_register_operand" "=v") | 14484 ;; floating point value to 8/16/32-bit integer to GPR in order to save it. |
14598 (fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))] | 14485 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem" |
14599 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" | 14486 [(set (match_operand:QHSI 0 "memory_operand" "=Z") |
14600 "xscvqpswz %0,%1" | 14487 (any_fix:QHSI |
14601 [(set_attr "type" "vecfloat") | 14488 (match_operand:IEEE128 1 "altivec_register_operand" "v"))) |
14602 (set_attr "size" "128")]) | 14489 (clobber (match_scratch:QHSI 2 "=v"))] |
14603 | |
14604 (define_insn "fixuns_<mode>si2_hw" | |
14605 [(set (match_operand:SI 0 "altivec_register_operand" "=v") | |
14606 (unsigned_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))] | |
14607 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" | |
14608 "xscvqpuwz %0,%1" | |
14609 [(set_attr "type" "vecfloat") | |
14610 (set_attr "size" "128")]) | |
14611 | |
14612 ;; Combiner pattern to prevent moving the result of converting an IEEE 128-bit | |
14613 ;; floating point value to 32-bit integer to GPR in order to save it. | |
14614 (define_insn_and_split "*fix<uns>_<mode>_mem" | |
14615 [(set (match_operand:SI 0 "memory_operand" "=Z") | |
14616 (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v"))) | |
14617 (clobber (match_scratch:SI 2 "=v"))] | |
14618 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" | 14490 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" |
14619 "#" | 14491 "#" |
14620 "&& reload_completed" | 14492 "&& reload_completed" |
14621 [(set (match_dup 2) | 14493 [(set (match_dup 2) |
14622 (any_fix:SI (match_dup 1))) | 14494 (any_fix:QHSI (match_dup 1))) |
14623 (set (match_dup 0) | 14495 (set (match_dup 0) |
14624 (match_dup 2))]) | 14496 (match_dup 2))]) |
14625 | 14497 |
14626 (define_insn "float_<mode>di2_hw" | 14498 (define_insn "float_<mode>di2_hw" |
14627 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") | 14499 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") |
14643 (set (match_dup 0) | 14515 (set (match_dup 0) |
14644 (float:IEEE128 (match_dup 2)))] | 14516 (float:IEEE128 (match_dup 2)))] |
14645 { | 14517 { |
14646 if (GET_CODE (operands[2]) == SCRATCH) | 14518 if (GET_CODE (operands[2]) == SCRATCH) |
14647 operands[2] = gen_reg_rtx (DImode); | 14519 operands[2] = gen_reg_rtx (DImode); |
14520 | |
14521 if (MEM_P (operands[1])) | |
14522 operands[1] = rs6000_address_for_fpconvert (operands[1]); | |
14648 }) | 14523 }) |
14649 | 14524 |
14650 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2" | 14525 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2" |
14651 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v") | 14526 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v") |
14652 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z"))) | 14527 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z"))) |
14706 (set (match_dup 0) | 14581 (set (match_dup 0) |
14707 (float:IEEE128 (match_dup 2)))] | 14582 (float:IEEE128 (match_dup 2)))] |
14708 { | 14583 { |
14709 if (GET_CODE (operands[2]) == SCRATCH) | 14584 if (GET_CODE (operands[2]) == SCRATCH) |
14710 operands[2] = gen_reg_rtx (DImode); | 14585 operands[2] = gen_reg_rtx (DImode); |
14586 | |
14587 if (MEM_P (operands[1])) | |
14588 operands[1] = rs6000_address_for_fpconvert (operands[1]); | |
14711 }) | 14589 }) |
14712 | 14590 |
14713 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2" | 14591 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2" |
14714 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v") | 14592 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v") |
14715 (unsigned_float:IEEE128 | 14593 (unsigned_float:IEEE128 |
14738 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di)); | 14616 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di)); |
14739 DONE; | 14617 DONE; |
14740 } | 14618 } |
14741 [(set_attr "length" "8,12,8") | 14619 [(set_attr "length" "8,12,8") |
14742 (set_attr "type" "vecfloat") | 14620 (set_attr "type" "vecfloat") |
14621 (set_attr "size" "128")]) | |
14622 | |
14623 ;; IEEE 128-bit round to integer built-in functions | |
14624 (define_insn "floor<mode>2" | |
14625 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") | |
14626 (unspec:IEEE128 | |
14627 [(match_operand:IEEE128 1 "altivec_register_operand" "v")] | |
14628 UNSPEC_FRIM))] | |
14629 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" | |
14630 "xsrqpi 1,%0,%1,3" | |
14631 [(set_attr "type" "vecfloat") | |
14632 (set_attr "size" "128")]) | |
14633 | |
14634 (define_insn "ceil<mode>2" | |
14635 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") | |
14636 (unspec:IEEE128 | |
14637 [(match_operand:IEEE128 1 "altivec_register_operand" "v")] | |
14638 UNSPEC_FRIP))] | |
14639 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" | |
14640 "xsrqpi 1,%0,%1,2" | |
14641 [(set_attr "type" "vecfloat") | |
14642 (set_attr "size" "128")]) | |
14643 | |
14644 (define_insn "btrunc<mode>2" | |
14645 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") | |
14646 (unspec:IEEE128 | |
14647 [(match_operand:IEEE128 1 "altivec_register_operand" "v")] | |
14648 UNSPEC_FRIZ))] | |
14649 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" | |
14650 "xsrqpi 1,%0,%1,1" | |
14651 [(set_attr "type" "vecfloat") | |
14652 (set_attr "size" "128")]) | |
14653 | |
14654 (define_insn "round<mode>2" | |
14655 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") | |
14656 (unspec:IEEE128 | |
14657 [(match_operand:IEEE128 1 "altivec_register_operand" "v")] | |
14658 UNSPEC_FRIN))] | |
14659 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" | |
14660 "xsrqpi 0,%0,%1,0" | |
14661 [(set_attr "type" "vecfloat") | |
14743 (set_attr "size" "128")]) | 14662 (set_attr "size" "128")]) |
14744 | 14663 |
14745 ;; IEEE 128-bit instructions with round to odd semantics | 14664 ;; IEEE 128-bit instructions with round to odd semantics |
14746 (define_insn "add<mode>3_odd" | 14665 (define_insn "add<mode>3_odd" |
14747 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") | 14666 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") |
14771 [(match_operand:IEEE128 1 "altivec_register_operand" "v") | 14690 [(match_operand:IEEE128 1 "altivec_register_operand" "v") |
14772 (match_operand:IEEE128 2 "altivec_register_operand" "v")] | 14691 (match_operand:IEEE128 2 "altivec_register_operand" "v")] |
14773 UNSPEC_MUL_ROUND_TO_ODD))] | 14692 UNSPEC_MUL_ROUND_TO_ODD))] |
14774 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" | 14693 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" |
14775 "xsmulqpo %0,%1,%2" | 14694 "xsmulqpo %0,%1,%2" |
14776 [(set_attr "type" "vecfloat") | 14695 [(set_attr "type" "qmul") |
14777 (set_attr "size" "128")]) | 14696 (set_attr "size" "128")]) |
14778 | 14697 |
14779 (define_insn "div<mode>3_odd" | 14698 (define_insn "div<mode>3_odd" |
14780 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") | 14699 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") |
14781 (unspec:IEEE128 | 14700 (unspec:IEEE128 |
14804 (match_operand:IEEE128 2 "altivec_register_operand" "v") | 14723 (match_operand:IEEE128 2 "altivec_register_operand" "v") |
14805 (match_operand:IEEE128 3 "altivec_register_operand" "0")] | 14724 (match_operand:IEEE128 3 "altivec_register_operand" "0")] |
14806 UNSPEC_FMA_ROUND_TO_ODD))] | 14725 UNSPEC_FMA_ROUND_TO_ODD))] |
14807 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" | 14726 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" |
14808 "xsmaddqpo %0,%1,%2" | 14727 "xsmaddqpo %0,%1,%2" |
14809 [(set_attr "type" "vecfloat") | 14728 [(set_attr "type" "qmul") |
14810 (set_attr "size" "128")]) | 14729 (set_attr "size" "128")]) |
14811 | 14730 |
14812 (define_insn "*fms<mode>4_odd" | 14731 (define_insn "*fms<mode>4_odd" |
14813 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") | 14732 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") |
14814 (unspec:IEEE128 | 14733 (unspec:IEEE128 |
14817 (neg:IEEE128 | 14736 (neg:IEEE128 |
14818 (match_operand:IEEE128 3 "altivec_register_operand" "0"))] | 14737 (match_operand:IEEE128 3 "altivec_register_operand" "0"))] |
14819 UNSPEC_FMA_ROUND_TO_ODD))] | 14738 UNSPEC_FMA_ROUND_TO_ODD))] |
14820 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" | 14739 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" |
14821 "xsmsubqpo %0,%1,%2" | 14740 "xsmsubqpo %0,%1,%2" |
14822 [(set_attr "type" "vecfloat") | 14741 [(set_attr "type" "qmul") |
14823 (set_attr "size" "128")]) | 14742 (set_attr "size" "128")]) |
14824 | 14743 |
14825 (define_insn "*nfma<mode>4_odd" | 14744 (define_insn "*nfma<mode>4_odd" |
14826 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") | 14745 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") |
14827 (neg:IEEE128 | 14746 (neg:IEEE128 |
14830 (match_operand:IEEE128 2 "altivec_register_operand" "v") | 14749 (match_operand:IEEE128 2 "altivec_register_operand" "v") |
14831 (match_operand:IEEE128 3 "altivec_register_operand" "0")] | 14750 (match_operand:IEEE128 3 "altivec_register_operand" "0")] |
14832 UNSPEC_FMA_ROUND_TO_ODD)))] | 14751 UNSPEC_FMA_ROUND_TO_ODD)))] |
14833 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" | 14752 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" |
14834 "xsnmaddqpo %0,%1,%2" | 14753 "xsnmaddqpo %0,%1,%2" |
14835 [(set_attr "type" "vecfloat") | 14754 [(set_attr "type" "qmul") |
14836 (set_attr "size" "128")]) | 14755 (set_attr "size" "128")]) |
14837 | 14756 |
14838 (define_insn "*nfms<mode>4_odd" | 14757 (define_insn "*nfms<mode>4_odd" |
14839 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") | 14758 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") |
14840 (neg:IEEE128 | 14759 (neg:IEEE128 |
14844 (neg:IEEE128 | 14763 (neg:IEEE128 |
14845 (match_operand:IEEE128 3 "altivec_register_operand" "0"))] | 14764 (match_operand:IEEE128 3 "altivec_register_operand" "0"))] |
14846 UNSPEC_FMA_ROUND_TO_ODD)))] | 14765 UNSPEC_FMA_ROUND_TO_ODD)))] |
14847 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" | 14766 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" |
14848 "xsnmsubqpo %0,%1,%2" | 14767 "xsnmsubqpo %0,%1,%2" |
14849 [(set_attr "type" "vecfloat") | 14768 [(set_attr "type" "qmul") |
14850 (set_attr "size" "128")]) | 14769 (set_attr "size" "128")]) |
14851 | 14770 |
14852 (define_insn "trunc<mode>df2_odd" | 14771 (define_insn "trunc<mode>df2_odd" |
14853 [(set (match_operand:DF 0 "vsx_register_operand" "=v") | 14772 [(set (match_operand:DF 0 "vsx_register_operand" "=v") |
14854 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")] | 14773 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")] |
14873 (include "sync.md") | 14792 (include "sync.md") |
14874 (include "vector.md") | 14793 (include "vector.md") |
14875 (include "vsx.md") | 14794 (include "vsx.md") |
14876 (include "altivec.md") | 14795 (include "altivec.md") |
14877 (include "dfp.md") | 14796 (include "dfp.md") |
14878 (include "paired.md") | |
14879 (include "crypto.md") | 14797 (include "crypto.md") |
14880 (include "htm.md") | 14798 (include "htm.md") |