| Index: gcc/gcc/config/rs6000/rs6000.md
|
| diff --git a/gcc/gcc/config/rs6000/rs6000.md b/gcc/gcc/config/rs6000/rs6000.md
|
| index 43931b247ab016cfb5ba72f730feba878b05302e..1418f5e624fd4c100ad94a2222f903c64f3b0ded 100644
|
| --- a/gcc/gcc/config/rs6000/rs6000.md
|
| +++ b/gcc/gcc/config/rs6000/rs6000.md
|
| @@ -1,6 +1,6 @@
|
| ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
|
| ;; Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
| -;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
|
| +;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
| ;; Free Software Foundation, Inc.
|
| ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
|
|
|
| @@ -55,6 +55,7 @@
|
|
|
| (define_constants
|
| [(UNSPEC_FRSP 0) ; frsp for POWER machines
|
| + (UNSPEC_PROBE_STACK 4) ; probe stack memory reference
|
| (UNSPEC_TIE 5) ; tie stack contents and stack pointer
|
| (UNSPEC_TOCPTR 6) ; address of a word pointing to the TOC
|
| (UNSPEC_TOC 7) ; address of the TOC (more-or-less)
|
| @@ -101,6 +102,7 @@
|
| (UNSPEC_RSQRT 48)
|
| (UNSPEC_TOCREL 49)
|
| (UNSPEC_MACHOPIC_OFFSET 50)
|
| + (UNSPEC_BPERM 51)
|
| ])
|
|
|
| ;;
|
| @@ -116,7 +118,7 @@
|
|
|
| ;; Define an insn type attribute. This is used in function unit delay
|
| ;; computations.
|
| -(define_attr "type" "integer,two,three,load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,store,store_ux,store_u,fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,insert_word,branch,cmp,fast_compare,compare,var_delayed_compare,delayed_compare,imul_compare,lmul_compare,fpcompare,cr_logical,delayed_cr,mfcr,mfcrf,mtcr,mfjmpr,mtjmpr,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,brinc,vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,vecfloat,vecfdiv,isync,sync,load_l,store_c,shift,trap,insert_dword,var_shift_rotate,cntlz,exts,mffgpr,mftgpr"
|
| +(define_attr "type" "integer,two,three,load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,store,store_ux,store_u,fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,insert_word,branch,cmp,fast_compare,compare,var_delayed_compare,delayed_compare,imul_compare,lmul_compare,fpcompare,cr_logical,delayed_cr,mfcr,mfcrf,mtcr,mfjmpr,mtjmpr,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,brinc,vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,vecfloat,vecfdiv,isync,sync,load_l,store_c,shift,trap,insert_dword,var_shift_rotate,cntlz,exts,mffgpr,mftgpr,isel"
|
| (const_string "integer"))
|
|
|
| ;; Define floating point instruction sub-types for use with Xfpu.md
|
| @@ -138,7 +140,7 @@
|
| ;; Processor type -- this attribute must exactly match the processor_type
|
| ;; enumeration in rs6000.h.
|
|
|
| -(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppce300c2,ppce300c3,ppce500mc,power4,power5,power6,cell"
|
| +(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc476,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,power4,power5,power6,power7,cell,ppca2"
|
| (const (symbol_ref "rs6000_cpu_attr")))
|
|
|
|
|
| @@ -157,6 +159,7 @@
|
| (include "mpc.md")
|
| (include "40x.md")
|
| (include "440.md")
|
| +(include "476.md")
|
| (include "603.md")
|
| (include "6xx.md")
|
| (include "7xx.md")
|
| @@ -164,11 +167,14 @@
|
| (include "8540.md")
|
| (include "e300c2c3.md")
|
| (include "e500mc.md")
|
| +(include "e500mc64.md")
|
| (include "power4.md")
|
| (include "power5.md")
|
| (include "power6.md")
|
| +(include "power7.md")
|
| (include "cell.md")
|
| (include "xfpu.md")
|
| +(include "a2.md")
|
|
|
| (include "predicates.md")
|
| (include "constraints.md")
|
| @@ -211,6 +217,10 @@
|
| (DD "TARGET_DFP")
|
| (TD "TARGET_DFP")])
|
|
|
| +; These modes do not fit in integer registers in 32-bit mode.
|
| +; but on e500v2, the gpr are 64 bit registers
|
| +(define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD])
|
| +
|
| ; Various instructions that come in SI and DI forms.
|
| ; A generic w/d attribute, for things like cmpw/cmpd.
|
| (define_mode_attr wd [(QI "b") (HI "h") (SI "w") (DI "d")])
|
| @@ -218,6 +228,19 @@
|
| ; DImode bits
|
| (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
|
|
|
| +;; ISEL/ISEL64 target selection
|
| +(define_mode_attr sel [(SI "") (DI "64")])
|
| +
|
| +;; Suffix for reload patterns
|
| +(define_mode_attr ptrsize [(SI "32bit")
|
| + (DI "64bit")])
|
| +
|
| +(define_mode_attr tptrsize [(SI "TARGET_32BIT")
|
| + (DI "TARGET_64BIT")])
|
| +
|
| +(define_mode_attr mptrsize [(SI "si")
|
| + (DI "di")])
|
| +
|
|
|
| ;; Start with fixed-point load and store insns. Here we put only the more
|
| ;; complex forms. Basic data transfer is done later.
|
| @@ -520,7 +543,7 @@
|
| "@
|
| {andil.|andi.} %2,%1,0xff
|
| #"
|
| - [(set_attr "type" "compare")
|
| + [(set_attr "type" "fast_compare,compare")
|
| (set_attr "length" "4,8")])
|
|
|
| (define_split
|
| @@ -546,7 +569,7 @@
|
| "@
|
| {andil.|andi.} %0,%1,0xff
|
| #"
|
| - [(set_attr "type" "compare")
|
| + [(set_attr "type" "fast_compare,compare")
|
| (set_attr "length" "4,8")])
|
|
|
| (define_split
|
| @@ -687,7 +710,7 @@
|
| "@
|
| {andil.|andi.} %2,%1,0xff
|
| #"
|
| - [(set_attr "type" "compare")
|
| + [(set_attr "type" "fast_compare,compare")
|
| (set_attr "length" "4,8")])
|
|
|
| (define_split
|
| @@ -713,7 +736,7 @@
|
| "@
|
| {andil.|andi.} %0,%1,0xff
|
| #"
|
| - [(set_attr "type" "compare")
|
| + [(set_attr "type" "fast_compare,compare")
|
| (set_attr "length" "4,8")])
|
|
|
| (define_split
|
| @@ -856,7 +879,7 @@
|
| "@
|
| {andil.|andi.} %2,%1,0xffff
|
| #"
|
| - [(set_attr "type" "compare")
|
| + [(set_attr "type" "fast_compare,compare")
|
| (set_attr "length" "4,8")])
|
|
|
| (define_split
|
| @@ -882,7 +905,7 @@
|
| "@
|
| {andil.|andi.} %0,%1,0xffff
|
| #"
|
| - [(set_attr "type" "compare")
|
| + [(set_attr "type" "fast_compare,compare")
|
| (set_attr "length" "4,8")])
|
|
|
| (define_split
|
| @@ -959,7 +982,7 @@
|
| [(set_attr "type" "compare")
|
| (set_attr "length" "4,8")])
|
|
|
| -;; IBM 405, 440 and 464 half-word multiplication operations.
|
| +;; IBM 405, 440, 464 and 476 half-word multiplication operations.
|
|
|
| (define_insn "*macchwc"
|
| [(set (match_operand:CC 3 "cc_reg_operand" "=x")
|
| @@ -1423,7 +1446,7 @@
|
| "mullhwu %0, %1, %2"
|
| [(set_attr "type" "imul3")])
|
|
|
| -;; IBM 405, 440 and 464 string-search dlmzb instruction support.
|
| +;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
|
| (define_insn "dlmzb"
|
| [(set (match_operand:CC 3 "cc_reg_operand" "=x")
|
| (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
|
| @@ -1670,7 +1693,7 @@
|
| "@
|
| nor. %2,%1,%1
|
| #"
|
| - [(set_attr "type" "compare")
|
| + [(set_attr "type" "fast_compare,compare")
|
| (set_attr "length" "4,8")])
|
|
|
| (define_split
|
| @@ -1696,7 +1719,7 @@
|
| "@
|
| nor. %0,%1,%1
|
| #"
|
| - [(set_attr "type" "compare")
|
| + [(set_attr "type" "fast_compare,compare")
|
| (set_attr "length" "4,8")])
|
|
|
| (define_split
|
| @@ -2060,23 +2083,42 @@
|
| "TARGET_POWER"
|
| "abs %0,%1")
|
|
|
| -(define_insn_and_split "abssi2_isel"
|
| - [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
|
| - (abs:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
|
| - (clobber (match_scratch:SI 2 "=&b"))
|
| +(define_insn_and_split "abs<mode>2_isel"
|
| + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
|
| + (abs:GPR (match_operand:GPR 1 "gpc_reg_operand" "b")))
|
| + (clobber (match_scratch:GPR 2 "=&b"))
|
| (clobber (match_scratch:CC 3 "=y"))]
|
| "TARGET_ISEL"
|
| "#"
|
| "&& reload_completed"
|
| - [(set (match_dup 2) (neg:SI (match_dup 1)))
|
| + [(set (match_dup 2) (neg:GPR (match_dup 1)))
|
| (set (match_dup 3)
|
| (compare:CC (match_dup 1)
|
| (const_int 0)))
|
| (set (match_dup 0)
|
| - (if_then_else:SI (ge (match_dup 3)
|
| - (const_int 0))
|
| - (match_dup 1)
|
| - (match_dup 2)))]
|
| + (if_then_else:GPR (ge (match_dup 3)
|
| + (const_int 0))
|
| + (match_dup 1)
|
| + (match_dup 2)))]
|
| + "")
|
| +
|
| +(define_insn_and_split "nabs<mode>2_isel"
|
| + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
|
| + (neg:GPR (abs:GPR (match_operand:GPR 1 "gpc_reg_operand" "b"))))
|
| + (clobber (match_scratch:GPR 2 "=&b"))
|
| + (clobber (match_scratch:CC 3 "=y"))]
|
| + "TARGET_ISEL"
|
| + "#"
|
| + "&& reload_completed"
|
| + [(set (match_dup 2) (neg:GPR (match_dup 1)))
|
| + (set (match_dup 3)
|
| + (compare:CC (match_dup 1)
|
| + (const_int 0)))
|
| + (set (match_dup 0)
|
| + (if_then_else:GPR (ge (match_dup 3)
|
| + (const_int 0))
|
| + (match_dup 2)
|
| + (match_dup 1)))]
|
| "")
|
|
|
| (define_insn_and_split "abssi2_nopower"
|
| @@ -2221,10 +2263,22 @@
|
| "TARGET_POPCNTB"
|
| "popcntb %0,%1")
|
|
|
| +(define_insn "popcntwsi2"
|
| + [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
|
| + (popcount:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
|
| + "TARGET_POPCNTD"
|
| + "popcntw %0,%1")
|
| +
|
| +(define_insn "popcntddi2"
|
| + [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
|
| + (popcount:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
|
| + "TARGET_POPCNTD && TARGET_POWERPC64"
|
| + "popcntd %0,%1")
|
| +
|
| (define_expand "popcount<mode>2"
|
| [(set (match_operand:GPR 0 "gpc_reg_operand" "")
|
| (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
|
| - "TARGET_POPCNTB"
|
| + "TARGET_POPCNTB || TARGET_POPCNTD"
|
| {
|
| rs6000_emit_popcount (operands[0], operands[1]);
|
| DONE;
|
| @@ -2239,15 +2293,102 @@
|
| DONE;
|
| })
|
|
|
| -(define_insn "bswapsi2"
|
| +;; Since the hardware zeros the upper part of the register, save generating the
|
| +;; AND immediate if we are converting to unsigned
|
| +(define_insn "*bswaphi2_extenddi"
|
| + [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
|
| + (zero_extend:DI
|
| + (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
|
| + "TARGET_POWERPC64"
|
| + "lhbrx %0,%y1"
|
| + [(set_attr "length" "4")
|
| + (set_attr "type" "load")])
|
| +
|
| +(define_insn "*bswaphi2_extendsi"
|
| + [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
|
| + (zero_extend:SI
|
| + (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
|
| + "TARGET_POWERPC"
|
| + "lhbrx %0,%y1"
|
| + [(set_attr "length" "4")
|
| + (set_attr "type" "load")])
|
| +
|
| +(define_expand "bswaphi2"
|
| + [(parallel [(set (match_operand:HI 0 "reg_or_mem_operand" "")
|
| + (bswap:HI
|
| + (match_operand:HI 1 "reg_or_mem_operand" "")))
|
| + (clobber (match_scratch:SI 2 ""))])]
|
| + ""
|
| +{
|
| + if (!REG_P (operands[0]) && !REG_P (operands[1]))
|
| + operands[1] = force_reg (HImode, operands[1]);
|
| +})
|
| +
|
| +(define_insn "bswaphi2_internal"
|
| + [(set (match_operand:HI 0 "reg_or_mem_operand" "=r,Z,&r")
|
| + (bswap:HI
|
| + (match_operand:HI 1 "reg_or_mem_operand" "Z,r,r")))
|
| + (clobber (match_scratch:SI 2 "=X,X,&r"))]
|
| + "TARGET_POWERPC"
|
| + "@
|
| + lhbrx %0,%y1
|
| + sthbrx %1,%y0
|
| + #"
|
| + [(set_attr "length" "4,4,12")
|
| + (set_attr "type" "load,store,*")])
|
| +
|
| +(define_split
|
| + [(set (match_operand:HI 0 "gpc_reg_operand" "")
|
| + (bswap:HI (match_operand:HI 1 "gpc_reg_operand" "")))
|
| + (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
|
| + "TARGET_POWERPC && reload_completed"
|
| + [(set (match_dup 3)
|
| + (zero_extract:SI (match_dup 4)
|
| + (const_int 8)
|
| + (const_int 16)))
|
| + (set (match_dup 2)
|
| + (and:SI (ashift:SI (match_dup 4)
|
| + (const_int 8))
|
| + (const_int 65280))) ;; 0xff00
|
| + (set (match_dup 3)
|
| + (ior:SI (match_dup 3)
|
| + (match_dup 2)))]
|
| + "
|
| +{
|
| + operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
|
| + operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
|
| +}")
|
| +
|
| +(define_insn "*bswapsi2_extenddi"
|
| + [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
|
| + (zero_extend:DI
|
| + (bswap:SI (match_operand:SI 1 "memory_operand" "Z"))))]
|
| + "TARGET_POWERPC64"
|
| + "lwbrx %0,%y1"
|
| + [(set_attr "length" "4")
|
| + (set_attr "type" "load")])
|
| +
|
| +(define_expand "bswapsi2"
|
| + [(set (match_operand:SI 0 "reg_or_mem_operand" "")
|
| + (bswap:SI
|
| + (match_operand:SI 1 "reg_or_mem_operand" "")))]
|
| + ""
|
| +{
|
| + if (!REG_P (operands[0]) && !REG_P (operands[1]))
|
| + operands[1] = force_reg (SImode, operands[1]);
|
| +})
|
| +
|
| +(define_insn "*bswapsi2_internal"
|
| [(set (match_operand:SI 0 "reg_or_mem_operand" "=r,Z,&r")
|
| - (bswap:SI (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
|
| + (bswap:SI
|
| + (match_operand:SI 1 "reg_or_mem_operand" "Z,r,r")))]
|
| ""
|
| "@
|
| {lbrx|lwbrx} %0,%y1
|
| {stbrx|stwbrx} %1,%y0
|
| #"
|
| - [(set_attr "length" "4,4,12")])
|
| + [(set_attr "length" "4,4,12")
|
| + (set_attr "type" "load,store,*")])
|
|
|
| (define_split
|
| [(set (match_operand:SI 0 "gpc_reg_operand" "")
|
| @@ -2266,6 +2407,300 @@
|
| (const_int 16)))]
|
| "")
|
|
|
| +(define_expand "bswapdi2"
|
| + [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
|
| + (bswap:DI
|
| + (match_operand:DI 1 "reg_or_mem_operand" "")))
|
| + (clobber (match_scratch:DI 2 ""))
|
| + (clobber (match_scratch:DI 3 ""))
|
| + (clobber (match_scratch:DI 4 ""))])]
|
| + ""
|
| +{
|
| + if (!REG_P (operands[0]) && !REG_P (operands[1]))
|
| + operands[1] = force_reg (DImode, operands[1]);
|
| +
|
| + if (!TARGET_POWERPC64)
|
| + {
|
| + /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
|
| + that uses 64-bit registers needs the same scratch registers as 64-bit
|
| + mode. */
|
| + emit_insn (gen_bswapdi2_32bit (operands[0], operands[1]));
|
| + DONE;
|
| + }
|
| +})
|
| +
|
| +;; Power7/cell has ldbrx/stdbrx, so use it directly
|
| +(define_insn "*bswapdi2_ldbrx"
|
| + [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,??&r")
|
| + (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
|
| + (clobber (match_scratch:DI 2 "=X,X,&r"))
|
| + (clobber (match_scratch:DI 3 "=X,X,&r"))
|
| + (clobber (match_scratch:DI 4 "=X,X,&r"))]
|
| + "TARGET_POWERPC64 && TARGET_LDBRX
|
| + && (REG_P (operands[0]) || REG_P (operands[1]))"
|
| + "@
|
| + ldbrx %0,%y1
|
| + stdbrx %1,%y0
|
| + #"
|
| + [(set_attr "length" "4,4,36")
|
| + (set_attr "type" "load,store,*")])
|
| +
|
| +;; Non-power7/cell, fall back to use lwbrx/stwbrx
|
| +(define_insn "*bswapdi2_64bit"
|
| + [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,??&r")
|
| + (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
|
| + (clobber (match_scratch:DI 2 "=&b,&b,&r"))
|
| + (clobber (match_scratch:DI 3 "=&r,&r,&r"))
|
| + (clobber (match_scratch:DI 4 "=&r,X,&r"))]
|
| + "TARGET_POWERPC64 && !TARGET_LDBRX
|
| + && (REG_P (operands[0]) || REG_P (operands[1]))"
|
| + "#"
|
| + [(set_attr "length" "16,12,36")])
|
| +
|
| +(define_split
|
| + [(set (match_operand:DI 0 "gpc_reg_operand" "")
|
| + (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
|
| + (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
|
| + (clobber (match_operand:DI 3 "gpc_reg_operand" ""))
|
| + (clobber (match_operand:DI 4 "gpc_reg_operand" ""))]
|
| + "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
|
| + [(const_int 0)]
|
| + "
|
| +{
|
| + rtx dest = operands[0];
|
| + rtx src = operands[1];
|
| + rtx op2 = operands[2];
|
| + rtx op3 = operands[3];
|
| + rtx op4 = operands[4];
|
| + rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode, 4);
|
| + rtx op4_32 = simplify_gen_subreg (SImode, op4, DImode, 4);
|
| + rtx addr1;
|
| + rtx addr2;
|
| + rtx word_high;
|
| + rtx word_low;
|
| +
|
| + addr1 = XEXP (src, 0);
|
| + if (GET_CODE (addr1) == PLUS)
|
| + {
|
| + emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
|
| + addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
|
| + }
|
| + else
|
| + {
|
| + emit_move_insn (op2, GEN_INT (4));
|
| + addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
|
| + }
|
| +
|
| + if (BYTES_BIG_ENDIAN)
|
| + {
|
| + word_high = change_address (src, SImode, addr1);
|
| + word_low = change_address (src, SImode, addr2);
|
| + }
|
| + else
|
| + {
|
| + word_high = change_address (src, SImode, addr2);
|
| + word_low = change_address (src, SImode, addr1);
|
| + }
|
| +
|
| + emit_insn (gen_bswapsi2 (op3_32, word_low));
|
| + emit_insn (gen_bswapsi2 (op4_32, word_high));
|
| + emit_insn (gen_ashldi3 (dest, op3, GEN_INT (32)));
|
| + emit_insn (gen_iordi3 (dest, dest, op4));
|
| +}")
|
| +
|
| +(define_split
|
| + [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
|
| + (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
|
| + (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
|
| + (clobber (match_operand:DI 3 "gpc_reg_operand" ""))
|
| + (clobber (match_operand:DI 4 "" ""))]
|
| + "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
|
| + [(const_int 0)]
|
| + "
|
| +{
|
| + rtx dest = operands[0];
|
| + rtx src = operands[1];
|
| + rtx op2 = operands[2];
|
| + rtx op3 = operands[3];
|
| + rtx src_si = simplify_gen_subreg (SImode, src, DImode, 4);
|
| + rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, 4);
|
| + rtx addr1;
|
| + rtx addr2;
|
| + rtx word_high;
|
| + rtx word_low;
|
| +
|
| + addr1 = XEXP (dest, 0);
|
| + if (GET_CODE (addr1) == PLUS)
|
| + {
|
| + emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
|
| + addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
|
| + }
|
| + else
|
| + {
|
| + emit_move_insn (op2, GEN_INT (4));
|
| + addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
|
| + }
|
| +
|
| + emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
|
| + if (BYTES_BIG_ENDIAN)
|
| + {
|
| + word_high = change_address (dest, SImode, addr1);
|
| + word_low = change_address (dest, SImode, addr2);
|
| + emit_insn (gen_bswapsi2 (word_high, src_si));
|
| + emit_insn (gen_bswapsi2 (word_low, op3_si));
|
| + }
|
| + else
|
| + {
|
| + word_high = change_address (dest, SImode, addr2);
|
| + word_low = change_address (dest, SImode, addr1);
|
| + emit_insn (gen_bswapsi2 (word_low, src_si));
|
| + emit_insn (gen_bswapsi2 (word_high, op3_si));
|
| + }
|
| +}")
|
| +
|
| +(define_split
|
| + [(set (match_operand:DI 0 "gpc_reg_operand" "")
|
| + (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
|
| + (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
|
| + (clobber (match_operand:DI 3 "gpc_reg_operand" ""))
|
| + (clobber (match_operand:DI 4 "" ""))]
|
| + "TARGET_POWERPC64 && reload_completed"
|
| + [(const_int 0)]
|
| + "
|
| +{
|
| + rtx dest = operands[0];
|
| + rtx src = operands[1];
|
| + rtx op2 = operands[2];
|
| + rtx op3 = operands[3];
|
| + rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, 4);
|
| + rtx src_si = simplify_gen_subreg (SImode, src, DImode, 4);
|
| + rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, 4);
|
| + rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, 4);
|
| +
|
| + emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
|
| + emit_insn (gen_bswapsi2 (dest_si, src_si));
|
| + emit_insn (gen_bswapsi2 (op3_si, op2_si));
|
| + emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
|
| + emit_insn (gen_iordi3 (dest, dest, op3));
|
| +}")
|
| +
|
| +(define_insn "bswapdi2_32bit"
|
| + [(set (match_operand:DI 0 "reg_or_mem_operand" "=&r,Z,??&r")
|
| + (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
|
| + (clobber (match_scratch:SI 2 "=&b,&b,X"))]
|
| + "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
|
| + "#"
|
| + [(set_attr "length" "16,12,36")])
|
| +
|
| +(define_split
|
| + [(set (match_operand:DI 0 "gpc_reg_operand" "")
|
| + (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
|
| + (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
|
| + "!TARGET_POWERPC64 && reload_completed"
|
| + [(const_int 0)]
|
| + "
|
| +{
|
| + rtx dest = operands[0];
|
| + rtx src = operands[1];
|
| + rtx op2 = operands[2];
|
| + rtx dest_hi = simplify_gen_subreg (SImode, dest, DImode, 0);
|
| + rtx dest_lo = simplify_gen_subreg (SImode, dest, DImode, 4);
|
| + rtx addr1;
|
| + rtx addr2;
|
| + rtx word_high;
|
| + rtx word_low;
|
| +
|
| + addr1 = XEXP (src, 0);
|
| + if (GET_CODE (addr1) == PLUS)
|
| + {
|
| + emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
|
| + addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
|
| + }
|
| + else
|
| + {
|
| + emit_move_insn (op2, GEN_INT (4));
|
| + addr2 = gen_rtx_PLUS (SImode, op2, addr1);
|
| + }
|
| +
|
| + if (BYTES_BIG_ENDIAN)
|
| + {
|
| + word_high = change_address (src, SImode, addr1);
|
| + word_low = change_address (src, SImode, addr2);
|
| + }
|
| + else
|
| + {
|
| + word_high = change_address (src, SImode, addr2);
|
| + word_low = change_address (src, SImode, addr1);
|
| + }
|
| +
|
| + emit_insn (gen_bswapsi2 (dest_hi, word_low));
|
| + emit_insn (gen_bswapsi2 (dest_lo, word_high));
|
| +}")
|
| +
|
| +(define_split
|
| + [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
|
| + (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
|
| + (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
|
| + "!TARGET_POWERPC64 && reload_completed"
|
| + [(const_int 0)]
|
| + "
|
| +{
|
| + rtx dest = operands[0];
|
| + rtx src = operands[1];
|
| + rtx op2 = operands[2];
|
| + rtx src_high = simplify_gen_subreg (SImode, src, DImode, 0);
|
| + rtx src_low = simplify_gen_subreg (SImode, src, DImode, 4);
|
| + rtx addr1;
|
| + rtx addr2;
|
| + rtx word_high;
|
| + rtx word_low;
|
| +
|
| + addr1 = XEXP (dest, 0);
|
| + if (GET_CODE (addr1) == PLUS)
|
| + {
|
| + emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
|
| + addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
|
| + }
|
| + else
|
| + {
|
| + emit_move_insn (op2, GEN_INT (4));
|
| + addr2 = gen_rtx_PLUS (SImode, op2, addr1);
|
| + }
|
| +
|
| + if (BYTES_BIG_ENDIAN)
|
| + {
|
| + word_high = change_address (dest, SImode, addr1);
|
| + word_low = change_address (dest, SImode, addr2);
|
| + }
|
| + else
|
| + {
|
| + word_high = change_address (dest, SImode, addr2);
|
| + word_low = change_address (dest, SImode, addr1);
|
| + }
|
| +
|
| + emit_insn (gen_bswapsi2 (word_high, src_low));
|
| + emit_insn (gen_bswapsi2 (word_low, src_high));
|
| +}")
|
| +
|
| +(define_split
|
| + [(set (match_operand:DI 0 "gpc_reg_operand" "")
|
| + (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
|
| + (clobber (match_operand:SI 2 "" ""))]
|
| + "!TARGET_POWERPC64 && reload_completed"
|
| + [(const_int 0)]
|
| + "
|
| +{
|
| + rtx dest = operands[0];
|
| + rtx src = operands[1];
|
| + rtx src_high = simplify_gen_subreg (SImode, src, DImode, 0);
|
| + rtx src_low = simplify_gen_subreg (SImode, src, DImode, 4);
|
| + rtx dest_high = simplify_gen_subreg (SImode, dest, DImode, 0);
|
| + rtx dest_low = simplify_gen_subreg (SImode, dest, DImode, 4);
|
| +
|
| + emit_insn (gen_bswapsi2 (dest_high, src_low));
|
| + emit_insn (gen_bswapsi2 (dest_low, src_high));
|
| +}")
|
| +
|
| (define_expand "mulsi3"
|
| [(use (match_operand:SI 0 "gpc_reg_operand" ""))
|
| (use (match_operand:SI 1 "gpc_reg_operand" ""))
|
| @@ -2852,7 +3287,7 @@
|
| {rlinm|rlwinm} %0,%1,0,%m2,%M2
|
| {andil.|andi.} %0,%1,%b2
|
| {andiu.|andis.} %0,%1,%u2"
|
| - [(set_attr "type" "*,*,compare,compare")])
|
| + [(set_attr "type" "*,*,fast_compare,fast_compare")])
|
|
|
| (define_insn "andsi3_nomc"
|
| [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
|
| @@ -2895,7 +3330,8 @@
|
| #
|
| #
|
| #"
|
| - [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare")
|
| + [(set_attr "type" "fast_compare,fast_compare,fast_compare,delayed_compare,\
|
| + compare,compare,compare,compare")
|
| (set_attr "length" "4,4,4,4,8,8,8,8")])
|
|
|
| (define_insn "*andsi3_internal3_mc"
|
| @@ -2915,7 +3351,8 @@
|
| #
|
| #
|
| #"
|
| - [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare")
|
| + [(set_attr "type" "compare,fast_compare,fast_compare,delayed_compare,compare,\
|
| + compare,compare,compare")
|
| (set_attr "length" "8,4,4,4,8,8,8,8")])
|
|
|
| (define_split
|
| @@ -2974,7 +3411,8 @@
|
| #
|
| #
|
| #"
|
| - [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare")
|
| + [(set_attr "type" "fast_compare,fast_compare,fast_compare,delayed_compare,\
|
| + compare,compare,compare,compare")
|
| (set_attr "length" "4,4,4,4,8,8,8,8")])
|
|
|
| (define_insn "*andsi3_internal5_mc"
|
| @@ -2996,7 +3434,8 @@
|
| #
|
| #
|
| #"
|
| - [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare")
|
| + [(set_attr "type" "compare,fast_compare,fast_compare,delayed_compare,compare,\
|
| + compare,compare,compare")
|
| (set_attr "length" "8,4,4,4,8,8,8,8")])
|
|
|
| (define_split
|
| @@ -3127,7 +3566,7 @@
|
| "@
|
| %q4. %3,%1,%2
|
| #"
|
| - [(set_attr "type" "compare")
|
| + [(set_attr "type" "fast_compare,compare")
|
| (set_attr "length" "4,8")])
|
|
|
| (define_split
|
| @@ -3156,7 +3595,7 @@
|
| "@
|
| %q4. %0,%1,%2
|
| #"
|
| - [(set_attr "type" "compare")
|
| + [(set_attr "type" "fast_compare,compare")
|
| (set_attr "length" "4,8")])
|
|
|
| (define_split
|
| @@ -3281,7 +3720,7 @@
|
| "@
|
| %q4. %3,%1,%2
|
| #"
|
| - [(set_attr "type" "compare")
|
| + [(set_attr "type" "fast_compare,compare")
|
| (set_attr "length" "4,8")])
|
|
|
| (define_split
|
| @@ -3310,7 +3749,7 @@
|
| "@
|
| %q4. %0,%1,%2
|
| #"
|
| - [(set_attr "type" "compare")
|
| + [(set_attr "type" "fast_compare,compare")
|
| (set_attr "length" "4,8")])
|
|
|
| (define_split
|
| @@ -3961,6 +4400,17 @@
|
| {rlinm|rlwinm} %0,%1,%h2,0xffffffff"
|
| [(set_attr "type" "var_shift_rotate,integer")])
|
|
|
| +(define_insn "*rotlsi3_64"
|
| + [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
|
| + (zero_extend:DI
|
| + (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
|
| + (match_operand:SI 2 "reg_or_cint_operand" "r,i"))))]
|
| + "TARGET_64BIT"
|
| + "@
|
| + {rlnm|rlwnm} %0,%1,%2,0xffffffff
|
| + {rlinm|rlwinm} %0,%1,%h2,0xffffffff"
|
| + [(set_attr "type" "var_shift_rotate,integer")])
|
| +
|
| (define_insn "*rotlsi3_internal2"
|
| [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
|
| (compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
|
| @@ -4305,6 +4755,17 @@
|
| {sli|slwi} %0,%1,%h2"
|
| [(set_attr "type" "var_shift_rotate,shift")])
|
|
|
| +(define_insn "*ashlsi3_64"
|
| + [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
|
| + (zero_extend:DI
|
| + (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
|
| + (match_operand:SI 2 "reg_or_cint_operand" "r,i"))))]
|
| + "TARGET_POWERPC64"
|
| + "@
|
| + {sl|slw} %0,%1,%2
|
| + {sli|slwi} %0,%1,%h2"
|
| + [(set_attr "type" "var_shift_rotate,shift")])
|
| +
|
| (define_insn ""
|
| [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
|
| (compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
|
| @@ -4542,6 +5003,17 @@
|
| {sri|srwi} %0,%1,%h2"
|
| [(set_attr "type" "integer,var_shift_rotate,shift")])
|
|
|
| +(define_insn "*lshrsi3_64"
|
| + [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
|
| + (zero_extend:DI
|
| + (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
|
| + (match_operand:SI 2 "reg_or_cint_operand" "r,i"))))]
|
| + "TARGET_POWERPC64"
|
| + "@
|
| + {sr|srw} %0,%1,%2
|
| + {sri|srwi} %0,%1,%h2"
|
| + [(set_attr "type" "var_shift_rotate,shift")])
|
| +
|
| (define_insn ""
|
| [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,?y,?y,?y")
|
| (compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r")
|
| @@ -4970,6 +5442,17 @@
|
| {srai|srawi} %0,%1,%h2"
|
| [(set_attr "type" "var_shift_rotate,shift")])
|
|
|
| +(define_insn "*ashrsi3_64"
|
| + [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
|
| + (sign_extend:DI
|
| + (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
|
| + (match_operand:SI 2 "reg_or_cint_operand" "r,i"))))]
|
| + "TARGET_POWERPC64"
|
| + "@
|
| + {sra|sraw} %0,%1,%2
|
| + {srai|srawi} %0,%1,%h2"
|
| + [(set_attr "type" "var_shift_rotate,shift")])
|
| +
|
| (define_insn ""
|
| [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
|
| (compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
|
| @@ -5119,7 +5602,7 @@
|
| "")
|
|
|
| (define_insn_and_split "*extendsfdf2_fpr"
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=f,?f,f")
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d")
|
| (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m")))]
|
| "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
|
| "@
|
| @@ -5142,7 +5625,7 @@
|
|
|
| (define_insn "*truncdfsf2_fpr"
|
| [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
| - (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "f")))]
|
| + (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d")))]
|
| "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
|
| "frsp %0,%1"
|
| [(set_attr "type" "fp")])
|
| @@ -5303,7 +5786,7 @@
|
| "fres %0,%1"
|
| [(set_attr "type" "fp")])
|
|
|
| -(define_insn ""
|
| +(define_insn "*fmaddsf4_powerpc"
|
| [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
| (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
| (match_operand:SF 2 "gpc_reg_operand" "f"))
|
| @@ -5314,7 +5797,7 @@
|
| [(set_attr "type" "fp")
|
| (set_attr "fp_type" "fp_maddsub_s")])
|
|
|
| -(define_insn ""
|
| +(define_insn "*fmaddsf4_power"
|
| [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
| (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
| (match_operand:SF 2 "gpc_reg_operand" "f"))
|
| @@ -5323,7 +5806,7 @@
|
| "{fma|fmadd} %0,%1,%2,%3"
|
| [(set_attr "type" "dmul")])
|
|
|
| -(define_insn ""
|
| +(define_insn "*fmsubsf4_powerpc"
|
| [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
| (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
| (match_operand:SF 2 "gpc_reg_operand" "f"))
|
| @@ -5334,7 +5817,7 @@
|
| [(set_attr "type" "fp")
|
| (set_attr "fp_type" "fp_maddsub_s")])
|
|
|
| -(define_insn ""
|
| +(define_insn "*fmsubsf4_power"
|
| [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
| (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
| (match_operand:SF 2 "gpc_reg_operand" "f"))
|
| @@ -5343,18 +5826,18 @@
|
| "{fms|fmsub} %0,%1,%2,%3"
|
| [(set_attr "type" "dmul")])
|
|
|
| -(define_insn ""
|
| +(define_insn "*fnmaddsf4_powerpc_1"
|
| [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
| (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
| (match_operand:SF 2 "gpc_reg_operand" "f"))
|
| (match_operand:SF 3 "gpc_reg_operand" "f"))))]
|
| "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
|
| - && TARGET_SINGLE_FLOAT && HONOR_SIGNED_ZEROS (SFmode)"
|
| + && TARGET_SINGLE_FLOAT"
|
| "fnmadds %0,%1,%2,%3"
|
| [(set_attr "type" "fp")
|
| (set_attr "fp_type" "fp_maddsub_s")])
|
|
|
| -(define_insn ""
|
| +(define_insn "*fnmaddsf4_powerpc_2"
|
| [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
| (minus:SF (mult:SF (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f"))
|
| (match_operand:SF 2 "gpc_reg_operand" "f"))
|
| @@ -5365,7 +5848,7 @@
|
| [(set_attr "type" "fp")
|
| (set_attr "fp_type" "fp_maddsub_s")])
|
|
|
| -(define_insn ""
|
| +(define_insn "*fnmaddsf4_power_1"
|
| [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
| (neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
| (match_operand:SF 2 "gpc_reg_operand" "f"))
|
| @@ -5374,7 +5857,7 @@
|
| "{fnma|fnmadd} %0,%1,%2,%3"
|
| [(set_attr "type" "dmul")])
|
|
|
| -(define_insn ""
|
| +(define_insn "*fnmaddsf4_power_2"
|
| [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
| (minus:SF (mult:SF (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f"))
|
| (match_operand:SF 2 "gpc_reg_operand" "f"))
|
| @@ -5384,18 +5867,18 @@
|
| "{fnma|fnmadd} %0,%1,%2,%3"
|
| [(set_attr "type" "dmul")])
|
|
|
| -(define_insn ""
|
| +(define_insn "*fnmsubsf4_powerpc_1"
|
| [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
| (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
| (match_operand:SF 2 "gpc_reg_operand" "f"))
|
| (match_operand:SF 3 "gpc_reg_operand" "f"))))]
|
| "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
|
| - && TARGET_SINGLE_FLOAT && HONOR_SIGNED_ZEROS (SFmode)"
|
| + && TARGET_SINGLE_FLOAT"
|
| "fnmsubs %0,%1,%2,%3"
|
| [(set_attr "type" "fp")
|
| (set_attr "fp_type" "fp_maddsub_s")])
|
|
|
| -(define_insn ""
|
| +(define_insn "*fnmsubsf4_powerpc_2"
|
| [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
| (minus:SF (match_operand:SF 3 "gpc_reg_operand" "f")
|
| (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
| @@ -5406,7 +5889,7 @@
|
| [(set_attr "type" "fp")
|
| (set_attr "fp_type" "fp_maddsub_s")])
|
|
|
| -(define_insn ""
|
| +(define_insn "*fnmsubsf4_power_1"
|
| [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
| (neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
| (match_operand:SF 2 "gpc_reg_operand" "f"))
|
| @@ -5415,7 +5898,7 @@
|
| "{fnms|fnmsub} %0,%1,%2,%3"
|
| [(set_attr "type" "dmul")])
|
|
|
| -(define_insn ""
|
| +(define_insn "*fnmsubsf4_power_2"
|
| [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
| (minus:SF (match_operand:SF 3 "gpc_reg_operand" "f")
|
| (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
| @@ -5496,9 +5979,18 @@
|
| (match_dup 5))
|
| (match_dup 3)
|
| (match_dup 4)))]
|
| - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
|
| - && !HONOR_NANS (DFmode) && !HONOR_SIGNED_ZEROS (DFmode)"
|
| + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
|
| + && ((TARGET_PPC_GFXOPT
|
| + && !HONOR_NANS (DFmode)
|
| + && !HONOR_SIGNED_ZEROS (DFmode))
|
| + || VECTOR_UNIT_VSX_P (DFmode))"
|
| {
|
| + if (VECTOR_UNIT_VSX_P (DFmode))
|
| + {
|
| + emit_insn (gen_vsx_copysigndf3 (operands[0], operands[1],
|
| + operands[2], CONST0_RTX (DFmode)));
|
| + DONE;
|
| + }
|
| operands[3] = gen_reg_rtx (DFmode);
|
| operands[4] = gen_reg_rtx (DFmode);
|
| operands[5] = CONST0_RTX (DFmode);
|
| @@ -5542,12 +6034,12 @@
|
| DONE;
|
| }")
|
|
|
| -(define_expand "movsicc"
|
| - [(set (match_operand:SI 0 "gpc_reg_operand" "")
|
| - (if_then_else:SI (match_operand 1 "comparison_operator" "")
|
| - (match_operand:SI 2 "gpc_reg_operand" "")
|
| - (match_operand:SI 3 "gpc_reg_operand" "")))]
|
| - "TARGET_ISEL"
|
| +(define_expand "mov<mode>cc"
|
| + [(set (match_operand:GPR 0 "gpc_reg_operand" "")
|
| + (if_then_else:GPR (match_operand 1 "comparison_operator" "")
|
| + (match_operand:GPR 2 "gpc_reg_operand" "")
|
| + (match_operand:GPR 3 "gpc_reg_operand" "")))]
|
| + "TARGET_ISEL<sel>"
|
| "
|
| {
|
| if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
|
| @@ -5564,31 +6056,33 @@
|
| ;; leave out the mode in operand 4 and use one pattern, but reload can
|
| ;; change the mode underneath our feet and then gets confused trying
|
| ;; to reload the value.
|
| -(define_insn "isel_signed"
|
| - [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
|
| - (if_then_else:SI
|
| +(define_insn "isel_signed_<mode>"
|
| + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
|
| + (if_then_else:GPR
|
| (match_operator 1 "comparison_operator"
|
| [(match_operand:CC 4 "cc_reg_operand" "y")
|
| (const_int 0)])
|
| - (match_operand:SI 2 "gpc_reg_operand" "b")
|
| - (match_operand:SI 3 "gpc_reg_operand" "b")))]
|
| - "TARGET_ISEL"
|
| + (match_operand:GPR 2 "gpc_reg_operand" "b")
|
| + (match_operand:GPR 3 "gpc_reg_operand" "b")))]
|
| + "TARGET_ISEL<sel>"
|
| "*
|
| { return output_isel (operands); }"
|
| - [(set_attr "length" "4")])
|
| + [(set_attr "type" "isel")
|
| + (set_attr "length" "4")])
|
|
|
| -(define_insn "isel_unsigned"
|
| - [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
|
| - (if_then_else:SI
|
| +(define_insn "isel_unsigned_<mode>"
|
| + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
|
| + (if_then_else:GPR
|
| (match_operator 1 "comparison_operator"
|
| [(match_operand:CCUNS 4 "cc_reg_operand" "y")
|
| (const_int 0)])
|
| - (match_operand:SI 2 "gpc_reg_operand" "b")
|
| - (match_operand:SI 3 "gpc_reg_operand" "b")))]
|
| - "TARGET_ISEL"
|
| + (match_operand:GPR 2 "gpc_reg_operand" "b")
|
| + (match_operand:GPR 3 "gpc_reg_operand" "b")))]
|
| + "TARGET_ISEL<sel>"
|
| "*
|
| { return output_isel (operands); }"
|
| - [(set_attr "length" "4")])
|
| + [(set_attr "type" "isel")
|
| + (set_attr "length" "4")])
|
|
|
| (define_expand "movsfcc"
|
| [(set (match_operand:SF 0 "gpc_reg_operand" "")
|
| @@ -5616,7 +6110,7 @@
|
|
|
| (define_insn "*fseldfsf4"
|
| [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
| - (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
|
| + (if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
|
| (match_operand:DF 4 "zero_fp_constant" "F"))
|
| (match_operand:SF 2 "gpc_reg_operand" "f")
|
| (match_operand:SF 3 "gpc_reg_operand" "f")))]
|
| @@ -5631,9 +6125,10 @@
|
| "")
|
|
|
| (define_insn "*negdf2_fpr"
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
| - (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
|
| - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
| + (neg:DF (match_operand:DF 1 "gpc_reg_operand" "d")))]
|
| + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
|
| + && !VECTOR_UNIT_VSX_P (DFmode)"
|
| "fneg %0,%1"
|
| [(set_attr "type" "fp")])
|
|
|
| @@ -5644,16 +6139,18 @@
|
| "")
|
|
|
| (define_insn "*absdf2_fpr"
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
| - (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
|
| - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
| + (abs:DF (match_operand:DF 1 "gpc_reg_operand" "d")))]
|
| + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
|
| + && !VECTOR_UNIT_VSX_P (DFmode)"
|
| "fabs %0,%1"
|
| [(set_attr "type" "fp")])
|
|
|
| (define_insn "*nabsdf2_fpr"
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
| - (neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f"))))]
|
| - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
| + (neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "d"))))]
|
| + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
|
| + && !VECTOR_UNIT_VSX_P (DFmode)"
|
| "fnabs %0,%1"
|
| [(set_attr "type" "fp")])
|
|
|
| @@ -5665,10 +6162,11 @@
|
| "")
|
|
|
| (define_insn "*adddf3_fpr"
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
| - (plus:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
|
| - (match_operand:DF 2 "gpc_reg_operand" "f")))]
|
| - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
| + (plus:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
|
| + (match_operand:DF 2 "gpc_reg_operand" "d")))]
|
| + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
|
| + && !VECTOR_UNIT_VSX_P (DFmode)"
|
| "{fa|fadd} %0,%1,%2"
|
| [(set_attr "type" "fp")
|
| (set_attr "fp_type" "fp_addsub_d")])
|
| @@ -5681,10 +6179,11 @@
|
| "")
|
|
|
| (define_insn "*subdf3_fpr"
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
| - (minus:DF (match_operand:DF 1 "gpc_reg_operand" "f")
|
| - (match_operand:DF 2 "gpc_reg_operand" "f")))]
|
| - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
| + (minus:DF (match_operand:DF 1 "gpc_reg_operand" "d")
|
| + (match_operand:DF 2 "gpc_reg_operand" "d")))]
|
| + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
|
| + && !VECTOR_UNIT_VSX_P (DFmode)"
|
| "{fs|fsub} %0,%1,%2"
|
| [(set_attr "type" "fp")
|
| (set_attr "fp_type" "fp_addsub_d")])
|
| @@ -5697,10 +6196,11 @@
|
| "")
|
|
|
| (define_insn "*muldf3_fpr"
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
| - (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
|
| - (match_operand:DF 2 "gpc_reg_operand" "f")))]
|
| - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
| + (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
|
| + (match_operand:DF 2 "gpc_reg_operand" "d")))]
|
| + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
|
| + && !VECTOR_UNIT_VSX_P (DFmode)"
|
| "{fm|fmul} %0,%1,%2"
|
| [(set_attr "type" "dmul")
|
| (set_attr "fp_type" "fp_mul_d")])
|
| @@ -5715,17 +6215,18 @@
|
| "")
|
|
|
| (define_insn "*divdf3_fpr"
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
| - (div:DF (match_operand:DF 1 "gpc_reg_operand" "f")
|
| - (match_operand:DF 2 "gpc_reg_operand" "f")))]
|
| - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !TARGET_SIMPLE_FPU"
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
| + (div:DF (match_operand:DF 1 "gpc_reg_operand" "d")
|
| + (match_operand:DF 2 "gpc_reg_operand" "d")))]
|
| + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && !TARGET_SIMPLE_FPU
|
| + && !VECTOR_UNIT_VSX_P (DFmode)"
|
| "{fd|fdiv} %0,%1,%2"
|
| [(set_attr "type" "ddiv")])
|
|
|
| (define_expand "recipdf3"
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
| - (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")
|
| - (match_operand:DF 2 "gpc_reg_operand" "f")]
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
| + (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")
|
| + (match_operand:DF 2 "gpc_reg_operand" "d")]
|
| UNSPEC_FRES))]
|
| "TARGET_RECIP && TARGET_HARD_FLOAT && TARGET_POPCNTB && !optimize_size
|
| && flag_finite_math_only && !flag_trapping_math"
|
| @@ -5734,82 +6235,98 @@
|
| DONE;
|
| })
|
|
|
| -(define_insn "fred"
|
| +(define_expand "fred"
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
| + (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRES))]
|
| + "(TARGET_POPCNTB || VECTOR_UNIT_VSX_P (DFmode)) && flag_finite_math_only"
|
| + "")
|
| +
|
| +(define_insn "*fred_fpr"
|
| [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
| (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))]
|
| - "TARGET_POPCNTB && flag_finite_math_only"
|
| + "TARGET_POPCNTB && flag_finite_math_only && !VECTOR_UNIT_VSX_P (DFmode)"
|
| "fre %0,%1"
|
| [(set_attr "type" "fp")])
|
|
|
| -(define_insn ""
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
| - (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
|
| - (match_operand:DF 2 "gpc_reg_operand" "f"))
|
| - (match_operand:DF 3 "gpc_reg_operand" "f")))]
|
| - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT"
|
| +(define_insn "*fmadddf4_fpr"
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
| + (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
|
| + (match_operand:DF 2 "gpc_reg_operand" "d"))
|
| + (match_operand:DF 3 "gpc_reg_operand" "d")))]
|
| + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
|
| + && VECTOR_UNIT_NONE_P (DFmode)"
|
| "{fma|fmadd} %0,%1,%2,%3"
|
| [(set_attr "type" "dmul")
|
| (set_attr "fp_type" "fp_maddsub_d")])
|
|
|
| -(define_insn ""
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
| - (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
|
| - (match_operand:DF 2 "gpc_reg_operand" "f"))
|
| - (match_operand:DF 3 "gpc_reg_operand" "f")))]
|
| - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT"
|
| +(define_insn "*fmsubdf4_fpr"
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
| + (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
|
| + (match_operand:DF 2 "gpc_reg_operand" "d"))
|
| + (match_operand:DF 3 "gpc_reg_operand" "d")))]
|
| + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
|
| + && VECTOR_UNIT_NONE_P (DFmode)"
|
| "{fms|fmsub} %0,%1,%2,%3"
|
| [(set_attr "type" "dmul")
|
| (set_attr "fp_type" "fp_maddsub_d")])
|
|
|
| -(define_insn ""
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
| - (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
|
| - (match_operand:DF 2 "gpc_reg_operand" "f"))
|
| - (match_operand:DF 3 "gpc_reg_operand" "f"))))]
|
| +(define_insn "*fnmadddf4_fpr_1"
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
| + (neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
|
| + (match_operand:DF 2 "gpc_reg_operand" "d"))
|
| + (match_operand:DF 3 "gpc_reg_operand" "d"))))]
|
| "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
|
| - && HONOR_SIGNED_ZEROS (DFmode)"
|
| + && VECTOR_UNIT_NONE_P (DFmode)"
|
| "{fnma|fnmadd} %0,%1,%2,%3"
|
| [(set_attr "type" "dmul")
|
| (set_attr "fp_type" "fp_maddsub_d")])
|
|
|
| -(define_insn ""
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
| - (minus:DF (mult:DF (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f"))
|
| - (match_operand:DF 2 "gpc_reg_operand" "f"))
|
| - (match_operand:DF 3 "gpc_reg_operand" "f")))]
|
| +(define_insn "*fnmadddf4_fpr_2"
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
| + (minus:DF (mult:DF (neg:DF (match_operand:DF 1 "gpc_reg_operand" "d"))
|
| + (match_operand:DF 2 "gpc_reg_operand" "d"))
|
| + (match_operand:DF 3 "gpc_reg_operand" "d")))]
|
| "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
|
| - && ! HONOR_SIGNED_ZEROS (DFmode)"
|
| + && ! HONOR_SIGNED_ZEROS (DFmode) && VECTOR_UNIT_NONE_P (DFmode)"
|
| "{fnma|fnmadd} %0,%1,%2,%3"
|
| [(set_attr "type" "dmul")
|
| (set_attr "fp_type" "fp_maddsub_d")])
|
|
|
| -(define_insn ""
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
| - (neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
|
| - (match_operand:DF 2 "gpc_reg_operand" "f"))
|
| - (match_operand:DF 3 "gpc_reg_operand" "f"))))]
|
| +(define_insn "*fnmsubdf4_fpr_1"
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
| + (neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
|
| + (match_operand:DF 2 "gpc_reg_operand" "d"))
|
| + (match_operand:DF 3 "gpc_reg_operand" "d"))))]
|
| "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
|
| - && HONOR_SIGNED_ZEROS (DFmode)"
|
| + && VECTOR_UNIT_NONE_P (DFmode)"
|
| "{fnms|fnmsub} %0,%1,%2,%3"
|
| [(set_attr "type" "dmul")
|
| (set_attr "fp_type" "fp_maddsub_d")])
|
|
|
| -(define_insn ""
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
| - (minus:DF (match_operand:DF 3 "gpc_reg_operand" "f")
|
| - (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
|
| - (match_operand:DF 2 "gpc_reg_operand" "f"))))]
|
| +(define_insn "*fnmsubdf4_fpr_2"
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
| + (minus:DF (match_operand:DF 3 "gpc_reg_operand" "d")
|
| + (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%d")
|
| + (match_operand:DF 2 "gpc_reg_operand" "d"))))]
|
| "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD && TARGET_DOUBLE_FLOAT
|
| - && ! HONOR_SIGNED_ZEROS (DFmode)"
|
| + && ! HONOR_SIGNED_ZEROS (DFmode) && VECTOR_UNIT_NONE_P (DFmode)"
|
| "{fnms|fnmsub} %0,%1,%2,%3"
|
| [(set_attr "type" "dmul")
|
| (set_attr "fp_type" "fp_maddsub_d")])
|
|
|
| -(define_insn "sqrtdf2"
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
| - (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
|
| +(define_expand "sqrtdf2"
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "")
|
| + (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
|
| "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS
|
| && TARGET_DOUBLE_FLOAT"
|
| + "")
|
| +
|
| +(define_insn "*sqrtdf2_fpr"
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
| + (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "d")))]
|
| + "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS
|
| + && TARGET_DOUBLE_FLOAT
|
| + && !VECTOR_UNIT_VSX_P (DFmode)"
|
| "fsqrt %0,%1"
|
| [(set_attr "type" "dsqrt")])
|
|
|
| @@ -5865,21 +6382,21 @@
|
| }")
|
|
|
| (define_insn "*fseldfdf4"
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
| - (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
| + (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "d")
|
| (match_operand:DF 4 "zero_fp_constant" "F"))
|
| - (match_operand:DF 2 "gpc_reg_operand" "f")
|
| - (match_operand:DF 3 "gpc_reg_operand" "f")))]
|
| + (match_operand:DF 2 "gpc_reg_operand" "d")
|
| + (match_operand:DF 3 "gpc_reg_operand" "d")))]
|
| "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
|
| "fsel %0,%1,%2,%3"
|
| [(set_attr "type" "fp")])
|
|
|
| (define_insn "*fselsfdf4"
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
| (if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
|
| (match_operand:SF 4 "zero_fp_constant" "F"))
|
| - (match_operand:DF 2 "gpc_reg_operand" "f")
|
| - (match_operand:DF 3 "gpc_reg_operand" "f")))]
|
| + (match_operand:DF 2 "gpc_reg_operand" "d")
|
| + (match_operand:DF 3 "gpc_reg_operand" "d")))]
|
| "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_SINGLE_FLOAT"
|
| "fsel %0,%1,%2,%3"
|
| [(set_attr "type" "fp")])
|
| @@ -5898,6 +6415,18 @@
|
| "TARGET_HARD_FLOAT && !TARGET_FPRS && TARGET_SINGLE_FLOAT"
|
| "")
|
|
|
| +(define_expand "fixuns_truncdfsi2"
|
| + [(set (match_operand:SI 0 "gpc_reg_operand" "")
|
| + (unsigned_fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))]
|
| + "TARGET_HARD_FLOAT && TARGET_E500_DOUBLE"
|
| + "")
|
| +
|
| +(define_expand "fixuns_truncdfdi2"
|
| + [(set (match_operand:DI 0 "register_operand" "")
|
| + (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
|
| + "TARGET_HARD_FLOAT && TARGET_VSX"
|
| + "")
|
| +
|
| ; For each of these conversions, there is a define_expand, a define_insn
|
| ; with a '#' template, and a define_split (with C code). The idea is
|
| ; to allow constant folding with the template of the define_insn,
|
| @@ -5935,16 +6464,16 @@
|
| }")
|
|
|
| (define_insn_and_split "*floatsidf2_internal"
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=&f")
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
|
| (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
|
| (use (match_operand:SI 2 "gpc_reg_operand" "r"))
|
| - (use (match_operand:DF 3 "gpc_reg_operand" "f"))
|
| + (use (match_operand:DF 3 "gpc_reg_operand" "d"))
|
| (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
|
| - (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))
|
| + (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
|
| (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
|
| "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
|
| "#"
|
| - "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[4]))"
|
| + ""
|
| [(pc)]
|
| "
|
| {
|
| @@ -6003,15 +6532,15 @@
|
| }")
|
|
|
| (define_insn_and_split "*floatunssidf2_internal"
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=&f")
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
|
| (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
|
| (use (match_operand:SI 2 "gpc_reg_operand" "r"))
|
| - (use (match_operand:DF 3 "gpc_reg_operand" "f"))
|
| + (use (match_operand:DF 3 "gpc_reg_operand" "d"))
|
| (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
|
| - (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))]
|
| + (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
|
| "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
|
| "#"
|
| - "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[4]))"
|
| + ""
|
| [(pc)]
|
| "
|
| {
|
| @@ -6072,13 +6601,13 @@
|
|
|
| (define_insn_and_split "*fix_truncdfsi2_internal"
|
| [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
|
| - (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
|
| - (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))
|
| + (fix:SI (match_operand:DF 1 "gpc_reg_operand" "d")))
|
| + (clobber (match_operand:DI 2 "gpc_reg_operand" "=d"))
|
| (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o"))]
|
| "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS
|
| && TARGET_DOUBLE_FLOAT"
|
| "#"
|
| - "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[3]))"
|
| + ""
|
| [(pc)]
|
| "
|
| {
|
| @@ -6095,8 +6624,8 @@
|
|
|
| (define_insn_and_split "fix_truncdfsi2_internal_gfxopt"
|
| [(set (match_operand:SI 0 "memory_operand" "=Z")
|
| - (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
|
| - (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))]
|
| + (fix:SI (match_operand:DF 1 "gpc_reg_operand" "d")))
|
| + (clobber (match_operand:DI 2 "gpc_reg_operand" "=d"))]
|
| "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS
|
| && TARGET_DOUBLE_FLOAT
|
| && TARGET_PPC_GFXOPT"
|
| @@ -6113,8 +6642,8 @@
|
|
|
| (define_insn_and_split "fix_truncdfsi2_mfpgpr"
|
| [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
|
| - (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
|
| - (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))
|
| + (fix:SI (match_operand:DF 1 "gpc_reg_operand" "d")))
|
| + (clobber (match_operand:DI 2 "gpc_reg_operand" "=d"))
|
| (clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))]
|
| "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
|
| && TARGET_DOUBLE_FLOAT"
|
| @@ -6131,32 +6660,46 @@
|
| ; because the first makes it clear that operand 0 is not live
|
| ; before the instruction.
|
| (define_insn "fctiwz"
|
| - [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
|
| - (unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))]
|
| + [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
|
| + (unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "d"))]
|
| UNSPEC_FCTIWZ))]
|
| "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS
|
| && TARGET_DOUBLE_FLOAT"
|
| "{fcirz|fctiwz} %0,%1"
|
| [(set_attr "type" "fp")])
|
|
|
| -(define_insn "btruncdf2"
|
| +(define_expand "btruncdf2"
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
| + (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIZ))]
|
| + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
|
| + "")
|
| +
|
| +(define_insn "*btruncdf2_fpr"
|
| [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
| (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIZ))]
|
| - "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
|
| + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
|
| + && !VECTOR_UNIT_VSX_P (DFmode)"
|
| "friz %0,%1"
|
| [(set_attr "type" "fp")])
|
|
|
| (define_insn "btruncsf2"
|
| [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
| (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIZ))]
|
| - "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT "
|
| + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
|
| "friz %0,%1"
|
| [(set_attr "type" "fp")])
|
|
|
| -(define_insn "ceildf2"
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
| - (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIP))]
|
| +(define_expand "ceildf2"
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "")
|
| + (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "")] UNSPEC_FRIP))]
|
| "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
|
| + "")
|
| +
|
| +(define_insn "*ceildf2_fpr"
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
| + (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIP))]
|
| + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
|
| + && !VECTOR_UNIT_VSX_P (DFmode)"
|
| "frip %0,%1"
|
| [(set_attr "type" "fp")])
|
|
|
| @@ -6167,10 +6710,17 @@
|
| "frip %0,%1"
|
| [(set_attr "type" "fp")])
|
|
|
| -(define_insn "floordf2"
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
| - (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIM))]
|
| +(define_expand "floordf2"
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "")
|
| + (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "")] UNSPEC_FRIM))]
|
| "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
|
| + "")
|
| +
|
| +(define_insn "*floordf2_fpr"
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
| + (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIM))]
|
| + "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
|
| + && !VECTOR_UNIT_VSX_P (DFmode)"
|
| "frim %0,%1"
|
| [(set_attr "type" "fp")])
|
|
|
| @@ -6181,9 +6731,10 @@
|
| "frim %0,%1"
|
| [(set_attr "type" "fp")])
|
|
|
| +;; No VSX equivalent to frin
|
| (define_insn "rounddf2"
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
| - (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIN))]
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
| + (unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] UNSPEC_FRIN))]
|
| "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
|
| "frin %0,%1"
|
| [(set_attr "type" "fp")])
|
| @@ -6195,10 +6746,16 @@
|
| "frin %0,%1"
|
| [(set_attr "type" "fp")])
|
|
|
| +(define_expand "ftruncdf2"
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "")
|
| + (fix:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
|
| + "VECTOR_UNIT_VSX_P (DFmode)"
|
| + "")
|
| +
|
| ; An UNSPEC is used so we don't have to support SImode in FP registers.
|
| (define_insn "stfiwx"
|
| [(set (match_operand:SI 0 "memory_operand" "=Z")
|
| - (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "f")]
|
| + (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d")]
|
| UNSPEC_STFIWX))]
|
| "TARGET_PPC_GFXOPT"
|
| "stfiwx %1,%y0"
|
| @@ -6210,17 +6767,41 @@
|
| "TARGET_HARD_FLOAT && !TARGET_FPRS"
|
| "")
|
|
|
| -(define_insn "floatdidf2"
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
| - (float:DF (match_operand:DI 1 "gpc_reg_operand" "!f#r")))]
|
| - "(TARGET_POWERPC64 || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
|
| +(define_expand "floatdidf2"
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "")
|
| + (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
|
| + "(TARGET_POWERPC64 || TARGET_XILINX_FPU || VECTOR_UNIT_VSX_P (DFmode))
|
| + && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
|
| + "")
|
| +
|
| +(define_insn "*floatdidf2_fpr"
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
| + (float:DF (match_operand:DI 1 "gpc_reg_operand" "!d#r")))]
|
| + "(TARGET_POWERPC64 || TARGET_XILINX_FPU)
|
| + && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
|
| + && !VECTOR_UNIT_VSX_P (DFmode)"
|
| "fcfid %0,%1"
|
| [(set_attr "type" "fp")])
|
|
|
| -(define_insn "fix_truncdfdi2"
|
| - [(set (match_operand:DI 0 "gpc_reg_operand" "=!f#r")
|
| - (fix:DI (match_operand:DF 1 "gpc_reg_operand" "f")))]
|
| - "(TARGET_POWERPC64 || TARGET_XILINX_FPU) && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
|
| +(define_expand "floatunsdidf2"
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "")
|
| + (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "")))]
|
| + "TARGET_VSX"
|
| + "")
|
| +
|
| +(define_expand "fix_truncdfdi2"
|
| + [(set (match_operand:DI 0 "gpc_reg_operand" "")
|
| + (fix:DI (match_operand:DF 1 "gpc_reg_operand" "")))]
|
| + "(TARGET_POWERPC64 || TARGET_XILINX_FPU || VECTOR_UNIT_VSX_P (DFmode))
|
| + && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS"
|
| + "")
|
| +
|
| +(define_insn "*fix_truncdfdi2_fpr"
|
| + [(set (match_operand:DI 0 "gpc_reg_operand" "=!d#r")
|
| + (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d")))]
|
| + "(TARGET_POWERPC64 || TARGET_XILINX_FPU)
|
| + && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
|
| + && !VECTOR_UNIT_VSX_P (DFmode)"
|
| "fctidz %0,%1"
|
| [(set_attr "type" "fp")])
|
|
|
| @@ -6247,8 +6828,8 @@
|
| ;; from double rounding.
|
| (define_insn_and_split "floatdisf2_internal1"
|
| [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
| - (float:SF (match_operand:DI 1 "gpc_reg_operand" "!f#r")))
|
| - (clobber (match_scratch:DF 2 "=f"))]
|
| + (float:SF (match_operand:DI 1 "gpc_reg_operand" "!d#r")))
|
| + (clobber (match_scratch:DF 2 "=d"))]
|
| "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT"
|
| "#"
|
| "&& reload_completed"
|
| @@ -6649,11 +7230,24 @@
|
|
|
| ;; PowerPC64 DImode operations.
|
|
|
| -(define_insn_and_split "absdi2"
|
| +(define_expand "absdi2"
|
| + [(set (match_operand:DI 0 "gpc_reg_operand" "")
|
| + (abs:DI (match_operand:DI 1 "gpc_reg_operand" "")))]
|
| + "TARGET_POWERPC64"
|
| + "
|
| +{
|
| + if (TARGET_ISEL)
|
| + emit_insn (gen_absdi2_isel (operands[0], operands[1]));
|
| + else
|
| + emit_insn (gen_absdi2_internal (operands[0], operands[1]));
|
| + DONE;
|
| +}")
|
| +
|
| +(define_insn_and_split "absdi2_internal"
|
| [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
|
| (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))
|
| (clobber (match_scratch:DI 2 "=&r,&r"))]
|
| - "TARGET_POWERPC64"
|
| + "TARGET_POWERPC64 && !TARGET_ISEL"
|
| "#"
|
| "&& reload_completed"
|
| [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 63)))
|
| @@ -6665,7 +7259,7 @@
|
| [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
|
| (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))))
|
| (clobber (match_scratch:DI 2 "=&r,&r"))]
|
| - "TARGET_POWERPC64"
|
| + "TARGET_POWERPC64 && !TARGET_ISEL"
|
| "#"
|
| "&& reload_completed"
|
| [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 63)))
|
| @@ -7609,7 +8203,7 @@
|
| andi. %0,%1,%b2
|
| andis. %0,%1,%u2
|
| #"
|
| - [(set_attr "type" "*,*,*,compare,compare,*")
|
| + [(set_attr "type" "*,*,*,fast_compare,fast_compare,*")
|
| (set_attr "length" "4,4,4,4,4,8")])
|
|
|
| (define_insn "anddi3_nomc"
|
| @@ -7667,7 +8261,9 @@
|
| #
|
| #
|
| #"
|
| - [(set_attr "type" "compare,compare,delayed_compare,compare,compare,compare,compare,compare,compare,compare,compare,compare")
|
| + [(set_attr "type" "fast_compare,compare,delayed_compare,fast_compare,\
|
| + fast_compare,compare,compare,compare,compare,compare,\
|
| + compare,compare")
|
| (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")])
|
|
|
| (define_split
|
| @@ -7718,7 +8314,9 @@
|
| #
|
| #
|
| #"
|
| - [(set_attr "type" "compare,compare,delayed_compare,compare,compare,compare,compare,compare,compare,compare,compare,compare")
|
| + [(set_attr "type" "fast_compare,compare,delayed_compare,fast_compare,\
|
| + fast_compare,compare,compare,compare,compare,compare,\
|
| + compare,compare")
|
| (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")])
|
|
|
| (define_split
|
| @@ -7858,7 +8456,7 @@
|
| "@
|
| %q4. %3,%1,%2
|
| #"
|
| - [(set_attr "type" "compare")
|
| + [(set_attr "type" "fast_compare,compare")
|
| (set_attr "length" "4,8")])
|
|
|
| (define_split
|
| @@ -7887,7 +8485,7 @@
|
| "@
|
| %q4. %0,%1,%2
|
| #"
|
| - [(set_attr "type" "compare")
|
| + [(set_attr "type" "fast_compare,compare")
|
| (set_attr "length" "4,8")])
|
|
|
| (define_split
|
| @@ -7958,7 +8556,7 @@
|
| "@
|
| %q4. %3,%2,%1
|
| #"
|
| - [(set_attr "type" "compare")
|
| + [(set_attr "type" "fast_compare,compare")
|
| (set_attr "length" "4,8")])
|
|
|
| (define_split
|
| @@ -7987,7 +8585,7 @@
|
| "@
|
| %q4. %0,%2,%1
|
| #"
|
| - [(set_attr "type" "compare")
|
| + [(set_attr "type" "fast_compare,compare")
|
| (set_attr "length" "4,8")])
|
|
|
| (define_split
|
| @@ -8024,7 +8622,7 @@
|
| "@
|
| %q4. %3,%1,%2
|
| #"
|
| - [(set_attr "type" "compare")
|
| + [(set_attr "type" "fast_compare,compare")
|
| (set_attr "length" "4,8")])
|
|
|
| (define_split
|
| @@ -8053,7 +8651,7 @@
|
| "@
|
| %q4. %0,%1,%2
|
| #"
|
| - [(set_attr "type" "compare")
|
| + [(set_attr "type" "fast_compare,compare")
|
| (set_attr "length" "4,8")])
|
|
|
| (define_split
|
| @@ -8070,6 +8668,51 @@
|
| (compare:CC (match_dup 0)
|
| (const_int 0)))]
|
| "")
|
| +
|
| +(define_expand "smindi3"
|
| + [(match_operand:DI 0 "gpc_reg_operand" "")
|
| + (match_operand:DI 1 "gpc_reg_operand" "")
|
| + (match_operand:DI 2 "gpc_reg_operand" "")]
|
| + "TARGET_ISEL64"
|
| + "
|
| +{
|
| + rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]);
|
| + DONE;
|
| +}")
|
| +
|
| +(define_expand "smaxdi3"
|
| + [(match_operand:DI 0 "gpc_reg_operand" "")
|
| + (match_operand:DI 1 "gpc_reg_operand" "")
|
| + (match_operand:DI 2 "gpc_reg_operand" "")]
|
| + "TARGET_ISEL64"
|
| + "
|
| +{
|
| + rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]);
|
| + DONE;
|
| +}")
|
| +
|
| +(define_expand "umindi3"
|
| + [(match_operand:DI 0 "gpc_reg_operand" "")
|
| + (match_operand:DI 1 "gpc_reg_operand" "")
|
| + (match_operand:DI 2 "gpc_reg_operand" "")]
|
| + "TARGET_ISEL64"
|
| + "
|
| +{
|
| + rs6000_emit_minmax (operands[0], UMIN, operands[1], operands[2]);
|
| + DONE;
|
| +}")
|
| +
|
| +(define_expand "umaxdi3"
|
| + [(match_operand:DI 0 "gpc_reg_operand" "")
|
| + (match_operand:DI 1 "gpc_reg_operand" "")
|
| + (match_operand:DI 2 "gpc_reg_operand" "")]
|
| + "TARGET_ISEL64"
|
| + "
|
| +{
|
| + rs6000_emit_minmax (operands[0], UMAX, operands[1], operands[2]);
|
| + DONE;
|
| +}")
|
| +
|
|
|
| ;; Now define ways of moving data around.
|
|
|
| @@ -8143,8 +8786,8 @@
|
| (define_insn "*movsi_internal1"
|
| [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,r,*q,*c*l,*h,*h")
|
| (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,R,*h,r,r,r,0"))]
|
| - "gpc_reg_operand (operands[0], SImode)
|
| - || gpc_reg_operand (operands[1], SImode)"
|
| + "!TARGET_SINGLE_FPU &&
|
| + (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
|
| "@
|
| mr %0,%1
|
| {cal|la} %0,%a1
|
| @@ -8162,6 +8805,30 @@
|
| [(set_attr "type" "*,*,load,store,*,*,*,*,mfjmpr,*,mtjmpr,*,*")
|
| (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
|
|
|
| +(define_insn "*movsi_internal1_single"
|
| + [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,r,*q,*c*l,*h,*h,m,*f")
|
| + (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,R,*h,r,r,r,0,f,m"))]
|
| + "TARGET_SINGLE_FPU &&
|
| + (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
|
| + "@
|
| + mr %0,%1
|
| + {cal|la} %0,%a1
|
| + {l%U1%X1|lwz%U1%X1} %0,%1
|
| + {st%U0%X0|stw%U0%X0} %1,%0
|
| + {lil|li} %0,%1
|
| + {liu|lis} %0,%v1
|
| + #
|
| + {cal|la} %0,%a1
|
| + mf%1 %0
|
| + mt%0 %1
|
| + mt%0 %1
|
| + mt%0 %1
|
| + {cror 0,0,0|nop}
|
| + stfs%U0%X0 %1, %0
|
| + lfs%U1%X1 %0, %1"
|
| + [(set_attr "type" "*,*,load,store,*,*,*,*,mfjmpr,*,mtjmpr,*,*,*,*")
|
| + (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4,4,4")])
|
| +
|
| ;; Split a load of a large constant into the appropriate two-insn
|
| ;; sequence.
|
|
|
| @@ -8473,8 +9140,8 @@
|
| ;; The "??" is a kludge until we can figure out a more reasonable way
|
| ;; of handling these non-offsettable values.
|
| (define_insn "*movdf_hardfloat32"
|
| - [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,f,f,m,!r,!r,!r")
|
| - (match_operand:DF 1 "input_operand" "r,m,r,f,m,f,G,H,F"))]
|
| + [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,ws,?wa,ws,?wa,Z,?Z,d,d,m,wa,!r,!r,!r")
|
| + (match_operand:DF 1 "input_operand" "r,m,r,ws,wa,Z,Z,ws,wa,d,m,d,j,G,H,F"))]
|
| "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
|
| && (gpc_reg_operand (operands[0], DFmode)
|
| || gpc_reg_operand (operands[1], DFmode))"
|
| @@ -8485,147 +9152,70 @@
|
| default:
|
| gcc_unreachable ();
|
| case 0:
|
| - /* We normally copy the low-numbered register first. However, if
|
| - the first register operand 0 is the same as the second register
|
| - of operand 1, we must copy in the opposite order. */
|
| - if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
|
| - return \"mr %L0,%L1\;mr %0,%1\";
|
| - else
|
| - return \"mr %0,%1\;mr %L0,%L1\";
|
| case 1:
|
| - if (rs6000_offsettable_memref_p (operands[1])
|
| - || (GET_CODE (operands[1]) == MEM
|
| - && (GET_CODE (XEXP (operands[1], 0)) == LO_SUM
|
| - || GET_CODE (XEXP (operands[1], 0)) == PRE_INC
|
| - || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC
|
| - || GET_CODE (XEXP (operands[1], 0)) == PRE_MODIFY)))
|
| - {
|
| - /* If the low-address word is used in the address, we must load
|
| - it last. Otherwise, load it first. Note that we cannot have
|
| - auto-increment in that case since the address register is
|
| - known to be dead. */
|
| - if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
|
| - operands[1], 0))
|
| - return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
|
| - else
|
| - return \"{l%U1%X1|lwz%U1%X1} %0,%1\;{l|lwz} %L0,%L1\";
|
| - }
|
| - else
|
| - {
|
| - rtx addreg;
|
| -
|
| - addreg = find_addr_reg (XEXP (operands[1], 0));
|
| - if (refers_to_regno_p (REGNO (operands[0]),
|
| - REGNO (operands[0]) + 1,
|
| - operands[1], 0))
|
| - {
|
| - output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg);
|
| - output_asm_insn (\"{l%X1|lwz%X1} %L0,%1\", operands);
|
| - output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg);
|
| - return \"{l%X1|lwz%X1} %0,%1\";
|
| - }
|
| - else
|
| - {
|
| - output_asm_insn (\"{l%X1|lwz%X1} %0,%1\", operands);
|
| - output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg);
|
| - output_asm_insn (\"{l%X1|lwz%X1} %L0,%1\", operands);
|
| - output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg);
|
| - return \"\";
|
| - }
|
| - }
|
| case 2:
|
| - if (rs6000_offsettable_memref_p (operands[0])
|
| - || (GET_CODE (operands[0]) == MEM
|
| - && (GET_CODE (XEXP (operands[0], 0)) == LO_SUM
|
| - || GET_CODE (XEXP (operands[0], 0)) == PRE_INC
|
| - || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
|
| - || GET_CODE (XEXP (operands[0], 0)) == PRE_MODIFY)))
|
| - return \"{st%U0%X0|stw%U0%X0} %1,%0\;{st|stw} %L1,%L0\";
|
| - else
|
| - {
|
| - rtx addreg;
|
| -
|
| - addreg = find_addr_reg (XEXP (operands[0], 0));
|
| - output_asm_insn (\"{st%X0|stw%X0} %1,%0\", operands);
|
| - output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg);
|
| - output_asm_insn (\"{st%X0|stw%X0} %L1,%0\", operands);
|
| - output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg);
|
| - return \"\";
|
| - }
|
| + return \"#\";
|
| case 3:
|
| - return \"fmr %0,%1\";
|
| case 4:
|
| - return \"lfd%U1%X1 %0,%1\";
|
| + return \"xxlor %x0,%x1,%x1\";
|
| case 5:
|
| - return \"stfd%U0%X0 %1,%0\";
|
| case 6:
|
| + return \"lxsd%U1x %x0,%y1\";
|
| case 7:
|
| case 8:
|
| + return \"stxsd%U0x %x1,%y0\";
|
| + case 9:
|
| + return \"fmr %0,%1\";
|
| + case 10:
|
| + return \"lfd%U1%X1 %0,%1\";
|
| + case 11:
|
| + return \"stfd%U0%X0 %1,%0\";
|
| + case 12:
|
| + return \"xxlxor %x0,%x0,%x0\";
|
| + case 13:
|
| + case 14:
|
| + case 15:
|
| return \"#\";
|
| }
|
| }"
|
| - [(set_attr "type" "two,load,store,fp,fpload,fpstore,*,*,*")
|
| - (set_attr "length" "8,16,16,4,4,4,8,12,16")])
|
| + [(set_attr "type" "two,load,store,fp,fp,fpload,fpload,fpstore,fpstore,fp,fpload,fpstore,vecsimple,*,*,*")
|
| + (set_attr "length" "8,16,16,4,4,4,4,4,4,4,4,4,4,8,12,16")])
|
|
|
| (define_insn "*movdf_softfloat32"
|
| [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r")
|
| (match_operand:DF 1 "input_operand" "r,m,r,G,H,F"))]
|
| "! TARGET_POWERPC64
|
| - && ((TARGET_FPRS && !TARGET_DOUBLE_FLOAT)
|
| + && ((TARGET_FPRS && TARGET_SINGLE_FLOAT)
|
| || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE)
|
| && (gpc_reg_operand (operands[0], DFmode)
|
| || gpc_reg_operand (operands[1], DFmode))"
|
| - "*
|
| -{
|
| - switch (which_alternative)
|
| - {
|
| - default:
|
| - gcc_unreachable ();
|
| - case 0:
|
| - /* We normally copy the low-numbered register first. However, if
|
| - the first register operand 0 is the same as the second register of
|
| - operand 1, we must copy in the opposite order. */
|
| - if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
|
| - return \"mr %L0,%L1\;mr %0,%1\";
|
| - else
|
| - return \"mr %0,%1\;mr %L0,%L1\";
|
| - case 1:
|
| - /* If the low-address word is used in the address, we must load
|
| - it last. Otherwise, load it first. Note that we cannot have
|
| - auto-increment in that case since the address register is
|
| - known to be dead. */
|
| - if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
|
| - operands[1], 0))
|
| - return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
|
| - else
|
| - return \"{l%U1%X1|lwz%U1%X1} %0,%1\;{l|lwz} %L0,%L1\";
|
| - case 2:
|
| - return \"{st%U0%X0|stw%U0%X0} %1,%0\;{st|stw} %L1,%L0\";
|
| - case 3:
|
| - case 4:
|
| - case 5:
|
| - return \"#\";
|
| - }
|
| -}"
|
| + "#"
|
| [(set_attr "type" "two,load,store,*,*,*")
|
| (set_attr "length" "8,8,8,8,12,16")])
|
|
|
| ; ld/std require word-aligned displacements -> 'Y' constraint.
|
| ; List Y->r and r->Y before r->r for reload.
|
| (define_insn "*movdf_hardfloat64_mfpgpr"
|
| - [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,f,f,m,*c*l,!r,*h,!r,!r,!r,r,f")
|
| - (match_operand:DF 1 "input_operand" "r,Y,r,f,m,f,r,h,0,G,H,F,f,r"))]
|
| + [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,ws,?wa,ws,?wa,Z,?Z,d,d,m,wa,*c*l,!r,*h,!r,!r,!r,r,d")
|
| + (match_operand:DF 1 "input_operand" "r,Y,r,ws,?wa,Z,Z,ws,wa,d,m,d,j,r,h,0,G,H,F,d,r"))]
|
| "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
|
| - && TARGET_DOUBLE_FLOAT
|
| + && TARGET_DOUBLE_FLOAT
|
| && (gpc_reg_operand (operands[0], DFmode)
|
| || gpc_reg_operand (operands[1], DFmode))"
|
| "@
|
| std%U0%X0 %1,%0
|
| ld%U1%X1 %0,%1
|
| mr %0,%1
|
| + xxlor %x0,%x1,%x1
|
| + xxlor %x0,%x1,%x1
|
| + lxsd%U1x %x0,%y1
|
| + lxsd%U1x %x0,%y1
|
| + stxsd%U0x %x1,%y0
|
| + stxsd%U0x %x1,%y0
|
| fmr %0,%1
|
| lfd%U1%X1 %0,%1
|
| stfd%U0%X0 %1,%0
|
| + xxlxor %x0,%x0,%x0
|
| mt%0 %1
|
| mf%1 %0
|
| {cror 0,0,0|nop}
|
| @@ -8634,33 +9224,40 @@
|
| #
|
| mftgpr %0,%1
|
| mffgpr %0,%1"
|
| - [(set_attr "type" "store,load,*,fp,fpload,fpstore,mtjmpr,mfjmpr,*,*,*,*,mftgpr,mffgpr")
|
| - (set_attr "length" "4,4,4,4,4,4,4,4,4,8,12,16,4,4")])
|
| + [(set_attr "type" "store,load,*,fp,fp,fpload,fpload,fpstore,fpstore,fp,fpload,fpstore,vecsimple,mtjmpr,mfjmpr,*,*,*,*,mftgpr,mffgpr")
|
| + (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,8,12,16,4,4")])
|
|
|
| ; ld/std require word-aligned displacements -> 'Y' constraint.
|
| ; List Y->r and r->Y before r->r for reload.
|
| (define_insn "*movdf_hardfloat64"
|
| - [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,f,f,m,*c*l,!r,*h,!r,!r,!r")
|
| - (match_operand:DF 1 "input_operand" "r,Y,r,f,m,f,r,h,0,G,H,F"))]
|
| + [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,ws,?wa,ws,?wa,Z,?Z,d,d,m,wa,*c*l,!r,*h,!r,!r,!r")
|
| + (match_operand:DF 1 "input_operand" "r,Y,r,ws,wa,Z,Z,ws,wa,d,m,d,j,r,h,0,G,H,F"))]
|
| "TARGET_POWERPC64 && !TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
|
| - && TARGET_DOUBLE_FLOAT
|
| + && TARGET_DOUBLE_FLOAT
|
| && (gpc_reg_operand (operands[0], DFmode)
|
| || gpc_reg_operand (operands[1], DFmode))"
|
| "@
|
| std%U0%X0 %1,%0
|
| ld%U1%X1 %0,%1
|
| mr %0,%1
|
| + xxlor %x0,%x1,%x1
|
| + xxlor %x0,%x1,%x1
|
| + lxsd%U1x %x0,%y1
|
| + lxsd%U1x %x0,%y1
|
| + stxsd%U0x %x1,%y0
|
| + stxsd%U0x %x1,%y0
|
| fmr %0,%1
|
| lfd%U1%X1 %0,%1
|
| stfd%U0%X0 %1,%0
|
| + xxlxor %x0,%x0,%x0
|
| mt%0 %1
|
| mf%1 %0
|
| {cror 0,0,0|nop}
|
| #
|
| #
|
| #"
|
| - [(set_attr "type" "store,load,*,fp,fpload,fpstore,mtjmpr,mfjmpr,*,*,*,*")
|
| - (set_attr "length" "4,4,4,4,4,4,4,4,4,8,12,16")])
|
| + [(set_attr "type" "store,load,*,fp,fp,fpload,fpload,fpstore,fpstore,fp,fpload,fpstore,vecsimple,mtjmpr,mfjmpr,*,*,*,*")
|
| + (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,8,12,16")])
|
|
|
| (define_insn "*movdf_softfloat64"
|
| [(set (match_operand:DF 0 "nonimmediate_operand" "=r,Y,r,cl,r,r,r,r,*h")
|
| @@ -8691,8 +9288,8 @@
|
| ; otherwise reload, given m->f, will try to pick f->f and reload it,
|
| ; which doesn't make progress. Likewise r->Y must be before r->r.
|
| (define_insn_and_split "*movtf_internal"
|
| - [(set (match_operand:TF 0 "nonimmediate_operand" "=o,f,f,r,Y,r")
|
| - (match_operand:TF 1 "input_operand" "f,o,f,YGHF,r,r"))]
|
| + [(set (match_operand:TF 0 "nonimmediate_operand" "=o,d,d,r,Y,r")
|
| + (match_operand:TF 1 "input_operand" "d,o,d,YGHF,r,r"))]
|
| "!TARGET_IEEEQUAD
|
| && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128
|
| && (gpc_reg_operand (operands[0], TFmode)
|
| @@ -8746,9 +9343,9 @@
|
| })
|
|
|
| (define_insn_and_split "*extenddftf2_internal"
|
| - [(set (match_operand:TF 0 "nonimmediate_operand" "=o,f,&f,r")
|
| - (float_extend:TF (match_operand:DF 1 "input_operand" "fr,mf,mf,rmGHF")))
|
| - (use (match_operand:DF 2 "zero_reg_mem_operand" "rf,m,f,n"))]
|
| + [(set (match_operand:TF 0 "nonimmediate_operand" "=o,d,&d,r")
|
| + (float_extend:TF (match_operand:DF 1 "input_operand" "dr,md,md,rmGHF")))
|
| + (use (match_operand:DF 2 "zero_reg_mem_operand" "rd,m,d,n"))]
|
| "!TARGET_IEEEQUAD
|
| && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
|
| && TARGET_LONG_DOUBLE_128"
|
| @@ -8789,8 +9386,8 @@
|
| "")
|
|
|
| (define_insn_and_split "trunctfdf2_internal1"
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=f,?f")
|
| - (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "0,f")))]
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
|
| + (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "0,d")))]
|
| "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT
|
| && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
|
| "@
|
| @@ -8805,8 +9402,8 @@
|
| [(set_attr "type" "fp")])
|
|
|
| (define_insn "trunctfdf2_internal2"
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
| - (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "f")))]
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
| + (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "d")))]
|
| "!TARGET_IEEEQUAD && TARGET_XL_COMPAT
|
| && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
|
| && TARGET_LONG_DOUBLE_128"
|
| @@ -8831,8 +9428,8 @@
|
|
|
| (define_insn_and_split "trunctfsf2_fprs"
|
| [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
| - (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "f")))
|
| - (clobber (match_scratch:DF 2 "=f"))]
|
| + (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "d")))
|
| + (clobber (match_scratch:DF 2 "=d"))]
|
| "!TARGET_IEEEQUAD
|
| && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT
|
| && TARGET_LONG_DOUBLE_128"
|
| @@ -8861,10 +9458,10 @@
|
| ; fadd, but rounding towards zero.
|
| ; This is probably not the optimal code sequence.
|
| (define_insn "fix_trunc_helper"
|
| - [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
|
| - (unspec:DF [(match_operand:TF 1 "gpc_reg_operand" "f")]
|
| + [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
|
| + (unspec:DF [(match_operand:TF 1 "gpc_reg_operand" "d")]
|
| UNSPEC_FIX_TRUNC_TF))
|
| - (clobber (match_operand:DF 2 "gpc_reg_operand" "=&f"))]
|
| + (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
|
| "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
|
| "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
|
| [(set_attr "type" "fp")
|
| @@ -8905,15 +9502,15 @@
|
|
|
| (define_insn_and_split "*fix_trunctfsi2_internal"
|
| [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
|
| - (fix:SI (match_operand:TF 1 "gpc_reg_operand" "f")))
|
| - (clobber (match_operand:DF 2 "gpc_reg_operand" "=f"))
|
| - (clobber (match_operand:DF 3 "gpc_reg_operand" "=&f"))
|
| - (clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))
|
| + (fix:SI (match_operand:TF 1 "gpc_reg_operand" "d")))
|
| + (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
|
| + (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
|
| + (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
|
| (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
|
| "!TARGET_IEEEQUAD
|
| && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
|
| "#"
|
| - "&& (can_create_pseudo_p () || offsettable_nonstrict_memref_p (operands[5]))"
|
| + ""
|
| [(pc)]
|
| {
|
| rtx lowword;
|
| @@ -8938,8 +9535,8 @@
|
| "")
|
|
|
| (define_insn "negtf2_internal"
|
| - [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
|
| - (neg:TF (match_operand:TF 1 "gpc_reg_operand" "f")))]
|
| + [(set (match_operand:TF 0 "gpc_reg_operand" "=d")
|
| + (neg:TF (match_operand:TF 1 "gpc_reg_operand" "d")))]
|
| "!TARGET_IEEEQUAD
|
| && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
|
| "*
|
| @@ -9004,8 +9601,8 @@
|
| ; List r->r after r->"o<>", otherwise reload will try to reload a
|
| ; non-offsettable address by using r->r which won't make progress.
|
| (define_insn "*movdi_internal32"
|
| - [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=o<>,r,r,*f,*f,m,r")
|
| - (match_operand:DI 1 "input_operand" "r,r,m,f,m,f,IJKnGHF"))]
|
| + [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=o<>,r,r,*d,*d,m,r")
|
| + (match_operand:DI 1 "input_operand" "r,r,m,d,m,d,IJKnGHF"))]
|
| "! TARGET_POWERPC64
|
| && (gpc_reg_operand (operands[0], DImode)
|
| || gpc_reg_operand (operands[1], DImode))"
|
| @@ -9041,16 +9638,16 @@
|
| }")
|
|
|
| (define_split
|
| - [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "")
|
| - (match_operand:DI 1 "input_operand" ""))]
|
| + [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "")
|
| + (match_operand:DIFD 1 "input_operand" ""))]
|
| "reload_completed && !TARGET_POWERPC64
|
| && gpr_or_gpr_p (operands[0], operands[1])"
|
| [(pc)]
|
| { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
|
|
|
| (define_insn "*movdi_mfpgpr"
|
| - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,*f,*f,m,r,*h,*h,r,*f")
|
| - (match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,f,m,f,*h,r,0,*f,r"))]
|
| + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,*d,*d,m,r,*h,*h,r,*d")
|
| + (match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,d,m,d,*h,r,0,*d,r"))]
|
| "TARGET_POWERPC64 && TARGET_MFPGPR && TARGET_HARD_FLOAT && TARGET_FPRS
|
| && (gpc_reg_operand (operands[0], DImode)
|
| || gpc_reg_operand (operands[1], DImode))"
|
| @@ -9074,8 +9671,8 @@
|
| (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4")])
|
|
|
| (define_insn "*movdi_internal64"
|
| - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,*f,*f,m,r,*h,*h")
|
| - (match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,f,m,f,*h,r,0"))]
|
| + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,*d,*d,m,r,*h,*h")
|
| + (match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,d,m,d,*h,r,0"))]
|
| "TARGET_POWERPC64 && (!TARGET_MFPGPR || !TARGET_HARD_FLOAT || !TARGET_FPRS)
|
| && (gpc_reg_operand (operands[0], DImode)
|
| || gpc_reg_operand (operands[1], DImode))"
|
| @@ -9237,15 +9834,16 @@
|
| (define_insn "*movti_ppc64"
|
| [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o<>,r")
|
| (match_operand:TI 1 "input_operand" "r,r,m"))]
|
| - "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode)
|
| - || gpc_reg_operand (operands[1], TImode))"
|
| + "(TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode)
|
| + || gpc_reg_operand (operands[1], TImode)))
|
| + && VECTOR_MEM_NONE_P (TImode)"
|
| "#"
|
| - [(set_attr "type" "*,load,store")])
|
| + [(set_attr "type" "*,store,load")])
|
|
|
| (define_split
|
| [(set (match_operand:TI 0 "gpc_reg_operand" "")
|
| (match_operand:TI 1 "const_double_operand" ""))]
|
| - "TARGET_POWERPC64"
|
| + "TARGET_POWERPC64 && VECTOR_MEM_NONE_P (TImode)"
|
| [(set (match_dup 2) (match_dup 4))
|
| (set (match_dup 3) (match_dup 5))]
|
| "
|
| @@ -9271,7 +9869,7 @@
|
| (define_split
|
| [(set (match_operand:TI 0 "nonimmediate_operand" "")
|
| (match_operand:TI 1 "input_operand" ""))]
|
| - "reload_completed
|
| + "reload_completed && VECTOR_MEM_NONE_P (TImode)
|
| && gpr_or_gpr_p (operands[0], operands[1])"
|
| [(pc)]
|
| { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
|
| @@ -10269,7 +10867,7 @@
|
| [(set_attr "type" "store_ux,store_u")])
|
|
|
| (define_insn "*movdf_update1"
|
| - [(set (match_operand:DF 3 "gpc_reg_operand" "=f,f")
|
| + [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
|
| (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
| (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
|
| (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
| @@ -10285,7 +10883,7 @@
|
| (define_insn "*movdf_update2"
|
| [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
| (match_operand:SI 2 "reg_or_short_operand" "r,I")))
|
| - (match_operand:DF 3 "gpc_reg_operand" "f,f"))
|
| + (match_operand:DF 3 "gpc_reg_operand" "d,d"))
|
| (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
| (plus:SI (match_dup 1) (match_dup 2)))]
|
| "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
|
| @@ -10374,7 +10972,7 @@
|
| (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
|
| (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
|
|
|
| -(define_insn "tls_gd_aix<TLSmode:tls_abi_suffix>"
|
| +(define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
|
| [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
|
| (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
|
| (match_operand 4 "" "g")))
|
| @@ -10384,10 +10982,21 @@
|
| (clobber (reg:SI LR_REGNO))]
|
| "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX"
|
| "addi %0,%1,%2@got@tlsgd\;bl %z3\;%."
|
| + "&& TARGET_TLS_MARKERS"
|
| + [(set (match_dup 0)
|
| + (unspec:TLSmode [(match_dup 1)
|
| + (match_dup 2)]
|
| + UNSPEC_TLSGD))
|
| + (parallel [(set (match_dup 0)
|
| + (call (mem:TLSmode (match_dup 3))
|
| + (match_dup 4)))
|
| + (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
|
| + (clobber (reg:SI LR_REGNO))])]
|
| + ""
|
| [(set_attr "type" "two")
|
| (set_attr "length" "12")])
|
|
|
| -(define_insn "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
|
| +(define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
|
| [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
|
| (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
|
| (match_operand 4 "" "g")))
|
| @@ -10407,10 +11016,62 @@
|
| else
|
| return "addi %0,%1,%2@got@tlsgd\;bl %z3";
|
| }
|
| + "&& TARGET_TLS_MARKERS"
|
| + [(set (match_dup 0)
|
| + (unspec:TLSmode [(match_dup 1)
|
| + (match_dup 2)]
|
| + UNSPEC_TLSGD))
|
| + (parallel [(set (match_dup 0)
|
| + (call (mem:TLSmode (match_dup 3))
|
| + (match_dup 4)))
|
| + (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
|
| + (clobber (reg:SI LR_REGNO))])]
|
| + ""
|
| [(set_attr "type" "two")
|
| (set_attr "length" "8")])
|
|
|
| -(define_insn "tls_ld_aix<TLSmode:tls_abi_suffix>"
|
| +(define_insn "*tls_gd<TLSmode:tls_abi_suffix>"
|
| + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
|
| + (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
|
| + (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
|
| + UNSPEC_TLSGD))]
|
| + "HAVE_AS_TLS && TARGET_TLS_MARKERS"
|
| + "addi %0,%1,%2@got@tlsgd"
|
| + [(set_attr "length" "4")])
|
| +
|
| +(define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
|
| + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
|
| + (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
|
| + (match_operand 2 "" "g")))
|
| + (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
|
| + UNSPEC_TLSGD)
|
| + (clobber (reg:SI LR_REGNO))]
|
| + "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX && TARGET_TLS_MARKERS"
|
| + "bl %z1(%3@tlsgd)\;%."
|
| + [(set_attr "type" "branch")
|
| + (set_attr "length" "8")])
|
| +
|
| +(define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
|
| + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
|
| + (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
|
| + (match_operand 2 "" "g")))
|
| + (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
|
| + UNSPEC_TLSGD)
|
| + (clobber (reg:SI LR_REGNO))]
|
| + "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
|
| +{
|
| + if (flag_pic)
|
| + {
|
| + if (TARGET_SECURE_PLT && flag_pic == 2)
|
| + return "bl %z1+32768(%3@tlsgd)@plt";
|
| + return "bl %z1(%3@tlsgd)@plt";
|
| + }
|
| + return "bl %z1(%3@tlsgd)";
|
| +}
|
| + [(set_attr "type" "branch")
|
| + (set_attr "length" "4")])
|
| +
|
| +(define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
|
| [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
|
| (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
|
| (match_operand 3 "" "g")))
|
| @@ -10419,9 +11080,19 @@
|
| (clobber (reg:SI LR_REGNO))]
|
| "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX"
|
| "addi %0,%1,%&@got@tlsld\;bl %z2\;%."
|
| + "&& TARGET_TLS_MARKERS"
|
| + [(set (match_dup 0)
|
| + (unspec:TLSmode [(match_dup 1)]
|
| + UNSPEC_TLSLD))
|
| + (parallel [(set (match_dup 0)
|
| + (call (mem:TLSmode (match_dup 2))
|
| + (match_dup 3)))
|
| + (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
|
| + (clobber (reg:SI LR_REGNO))])]
|
| + ""
|
| [(set_attr "length" "12")])
|
|
|
| -(define_insn "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
|
| +(define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
|
| [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
|
| (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
|
| (match_operand 3 "" "g")))
|
| @@ -10440,8 +11111,56 @@
|
| else
|
| return "addi %0,%1,%&@got@tlsld\;bl %z2";
|
| }
|
| + "&& TARGET_TLS_MARKERS"
|
| + [(set (match_dup 0)
|
| + (unspec:TLSmode [(match_dup 1)]
|
| + UNSPEC_TLSLD))
|
| + (parallel [(set (match_dup 0)
|
| + (call (mem:TLSmode (match_dup 2))
|
| + (match_dup 3)))
|
| + (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
|
| + (clobber (reg:SI LR_REGNO))])]
|
| + ""
|
| [(set_attr "length" "8")])
|
|
|
| +(define_insn "*tls_ld<TLSmode:tls_abi_suffix>"
|
| + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
|
| + (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
|
| + UNSPEC_TLSLD))]
|
| + "HAVE_AS_TLS && TARGET_TLS_MARKERS"
|
| + "addi %0,%1,%&@got@tlsld"
|
| + [(set_attr "length" "4")])
|
| +
|
| +(define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
|
| + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
|
| + (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
|
| + (match_operand 2 "" "g")))
|
| + (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
|
| + (clobber (reg:SI LR_REGNO))]
|
| + "HAVE_AS_TLS && DEFAULT_ABI == ABI_AIX && TARGET_TLS_MARKERS"
|
| + "bl %z1(%&@tlsld)\;%."
|
| + [(set_attr "type" "branch")
|
| + (set_attr "length" "8")])
|
| +
|
| +(define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
|
| + [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
|
| + (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
|
| + (match_operand 2 "" "g")))
|
| + (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
|
| + (clobber (reg:SI LR_REGNO))]
|
| + "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
|
| +{
|
| + if (flag_pic)
|
| + {
|
| + if (TARGET_SECURE_PLT && flag_pic == 2)
|
| + return "bl %z1+32768(%&@tlsld)@plt";
|
| + return "bl %z1(%&@tlsld)@plt";
|
| + }
|
| + return "bl %z1(%&@tlsld)";
|
| +}
|
| + [(set_attr "type" "branch")
|
| + (set_attr "length" "4")])
|
| +
|
| (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
|
| [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
|
| (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
|
| @@ -10718,10 +11437,12 @@
|
|
|
| (define_insn "load_toc_v4_PIC_1b"
|
| [(set (reg:SI LR_REGNO)
|
| - (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")]
|
| - UNSPEC_TOCPTR))]
|
| + (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
|
| + (label_ref (match_operand 1 "" ""))]
|
| + UNSPEC_TOCPTR))
|
| + (match_dup 1)]
|
| "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"
|
| - "bcl 20,31,$+8\\n\\t.long %0-$"
|
| + "bcl 20,31,$+8\;.long %0-$"
|
| [(set_attr "type" "branch")
|
| (set_attr "length" "8")])
|
|
|
| @@ -11747,267 +12468,103 @@
|
| [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
|
| ""
|
| "")
|
| +
|
| +(define_insn "probe_stack"
|
| + [(set (match_operand 0 "memory_operand" "=m")
|
| + (unspec [(const_int 0)] UNSPEC_PROBE_STACK))]
|
| + ""
|
| + "{st%U0%X0|stw%U0%X0} 0,%0"
|
| + [(set_attr "type" "store")
|
| + (set_attr "length" "4")])
|
|
|
| ;; Compare insns are next. Note that the RS/6000 has two types of compares,
|
| ;; signed & unsigned, and one type of branch.
|
| ;;
|
| ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
|
| -;; insns, and branches. We store the operands of compares until we see
|
| -;; how it is used.
|
| -(define_expand "cmp<mode>"
|
| - [(set (cc0)
|
| - (compare (match_operand:GPR 0 "gpc_reg_operand" "")
|
| - (match_operand:GPR 1 "reg_or_short_operand" "")))]
|
| +;; insns, and branches.
|
| +
|
| +(define_expand "cbranch<mode>4"
|
| + [(use (match_operator 0 "rs6000_cbranch_operator"
|
| + [(match_operand:GPR 1 "gpc_reg_operand" "")
|
| + (match_operand:GPR 2 "reg_or_short_operand" "")]))
|
| + (use (match_operand 3 ""))]
|
| ""
|
| "
|
| {
|
| - /* Take care of the possibility that operands[1] might be negative but
|
| + /* Take care of the possibility that operands[2] might be negative but
|
| this might be a logical operation. That insn doesn't exist. */
|
| - if (GET_CODE (operands[1]) == CONST_INT
|
| - && INTVAL (operands[1]) < 0)
|
| - operands[1] = force_reg (<MODE>mode, operands[1]);
|
| + if (GET_CODE (operands[2]) == CONST_INT
|
| + && INTVAL (operands[2]) < 0)
|
| + {
|
| + operands[2] = force_reg (<MODE>mode, operands[2]);
|
| + operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
|
| + GET_MODE (operands[0]),
|
| + operands[1], operands[2]);
|
| + }
|
|
|
| - rs6000_compare_op0 = operands[0];
|
| - rs6000_compare_op1 = operands[1];
|
| - rs6000_compare_fp_p = 0;
|
| + rs6000_emit_cbranch (<MODE>mode, operands);
|
| DONE;
|
| }")
|
|
|
| -(define_expand "cmp<mode>"
|
| - [(set (cc0) (compare (match_operand:FP 0 "gpc_reg_operand" "")
|
| - (match_operand:FP 1 "gpc_reg_operand" "")))]
|
| +(define_expand "cbranch<mode>4"
|
| + [(use (match_operator 0 "rs6000_cbranch_operator"
|
| + [(match_operand:FP 1 "gpc_reg_operand" "")
|
| + (match_operand:FP 2 "gpc_reg_operand" "")]))
|
| + (use (match_operand 3 ""))]
|
| ""
|
| "
|
| {
|
| - rs6000_compare_op0 = operands[0];
|
| - rs6000_compare_op1 = operands[1];
|
| - rs6000_compare_fp_p = 1;
|
| + rs6000_emit_cbranch (<MODE>mode, operands);
|
| DONE;
|
| }")
|
|
|
| -(define_expand "beq"
|
| - [(use (match_operand 0 "" ""))]
|
| - ""
|
| - "{ rs6000_emit_cbranch (EQ, operands[0]); DONE; }")
|
| -
|
| -(define_expand "bne"
|
| - [(use (match_operand 0 "" ""))]
|
| - ""
|
| - "{ rs6000_emit_cbranch (NE, operands[0]); DONE; }")
|
| -
|
| -(define_expand "bge"
|
| - [(use (match_operand 0 "" ""))]
|
| - ""
|
| - "{ rs6000_emit_cbranch (GE, operands[0]); DONE; }")
|
| -
|
| -(define_expand "bgt"
|
| - [(use (match_operand 0 "" ""))]
|
| - ""
|
| - "{ rs6000_emit_cbranch (GT, operands[0]); DONE; }")
|
| -
|
| -(define_expand "ble"
|
| - [(use (match_operand 0 "" ""))]
|
| - ""
|
| - "{ rs6000_emit_cbranch (LE, operands[0]); DONE; }")
|
| -
|
| -(define_expand "blt"
|
| - [(use (match_operand 0 "" ""))]
|
| - ""
|
| - "{ rs6000_emit_cbranch (LT, operands[0]); DONE; }")
|
| -
|
| -(define_expand "bgeu"
|
| - [(use (match_operand 0 "" ""))]
|
| - ""
|
| - "{ rs6000_emit_cbranch (GEU, operands[0]); DONE; }")
|
| -
|
| -(define_expand "bgtu"
|
| - [(use (match_operand 0 "" ""))]
|
| - ""
|
| - "{ rs6000_emit_cbranch (GTU, operands[0]); DONE; }")
|
| -
|
| -(define_expand "bleu"
|
| - [(use (match_operand 0 "" ""))]
|
| - ""
|
| - "{ rs6000_emit_cbranch (LEU, operands[0]); DONE; }")
|
| -
|
| -(define_expand "bltu"
|
| - [(use (match_operand 0 "" ""))]
|
| - ""
|
| - "{ rs6000_emit_cbranch (LTU, operands[0]); DONE; }")
|
| -
|
| -(define_expand "bunordered"
|
| - [(use (match_operand 0 "" ""))]
|
| - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
|
| - "{ rs6000_emit_cbranch (UNORDERED, operands[0]); DONE; }")
|
| -
|
| -(define_expand "bordered"
|
| - [(use (match_operand 0 "" ""))]
|
| - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
|
| - "{ rs6000_emit_cbranch (ORDERED, operands[0]); DONE; }")
|
| -
|
| -(define_expand "buneq"
|
| - [(use (match_operand 0 "" ""))]
|
| - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
|
| - "{ rs6000_emit_cbranch (UNEQ, operands[0]); DONE; }")
|
| -
|
| -(define_expand "bunge"
|
| - [(use (match_operand 0 "" ""))]
|
| - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
|
| - "{ rs6000_emit_cbranch (UNGE, operands[0]); DONE; }")
|
| -
|
| -(define_expand "bungt"
|
| - [(use (match_operand 0 "" ""))]
|
| - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
|
| - "{ rs6000_emit_cbranch (UNGT, operands[0]); DONE; }")
|
| -
|
| -(define_expand "bunle"
|
| - [(use (match_operand 0 "" ""))]
|
| - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
|
| - "{ rs6000_emit_cbranch (UNLE, operands[0]); DONE; }")
|
| -
|
| -(define_expand "bunlt"
|
| - [(use (match_operand 0 "" ""))]
|
| - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
|
| - "{ rs6000_emit_cbranch (UNLT, operands[0]); DONE; }")
|
| -
|
| -(define_expand "bltgt"
|
| - [(use (match_operand 0 "" ""))]
|
| - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
|
| - "{ rs6000_emit_cbranch (LTGT, operands[0]); DONE; }")
|
| -
|
| -;; For SNE, we would prefer that the xor/abs sequence be used for integers.
|
| -;; For SEQ, likewise, except that comparisons with zero should be done
|
| -;; with an scc insns. However, due to the order that combine see the
|
| -;; resulting insns, we must, in fact, allow SEQ for integers. Fail in
|
| -;; the cases we don't want to handle.
|
| -(define_expand "seq"
|
| - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
| - ""
|
| - "{ rs6000_emit_sCOND (EQ, operands[0]); DONE; }")
|
| -
|
| -(define_expand "sne"
|
| - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
| +(define_expand "cstore<mode>4"
|
| + [(use (match_operator 1 "rs6000_cbranch_operator"
|
| + [(match_operand:GPR 2 "gpc_reg_operand" "")
|
| + (match_operand:GPR 3 "reg_or_short_operand" "")]))
|
| + (clobber (match_operand:SI 0 "register_operand"))]
|
| ""
|
| "
|
| {
|
| - if (! rs6000_compare_fp_p)
|
| - FAIL;
|
| -
|
| - rs6000_emit_sCOND (NE, operands[0]);
|
| - DONE;
|
| -}")
|
| -
|
| -;; A >= 0 is best done the portable way for A an integer.
|
| -(define_expand "sge"
|
| - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
| - ""
|
| - "
|
| -{
|
| - if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
|
| - FAIL;
|
| -
|
| - rs6000_emit_sCOND (GE, operands[0]);
|
| - DONE;
|
| -}")
|
| + /* Take care of the possibility that operands[3] might be negative but
|
| + this might be a logical operation. That insn doesn't exist. */
|
| + if (GET_CODE (operands[3]) == CONST_INT
|
| + && INTVAL (operands[3]) < 0)
|
| + {
|
| + operands[3] = force_reg (<MODE>mode, operands[3]);
|
| + operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
|
| + GET_MODE (operands[1]),
|
| + operands[2], operands[3]);
|
| + }
|
|
|
| -;; A > 0 is best done using the portable sequence, so fail in that case.
|
| -(define_expand "sgt"
|
| - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
| - ""
|
| - "
|
| -{
|
| - if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
|
| + /* For SNE, we would prefer that the xor/abs sequence be used for integers.
|
| + For SEQ, likewise, except that comparisons with zero should be done
|
| + with an scc insns. However, due to the order that combine see the
|
| + resulting insns, we must, in fact, allow SEQ for integers. Fail in
|
| + the cases we don't want to handle or are best handled by portable
|
| + code. */
|
| + if (GET_CODE (operands[1]) == NE)
|
| FAIL;
|
| -
|
| - rs6000_emit_sCOND (GT, operands[0]);
|
| - DONE;
|
| -}")
|
| -
|
| -;; A <= 0 is best done the portable way for A an integer.
|
| -(define_expand "sle"
|
| - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
| - ""
|
| - "
|
| -{
|
| - if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
|
| + if ((GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE
|
| + || GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE)
|
| + && operands[3] == const0_rtx)
|
| FAIL;
|
| -
|
| - rs6000_emit_sCOND (LE, operands[0]);
|
| + rs6000_emit_sCOND (<MODE>mode, operands);
|
| DONE;
|
| }")
|
|
|
| -;; A < 0 is best done in the portable way for A an integer.
|
| -(define_expand "slt"
|
| - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
| +(define_expand "cstore<mode>4"
|
| + [(use (match_operator 1 "rs6000_cbranch_operator"
|
| + [(match_operand:FP 2 "gpc_reg_operand" "")
|
| + (match_operand:FP 3 "gpc_reg_operand" "")]))
|
| + (clobber (match_operand:SI 0 "register_operand"))]
|
| ""
|
| "
|
| {
|
| - if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
|
| - FAIL;
|
| -
|
| - rs6000_emit_sCOND (LT, operands[0]);
|
| + rs6000_emit_sCOND (<MODE>mode, operands);
|
| DONE;
|
| }")
|
|
|
| -(define_expand "sgeu"
|
| - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
| - ""
|
| - "{ rs6000_emit_sCOND (GEU, operands[0]); DONE; }")
|
| -
|
| -(define_expand "sgtu"
|
| - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
| - ""
|
| - "{ rs6000_emit_sCOND (GTU, operands[0]); DONE; }")
|
| -
|
| -(define_expand "sleu"
|
| - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
| - ""
|
| - "{ rs6000_emit_sCOND (LEU, operands[0]); DONE; }")
|
| -
|
| -(define_expand "sltu"
|
| - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
| - ""
|
| - "{ rs6000_emit_sCOND (LTU, operands[0]); DONE; }")
|
| -
|
| -(define_expand "sunordered"
|
| - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
| - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
|
| - "{ rs6000_emit_sCOND (UNORDERED, operands[0]); DONE; }")
|
| -
|
| -(define_expand "sordered"
|
| - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
| - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
|
| - "{ rs6000_emit_sCOND (ORDERED, operands[0]); DONE; }")
|
| -
|
| -(define_expand "suneq"
|
| - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
| - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
|
| - "{ rs6000_emit_sCOND (UNEQ, operands[0]); DONE; }")
|
| -
|
| -(define_expand "sunge"
|
| - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
| - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
|
| - "{ rs6000_emit_sCOND (UNGE, operands[0]); DONE; }")
|
| -
|
| -(define_expand "sungt"
|
| - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
| - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
|
| - "{ rs6000_emit_sCOND (UNGT, operands[0]); DONE; }")
|
| -
|
| -(define_expand "sunle"
|
| - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
| - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
|
| - "{ rs6000_emit_sCOND (UNLE, operands[0]); DONE; }")
|
| -
|
| -(define_expand "sunlt"
|
| - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
| - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
|
| - "{ rs6000_emit_sCOND (UNLT, operands[0]); DONE; }")
|
| -
|
| -(define_expand "sltgt"
|
| - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
| - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)"
|
| - "{ rs6000_emit_sCOND (LTGT, operands[0]); DONE; }")
|
|
|
| (define_expand "stack_protect_set"
|
| [(match_operand 0 "memory_operand" "")
|
| @@ -12050,16 +12607,16 @@
|
| (match_operand 2 "" "")]
|
| ""
|
| {
|
| + rtx test, op0, op1;
|
| #ifdef TARGET_THREAD_SSP_OFFSET
|
| rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
|
| rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
|
| operands[1] = gen_rtx_MEM (Pmode, addr);
|
| #endif
|
| - rs6000_compare_op0 = operands[0];
|
| - rs6000_compare_op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]),
|
| - UNSPEC_SP_TEST);
|
| - rs6000_compare_fp_p = 0;
|
| - emit_jump_insn (gen_beq (operands[2]));
|
| + op0 = operands[0];
|
| + op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST);
|
| + test = gen_rtx_EQ (VOIDmode, op0, op1);
|
| + emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2]));
|
| DONE;
|
| })
|
|
|
| @@ -12213,17 +12770,18 @@
|
|
|
| (define_insn "*cmpdf_internal1"
|
| [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
|
| - (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "f")
|
| - (match_operand:DF 2 "gpc_reg_operand" "f")))]
|
| - "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT"
|
| + (compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "d")
|
| + (match_operand:DF 2 "gpc_reg_operand" "d")))]
|
| + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
|
| + && !VECTOR_UNIT_VSX_P (DFmode)"
|
| "fcmpu %0,%1,%2"
|
| [(set_attr "type" "fpcompare")])
|
|
|
| ;; Only need to compare second words if first words equal
|
| (define_insn "*cmptf_internal1"
|
| [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
|
| - (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "f")
|
| - (match_operand:TF 2 "gpc_reg_operand" "f")))]
|
| + (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "d")
|
| + (match_operand:TF 2 "gpc_reg_operand" "d")))]
|
| "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT
|
| && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
|
| "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
|
| @@ -12232,16 +12790,16 @@
|
|
|
| (define_insn_and_split "*cmptf_internal2"
|
| [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
|
| - (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "f")
|
| - (match_operand:TF 2 "gpc_reg_operand" "f")))
|
| - (clobber (match_scratch:DF 3 "=f"))
|
| - (clobber (match_scratch:DF 4 "=f"))
|
| - (clobber (match_scratch:DF 5 "=f"))
|
| - (clobber (match_scratch:DF 6 "=f"))
|
| - (clobber (match_scratch:DF 7 "=f"))
|
| - (clobber (match_scratch:DF 8 "=f"))
|
| - (clobber (match_scratch:DF 9 "=f"))
|
| - (clobber (match_scratch:DF 10 "=f"))]
|
| + (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "d")
|
| + (match_operand:TF 2 "gpc_reg_operand" "d")))
|
| + (clobber (match_scratch:DF 3 "=d"))
|
| + (clobber (match_scratch:DF 4 "=d"))
|
| + (clobber (match_scratch:DF 5 "=d"))
|
| + (clobber (match_scratch:DF 6 "=d"))
|
| + (clobber (match_scratch:DF 7 "=d"))
|
| + (clobber (match_scratch:DF 8 "=d"))
|
| + (clobber (match_scratch:DF 9 "=d"))
|
| + (clobber (match_scratch:DF 10 "=d"))]
|
| "!TARGET_IEEEQUAD && TARGET_XL_COMPAT
|
| && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
|
| "#"
|
| @@ -12259,7 +12817,7 @@
|
| (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
|
| (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
|
| (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
|
| - (set (match_dup 0) (compare:CCFP (match_dup 7) (match_dup 4)))
|
| + (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
|
| (match_dup 12)]
|
| {
|
| REAL_VALUE_TYPE rv;
|
| @@ -14630,17 +15188,16 @@
|
| "{t 31,0,0|trap}"
|
| [(set_attr "type" "trap")])
|
|
|
| -(define_expand "conditional_trap"
|
| - [(trap_if (match_operator 0 "trap_comparison_operator"
|
| - [(match_dup 2) (match_dup 3)])
|
| - (match_operand 1 "const_int_operand" ""))]
|
| +(define_expand "ctrap<mode>4"
|
| + [(trap_if (match_operator 0 "ordered_comparison_operator"
|
| + [(match_operand:GPR 1 "register_operand")
|
| + (match_operand:GPR 2 "reg_or_short_operand")])
|
| + (match_operand 3 "zero_constant" ""))]
|
| ""
|
| - "if (rs6000_compare_fp_p || operands[1] != const0_rtx) FAIL;
|
| - operands[2] = rs6000_compare_op0;
|
| - operands[3] = rs6000_compare_op1;")
|
| + "")
|
|
|
| (define_insn ""
|
| - [(trap_if (match_operator 0 "trap_comparison_operator"
|
| + [(trap_if (match_operator 0 "ordered_comparison_operator"
|
| [(match_operand:GPR 1 "register_operand" "r")
|
| (match_operand:GPR 2 "reg_or_short_operand" "rI")])
|
| (const_int 0))]
|
| @@ -14707,7 +15264,7 @@
|
| (set (match_operand:P 3 "memory_operand" "=m")
|
| (match_operand:P 4 "gpc_reg_operand" "r"))])]
|
| ""
|
| - "bl %z1"
|
| + "bl %1"
|
| [(set_attr "type" "branch")
|
| (set_attr "length" "4")])
|
|
|
| @@ -14717,9 +15274,9 @@
|
| (use (match_operand:P 1 "symbol_ref_operand" "s"))
|
| (use (match_operand:P 2 "gpc_reg_operand" "r"))
|
| (set (match_operand:DF 3 "memory_operand" "=m")
|
| - (match_operand:DF 4 "gpc_reg_operand" "f"))])]
|
| + (match_operand:DF 4 "gpc_reg_operand" "d"))])]
|
| ""
|
| - "bl %z1"
|
| + "bl %1"
|
| [(set_attr "type" "branch")
|
| (set_attr "length" "4")])
|
|
|
| @@ -14732,6 +15289,15 @@
|
| ""
|
| [(set_attr "length" "0")])
|
|
|
| +; Like stack_tie, but depend on both fp and sp based memory.
|
| +(define_insn "frame_tie"
|
| + [(set (match_operand:BLK 0 "memory_operand" "+m")
|
| + (unspec:BLK [(match_dup 0)
|
| + (match_operand:BLK 1 "memory_operand" "m")] UNSPEC_TIE))]
|
| + ""
|
| + ""
|
| + [(set_attr "length" "0")])
|
| +
|
|
|
| (define_expand "epilogue"
|
| [(use (const_int 0))]
|
| @@ -14814,7 +15380,7 @@
|
| (set (match_operand:P 4 "gpc_reg_operand" "=r")
|
| (match_operand:P 5 "memory_operand" "m"))])]
|
| ""
|
| - "bl %z2"
|
| + "bl %2"
|
| [(set_attr "type" "branch")
|
| (set_attr "length" "4")])
|
|
|
| @@ -14827,7 +15393,7 @@
|
| (set (match_operand:P 4 "gpc_reg_operand" "=r")
|
| (match_operand:P 5 "memory_operand" "m"))])]
|
| ""
|
| - "b %z2"
|
| + "b %2"
|
| [(set_attr "type" "branch")
|
| (set_attr "length" "4")])
|
|
|
| @@ -14837,10 +15403,23 @@
|
| (clobber (match_operand:P 1 "register_operand" "=l"))
|
| (use (match_operand:P 2 "symbol_ref_operand" "s"))
|
| (use (match_operand:P 3 "gpc_reg_operand" "r"))
|
| - (set (match_operand:DF 4 "gpc_reg_operand" "=f")
|
| + (set (match_operand:DF 4 "gpc_reg_operand" "=d")
|
| (match_operand:DF 5 "memory_operand" "m"))])]
|
| ""
|
| - "b %z2"
|
| + "b %2"
|
| + [(set_attr "type" "branch")
|
| + (set_attr "length" "4")])
|
| +
|
| +(define_insn "*return_and_restore_fpregs_aix_<mode>"
|
| + [(match_parallel 0 "any_parallel_operand"
|
| + [(return)
|
| + (use (match_operand:P 1 "register_operand" "l"))
|
| + (use (match_operand:P 2 "symbol_ref_operand" "s"))
|
| + (use (match_operand:P 3 "gpc_reg_operand" "r"))
|
| + (set (match_operand:DF 4 "gpc_reg_operand" "=d")
|
| + (match_operand:DF 5 "memory_operand" "m"))])]
|
| + ""
|
| + "b %2"
|
| [(set_attr "type" "branch")
|
| (set_attr "length" "4")])
|
|
|
| @@ -14889,8 +15468,19 @@
|
| }"
|
| [(set_attr "type" "load")])
|
|
|
| +(define_insn "bpermd_<mode>"
|
| + [(set (match_operand:P 0 "gpc_reg_operand" "=r")
|
| + (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
|
| + (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
|
| + "TARGET_POPCNTD"
|
| + "bpermd %0,%1,%2"
|
| + [(set_attr "type" "integer")])
|
| +
|
| +
|
|
|
| (include "sync.md")
|
| +(include "vector.md")
|
| +(include "vsx.md")
|
| (include "altivec.md")
|
| (include "spe.md")
|
| (include "dfp.md")
|
|
|