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") |