Mercurial > hg > CbC > CbC_gcc
diff gcc/config/rs6000/rs6000.md @ 57:326d9e06c2e3
modify c-parser.c
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 15 Feb 2010 00:54:17 +0900 |
parents | 27e6f95b2c21 77e2b8dfacca |
children | 1b10fe6932e1 |
line wrap: on
line diff
--- a/gcc/config/rs6000/rs6000.md Sun Feb 07 18:30:54 2010 +0900 +++ b/gcc/config/rs6000/rs6000.md Mon Feb 15 00:54:17 2010 +0900 @@ -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") @@ -218,6 +224,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 +539,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 +565,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 +706,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 +732,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 +875,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 +901,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 +978,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 +1442,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 +1689,7 @@ "@ nor. %2,%1,%1 #" - [(set_attr "type" "compare") + [(set_attr "type" "fast_compare,compare") (set_attr "length" "4,8")]) (define_split @@ -1696,7 +1715,7 @@ "@ nor. %0,%1,%1 #" - [(set_attr "type" "compare") + [(set_attr "type" "fast_compare,compare") (set_attr "length" "4,8")]) (define_split @@ -2060,23 +2079,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 +2259,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 +2289,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 +2403,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 +3283,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 +3326,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 +3347,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 +3407,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 +3430,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 +3562,7 @@ "@ %q4. %3,%1,%2 #" - [(set_attr "type" "compare") + [(set_attr "type" "fast_compare,compare") (set_attr "length" "4,8")]) (define_split @@ -3156,7 +3591,7 @@ "@ %q4. %0,%1,%2 #" - [(set_attr "type" "compare") + [(set_attr "type" "fast_compare,compare") (set_attr "length" "4,8")]) (define_split @@ -3281,7 +3716,7 @@ "@ %q4. %3,%1,%2 #" - [(set_attr "type" "compare") + [(set_attr "type" "fast_compare,compare") (set_attr "length" "4,8")]) (define_split @@ -3310,7 +3745,7 @@ "@ %q4. %0,%1,%2 #" - [(set_attr "type" "compare") + [(set_attr "type" "fast_compare,compare") (set_attr "length" "4,8")]) (define_split @@ -3961,6 +4396,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 +4751,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 +4999,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 +5438,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 +5598,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 +5621,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 +5782,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 +5793,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 +5802,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 +5813,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 +5822,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 +5844,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 +5853,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 +5863,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 +5885,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 +5894,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 +5975,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 +6030,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 +6052,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")]) - -(define_insn "isel_unsigned" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (if_then_else:SI + [(set_attr "type" "isel") + (set_attr "length" "4")]) + +(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 +6106,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 +6121,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 +6135,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 +6158,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 +6175,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 +6192,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 +6211,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 +6231,91 @@ 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")))] + [(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" + && TARGET_DOUBLE_FLOAT + && !VECTOR_UNIT_VSX_P (DFmode)" "fsqrt %0,%1" [(set_attr "type" "dsqrt")]) @@ -5865,21 +6371,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 +6404,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 +6453,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 +6521,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 +6590,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 +6613,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 +6631,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 +6649,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 +6699,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 +6720,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 +6735,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 +6756,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 +6817,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 +7219,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 +7248,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 +8192,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 +8250,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 +8303,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 +8445,7 @@ "@ %q4. %3,%1,%2 #" - [(set_attr "type" "compare") + [(set_attr "type" "fast_compare,compare") (set_attr "length" "4,8")]) (define_split @@ -7887,7 +8474,7 @@ "@ %q4. %0,%1,%2 #" - [(set_attr "type" "compare") + [(set_attr "type" "fast_compare,compare") (set_attr "length" "4,8")]) (define_split @@ -7958,7 +8545,7 @@ "@ %q4. %3,%2,%1 #" - [(set_attr "type" "compare") + [(set_attr "type" "fast_compare,compare") (set_attr "length" "4,8")]) (define_split @@ -7987,7 +8574,7 @@ "@ %q4. %0,%2,%1 #" - [(set_attr "type" "compare") + [(set_attr "type" "fast_compare,compare") (set_attr "length" "4,8")]) (define_split @@ -8024,7 +8611,7 @@ "@ %q4. %3,%1,%2 #" - [(set_attr "type" "compare") + [(set_attr "type" "fast_compare,compare") (set_attr "length" "4,8")]) (define_split @@ -8053,7 +8640,7 @@ "@ %q4. %0,%1,%2 #" - [(set_attr "type" "compare") + [(set_attr "type" "fast_compare,compare") (set_attr "length" "4,8")]) (define_split @@ -8070,6 +8657,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 +8775,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 +8794,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 +9129,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))" @@ -8553,25 +9209,36 @@ 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))" @@ -8613,19 +9280,26 @@ ; 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 +9308,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 +9372,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 +9427,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 +9470,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 +9486,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 +9512,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 +9542,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 +9586,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 +9619,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 +9685,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))" @@ -9049,8 +9730,8 @@ { 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 +9755,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 +9918,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 +9953,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 +10951,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 +10967,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 +11056,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 +11066,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 +11100,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 +11164,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 +11195,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") @@ -11776,267 +12579,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" "")))] - "" - " -{ - /* Take care of the possibility that operands[1] might be negative but +;; 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[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]); - - rs6000_compare_op0 = operands[0]; - rs6000_compare_op1 = operands[1]; - rs6000_compare_fp_p = 0; + 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_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" "")))] - "" - " -{ - rs6000_compare_op0 = operands[0]; - rs6000_compare_op1 = operands[1]; - rs6000_compare_fp_p = 1; +(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_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" ""))] - "" - " -{ - if (! rs6000_compare_fp_p) +(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"))] + "" + " +{ + /* 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]); + } + + /* 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 (NE, operands[0]); + 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 (<MODE>mode, operands); 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; -}") - -;; 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) - 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) - FAIL; - - rs6000_emit_sCOND (LE, operands[0]); - 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" ""))] - "" - " -{ - if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx) - FAIL; - - rs6000_emit_sCOND (LT, operands[0]); +(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"))] + "" + " +{ + 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" "") @@ -12079,16 +12718,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; }) @@ -12242,17 +12881,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" @@ -12261,16 +12901,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" "#" @@ -14659,17 +15299,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" ""))] - "" - "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" +(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" ""))] + "" + "") + +(define_insn "" + [(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))] @@ -14736,7 +15375,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")]) @@ -14746,9 +15385,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"))])] - "" - "bl %z1" + (match_operand:DF 4 "gpc_reg_operand" "d"))])] + "" + "bl %1" [(set_attr "type" "branch") (set_attr "length" "4")]) @@ -14843,7 +15482,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")]) @@ -14856,7 +15495,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")]) @@ -14866,10 +15505,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")]) @@ -14918,8 +15570,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")