diff options
Diffstat (limited to 'contrib/gcc/config/rs6000/rs6000.md')
-rw-r--r-- | contrib/gcc/config/rs6000/rs6000.md | 3855 |
1 files changed, 1519 insertions, 2336 deletions
diff --git a/contrib/gcc/config/rs6000/rs6000.md b/contrib/gcc/config/rs6000/rs6000.md index ec16c19..4c95031 100644 --- a/contrib/gcc/config/rs6000/rs6000.md +++ b/contrib/gcc/config/rs6000/rs6000.md @@ -1,6 +1,6 @@ ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler ;; Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, -;; 1999, 2000, 2001 Free Software Foundation, Inc. +;; 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ;; This file is part of GNU CC. @@ -32,6 +32,8 @@ ;; 8 movsi_got ;; 9/v eh_reg_restore ;; 10 fctiwz +;; 15 load_macho_picbase +;; 16 macho_correct_pic ;; 19 movesi_from_cr ;; 20 movesi_to_cr @@ -56,7 +58,7 @@ ;; Processor type -- this attribute must exactly match the processor_type ;; enumeration in rs6000.h. -(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450" +(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,power4" (const (symbol_ref "rs6000_cpu_attr"))) ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY @@ -375,42 +377,52 @@ (and (eq_attr "type" "cr_logical") (eq_attr "cpu" "ppc7450")) 1 1) + (define_function_unit "vec_alu2" 2 0 (and (eq_attr "type" "vecsimple") (eq_attr "cpu" "ppc7450")) 1 2 [(eq_attr "type" "vecsimple")]) + (define_function_unit "vec_alu2" 2 0 (and (eq_attr "type" "vecsimple") (eq_attr "cpu" "ppc7450")) 1 1 [(eq_attr "type" "!vecsimple")]) + (define_function_unit "vec_alu2" 2 0 (and (eq_attr "type" "veccomplex") (eq_attr "cpu" "ppc7450")) 4 2 [(eq_attr "type" "veccomplex")]) + (define_function_unit "vec_alu2" 2 0 (and (eq_attr "type" "veccomplex") (eq_attr "cpu" "ppc7450")) 4 1 [(eq_attr "type" "!veccomplex")]) + (define_function_unit "vec_alu2" 2 0 (and (eq_attr "type" "veccmp") (eq_attr "cpu" "ppc7450")) 2 2 [(eq_attr "type" "veccmp")]) + (define_function_unit "vec_alu2" 2 0 (and (eq_attr "type" "veccmp") (eq_attr "cpu" "ppc7450")) 2 1 [(eq_attr "type" "!veccmp")]) + (define_function_unit "vec_alu2" 2 0 (and (eq_attr "type" "vecfloat") (eq_attr "cpu" "ppc7450")) 4 2 [(eq_attr "type" "vecfloat")]) + (define_function_unit "vec_alu2" 2 0 (and (eq_attr "type" "vecfloat") (eq_attr "cpu" "ppc7450")) 4 1 [(eq_attr "type" "!vecfloat")]) + (define_function_unit "vec_alu2" 2 0 (and (eq_attr "type" "vecperm") (eq_attr "cpu" "ppc7450")) 2 2 [(eq_attr "type" "vecperm")]) + (define_function_unit "vec_alu2" 2 0 (and (eq_attr "type" "vecperm") (eq_attr "cpu" "ppc7450")) @@ -489,7 +501,7 @@ (define_function_unit "iu" 1 0 (and (eq_attr "type" "compare,delayed_compare") - (eq_attr "cpu" "rs64a,mpccore,ppc403,ppc405,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630")) + (eq_attr "cpu" "rs64a,mpccore,ppc403,ppc405,ppc601,ppc603")) 3 1) ; some extra cycles added by TARGET_SCHED_ADJUST_COST between compare @@ -533,7 +545,7 @@ ; fp compare uses fp unit (define_function_unit "fpu" 1 0 (and (eq_attr "type" "fpcompare") - (eq_attr "cpu" "rs64a,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630")) + (eq_attr "cpu" "rs64a,ppc601,ppc603,ppc604,ppc604e,ppc620")) 5 1) (define_function_unit "fpu" 1 0 @@ -699,22 +711,12 @@ ; RIOS2 has two symmetric FPUs. (define_function_unit "fpu2" 2 0 - (and (eq_attr "type" "fp") - (eq_attr "cpu" "rios2")) - 2 1) - -(define_function_unit "fpu2" 2 0 - (and (eq_attr "type" "fp") - (eq_attr "cpu" "ppc630")) - 3 1) - -(define_function_unit "fpu2" 2 0 - (and (eq_attr "type" "dmul") + (and (eq_attr "type" "fp,dmul") (eq_attr "cpu" "rios2")) 2 1) (define_function_unit "fpu2" 2 0 - (and (eq_attr "type" "dmul") + (and (eq_attr "type" "fp,dmul") (eq_attr "cpu" "ppc630")) 3 1) @@ -748,6 +750,109 @@ (eq_attr "cpu" "ppc630")) 26 26) +;; Power4 +(define_function_unit "lsu2" 2 0 + (and (eq_attr "type" "load") + (eq_attr "cpu" "power4")) + 3 1) + +(define_function_unit "lsu2" 2 0 + (and (eq_attr "type" "fpload") + (eq_attr "cpu" "power4")) + 5 1) + +(define_function_unit "lsu2" 2 0 + (and (eq_attr "type" "store,fpstore") + (eq_attr "cpu" "power4")) + 1 1) + +(define_function_unit "iu2" 2 0 + (and (eq_attr "type" "integer") + (eq_attr "cpu" "power4")) + 2 1) + +(define_function_unit "iu2" 2 0 + (and (eq_attr "type" "lmul") + (eq_attr "cpu" "power4")) + 7 6) + +(define_function_unit "iu2" 2 0 + (and (eq_attr "type" "imul") + (eq_attr "cpu" "power4")) + 5 4) + +(define_function_unit "iu2" 2 0 + (and (eq_attr "type" "imul2,imul3") + (eq_attr "cpu" "power4")) + 4 3) + +(define_function_unit "iu2" 2 0 + (and (eq_attr "type" "idiv") + (eq_attr "cpu" "power4")) + 36 35) + +(define_function_unit "iu2" 2 0 + (and (eq_attr "type" "ldiv") + (eq_attr "cpu" "power4")) + 68 67) + +(define_function_unit "imuldiv" 1 0 + (and (eq_attr "type" "idiv") + (eq_attr "cpu" "power4")) + 36 35) + +(define_function_unit "imuldiv" 1 0 + (and (eq_attr "type" "ldiv") + (eq_attr "cpu" "power4")) + 68 67) + +(define_function_unit "iu2" 2 0 + (and (eq_attr "type" "compare") + (eq_attr "cpu" "power4")) + 3 1) + +(define_function_unit "iu2" 2 0 + (and (eq_attr "type" "delayed_compare") + (eq_attr "cpu" "power4")) + 4 1) + +(define_function_unit "bpu" 1 0 + (and (eq_attr "type" "mtjmpr") + (eq_attr "cpu" "power4")) + 3 1) + +(define_function_unit "bpu" 1 0 + (and (eq_attr "type" "jmpreg,branch") + (eq_attr "cpu" "power4")) + 2 1) + +(define_function_unit "cru" 1 0 + (and (eq_attr "type" "cr_logical") + (eq_attr "cpu" "power4")) + 4 1) + +(define_function_unit "fpu2" 2 0 + (and (eq_attr "type" "fp,dmul") + (eq_attr "cpu" "power4")) + 6 1) + +; adjust_cost increases the cost of dependent branches, +; so shave a few cycles off for fpcompare. +(define_function_unit "fpu2" 2 0 + (and (eq_attr "type" "fpcompare") + (eq_attr "cpu" "power4")) + 5 1) + +(define_function_unit "fpu2" 2 0 + (and (eq_attr "type" "sdiv,ddiv") + (eq_attr "cpu" "power4")) + 33 28) + +(define_function_unit "fpu2" 2 0 + (and (eq_attr "type" "ssqrt,dsqrt") + (eq_attr "cpu" "power4")) + 40 35) + ;; Start with fixed-point load and store insns. Here we put only the more ;; complex forms. Basic data transfer is done later. @@ -1631,7 +1736,7 @@ ? operands[0] : gen_reg_rtx (SImode)); HOST_WIDE_INT val = INTVAL (operands[2]); - HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000); + HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; HOST_WIDE_INT rest = trunc_int_for_mode (val - low, SImode); /* The ordering here is important for the prolog expander. @@ -1740,7 +1845,7 @@ " { HOST_WIDE_INT val = INTVAL (operands[2]); - HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000); + HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; HOST_WIDE_INT rest = trunc_int_for_mode (val - low, SImode); operands[3] = GEN_INT (rest); @@ -1936,9 +2041,18 @@ (minus:SI (match_dup 2) (match_dup 1)))) (set (match_operand:SI 0 "gpc_reg_operand" "") (minus:SI (match_dup 2) (match_dup 3)))] - "TARGET_POWER" + "TARGET_POWER || TARGET_ISEL" " -{ operands[3] = gen_reg_rtx (SImode); }") +{ + if (TARGET_ISEL) + { + operands[2] = force_reg (SImode, operands[2]); + rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]); + DONE; + } + + operands[3] = gen_reg_rtx (SImode); +}") (define_split [(set (match_operand:SI 0 "gpc_reg_operand" "") @@ -1961,9 +2075,17 @@ (minus:SI (match_dup 2) (match_dup 1)))) (set (match_operand:SI 0 "gpc_reg_operand" "") (plus:SI (match_dup 3) (match_dup 1)))] - "TARGET_POWER" + "TARGET_POWER || TARGET_ISEL" " -{ operands[3] = gen_reg_rtx (SImode); }") +{ + if (TARGET_ISEL) + { + operands[2] = force_reg (SImode, operands[2]); + rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); + DONE; + } + operands[3] = gen_reg_rtx (SImode); +}") (define_split [(set (match_operand:SI 0 "gpc_reg_operand" "") @@ -1988,9 +2110,14 @@ (minus:SI (match_dup 4) (match_dup 3)))) (set (match_operand:SI 0 "gpc_reg_operand" "") (minus:SI (match_dup 2) (match_dup 3)))] - "TARGET_POWER" + "TARGET_POWER || TARGET_ISEL" " { + if (TARGET_ISEL) + { + rs6000_emit_minmax (operands[0], UMIN, operands[1], operands[2]); + DONE; + } operands[3] = gen_reg_rtx (SImode); operands[4] = gen_reg_rtx (SImode); operands[5] = GEN_INT (-2147483647 - 1); @@ -2006,9 +2133,14 @@ (minus:SI (match_dup 4) (match_dup 3)))) (set (match_operand:SI 0 "gpc_reg_operand" "") (plus:SI (match_dup 3) (match_dup 1)))] - "TARGET_POWER" + "TARGET_POWER || TARGET_ISEL" " { + if (TARGET_ISEL) + { + rs6000_emit_minmax (operands[0], UMAX, operands[1], operands[2]); + DONE; + } operands[3] = gen_reg_rtx (SImode); operands[4] = gen_reg_rtx (SImode); operands[5] = GEN_INT (-2147483647 - 1); @@ -2107,37 +2239,50 @@ "" " { - if (! TARGET_POWER) + if (TARGET_ISEL) + { + emit_insn (gen_abssi2_isel (operands[0], operands[1])); + DONE; + } + else if (! TARGET_POWER) { emit_insn (gen_abssi2_nopower (operands[0], operands[1])); DONE; } }") -(define_insn "abssi2_power" +(define_insn "*abssi2_power" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))] "TARGET_POWER" "abs %0,%1") -(define_insn "abssi2_nopower" +(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")) + (clobber (match_scratch:CC 3 "=y"))] + "TARGET_ISEL" + "#" + "&& reload_completed" + [(set (match_dup 2) (neg:SI (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)))] + "") + +(define_insn_and_split "abssi2_nopower" [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r") - (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0"))) + (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0"))) (clobber (match_scratch:SI 2 "=&r,&r"))] - "! TARGET_POWER" - "* -{ - return (TARGET_POWERPC) - ? \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;subf %0,%2,%0\" - : \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;{sf|subfc} %0,%2,%0\"; -}" - [(set_attr "length" "12")]) - -(define_split - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (abs:SI (match_operand:SI 1 "gpc_reg_operand" ""))) - (clobber (match_scratch:SI 2 ""))] - "! TARGET_POWER && reload_completed" + "! TARGET_POWER && ! TARGET_ISEL" + "#" + "&& reload_completed" [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31))) (set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1))) (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))] @@ -2149,24 +2294,13 @@ "TARGET_POWER" "nabs %0,%1") -(define_insn "*nabs_no_power" +(define_insn_and_split "*nabs_nopower" [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r") - (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0")))) + (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0")))) (clobber (match_scratch:SI 2 "=&r,&r"))] "! TARGET_POWER" - "* -{ - return (TARGET_POWERPC) - ? \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;subf %0,%0,%2\" - : \"{srai|srawi} %2,%1,31\;xor %0,%2,%1\;{sf|subfc} %0,%0,%2\"; -}" - [(set_attr "length" "12")]) - -(define_split - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "")))) - (clobber (match_scratch:SI 2 ""))] - "! TARGET_POWER && reload_completed" + "#" + "&& reload_completed" [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31))) (set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1))) (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 0)))] @@ -2538,7 +2672,7 @@ rtx temp2; if (GET_CODE (operands[2]) != CONST_INT - || INTVAL (operands[2]) < 0 + || INTVAL (operands[2]) <= 0 || (i = exact_log2 (INTVAL (operands[2]))) < 0) FAIL; @@ -2804,7 +2938,7 @@ {andiu.|andis.} %0,%1,%u2") ;; Note to set cr's other than cr0 we do the and immediate and then -;; the test again -- this avoids a mcrf which on the higher end +;; the test again -- this avoids a mfcr which on the higher end ;; machines causes an execution serialization (define_insn "*andsi3_internal2" @@ -2827,6 +2961,26 @@ [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare") (set_attr "length" "4,4,4,4,8,8,8,8")]) +(define_insn "*andsi3_internal3" + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y") + (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r") + (match_operand:SI 2 "and_operand" "r,K,L,T,r,K,L,T")) + (const_int 0))) + (clobber (match_scratch:SI 3 "=r,r,r,r,r,r,r,r")) + (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))] + "TARGET_POWERPC64" + "@ + # + {andil.|andi.} %3,%1,%b2 + {andiu.|andis.} %3,%1,%u2 + {rlinm.|rlwinm.} %3,%1,0,%m2,%M2 + # + # + # + #" + [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare") + (set_attr "length" "8,4,4,4,8,8,8,8")]) + (define_split [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "") @@ -2834,7 +2988,7 @@ (const_int 0))) (clobber (match_scratch:SI 3 "")) (clobber (match_scratch:CC 4 ""))] - "! TARGET_POWERPC64 && reload_completed" + "reload_completed" [(parallel [(set (match_dup 3) (and:SI (match_dup 1) (match_dup 2))) @@ -2844,7 +2998,27 @@ (const_int 0)))] "") -(define_insn "*andsi3_internal3" +;; We don't have a 32 bit "and. rt,ra,rb" for ppc64. cr is set from the +;; whole 64 bit reg, and we don't know what is in the high 32 bits. + +(define_split + [(set (match_operand:CC 0 "cc_reg_operand" "") + (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "gpc_reg_operand" "")) + (const_int 0))) + (clobber (match_scratch:SI 3 "")) + (clobber (match_scratch:CC 4 ""))] + "TARGET_POWERPC64 && reload_completed" + [(parallel [(set (match_dup 3) + (and:SI (match_dup 1) + (match_dup 2))) + (clobber (match_dup 4))]) + (set (match_dup 0) + (compare:CC (match_dup 3) + (const_int 0)))] + "") + +(define_insn "*andsi3_internal4" [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y") (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r") (match_operand:SI 2 "and_operand" "r,K,L,T,r,K,L,T")) @@ -2866,6 +3040,28 @@ [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare") (set_attr "length" "4,4,4,4,8,8,8,8")]) +(define_insn "*andsi3_internal5" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y") + (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r") + (match_operand:SI 2 "and_operand" "r,K,L,T,r,K,L,T")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r") + (and:SI (match_dup 1) + (match_dup 2))) + (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))] + "TARGET_POWERPC64" + "@ + # + {andil.|andi.} %0,%1,%b2 + {andiu.|andis.} %0,%1,%u2 + {rlinm.|rlwinm.} %0,%1,0,%m2,%M2 + # + # + # + #" + [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare") + (set_attr "length" "8,4,4,4,8,8,8,8")]) + (define_split [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "") @@ -2875,7 +3071,7 @@ (and:SI (match_dup 1) (match_dup 2))) (clobber (match_scratch:CC 4 ""))] - "! TARGET_POWERPC64 && reload_completed" + "reload_completed" [(parallel [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2))) @@ -2885,6 +3081,104 @@ (const_int 0)))] "") +(define_split + [(set (match_operand:CC 3 "cc_reg_operand" "") + (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "") + (match_operand:SI 2 "gpc_reg_operand" "")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "") + (and:SI (match_dup 1) + (match_dup 2))) + (clobber (match_scratch:CC 4 ""))] + "TARGET_POWERPC64 && reload_completed" + [(parallel [(set (match_dup 0) + (and:SI (match_dup 1) + (match_dup 2))) + (clobber (match_dup 4))]) + (set (match_dup 3) + (compare:CC (match_dup 0) + (const_int 0)))] + "") + +;; Handle the PowerPC64 rlwinm corner case + +(define_insn_and_split "*andsi3_internal6" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (and:SI (match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:SI 2 "mask_operand_wrap" "i")))] + "TARGET_POWERPC64" + "#" + "TARGET_POWERPC64" + [(set (match_dup 0) + (and:SI (rotate:SI (match_dup 1) (match_dup 3)) + (match_dup 4))) + (set (match_dup 0) + (rotate:SI (match_dup 0) (match_dup 5)))] + " +{ + int mb = extract_MB (operands[2]); + int me = extract_ME (operands[2]); + operands[3] = GEN_INT (me + 1); + operands[5] = GEN_INT (32 - (me + 1)); + operands[4] = GEN_INT (~((HOST_WIDE_INT) -1 << (33 + me - mb))); +}" + [(set_attr "length" "8")]) + +(define_insn_and_split "*andsi3_internal7" + [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") + (compare:CC (and:SI (match_operand:SI 0 "gpc_reg_operand" "r,r") + (match_operand:SI 1 "mask_operand_wrap" "i,i")) + (const_int 0))) + (clobber (match_scratch:SI 3 "=r,r"))] + "TARGET_POWERPC64" + "#" + "TARGET_POWERPC64" + [(parallel [(set (match_dup 2) + (compare:CC (and:SI (rotate:SI (match_dup 0) (match_dup 4)) + (match_dup 5)) + (const_int 0))) + (clobber (match_dup 3))])] + " +{ + int mb = extract_MB (operands[1]); + int me = extract_ME (operands[1]); + operands[4] = GEN_INT (me + 1); + operands[5] = GEN_INT (~((HOST_WIDE_INT) -1 << (33 + me - mb))); +}" + [(set_attr "type" "delayed_compare,compare") + (set_attr "length" "4,8")]) + +(define_insn_and_split "*andsi3_internal8" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") + (compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "mask_operand_wrap" "i,i")) + (const_int 0))) + (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + (and:SI (match_dup 1) + (match_dup 2)))] + "TARGET_POWERPC64" + "#" + "TARGET_POWERPC64" + [(parallel [(set (match_dup 3) + (compare:CC (and:SI (rotate:SI (match_dup 1) (match_dup 4)) + (match_dup 5)) + (const_int 0))) + (set (match_dup 0) + (and:SI (rotate:SI (match_dup 1) (match_dup 4)) + (match_dup 5)))]) + (set (match_dup 0) + (rotate:SI (match_dup 0) (match_dup 6)))] + " +{ + int mb = extract_MB (operands[2]); + int me = extract_ME (operands[2]); + operands[4] = GEN_INT (me + 1); + operands[6] = GEN_INT (32 - (me + 1)); + operands[5] = GEN_INT (~((HOST_WIDE_INT) -1 << (33 + me - mb))); +}" + [(set_attr "type" "delayed_compare,compare") + (set_attr "length" "8,12")]) + (define_expand "iorsi3" [(set (match_operand:SI 0 "gpc_reg_operand" "") (ior:SI (match_operand:SI 1 "gpc_reg_operand" "") @@ -3321,7 +3615,7 @@ #" [(set_attr "type" "compare") (set_attr "length" "4,8")]) - + (define_split [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "") (compare:CC @@ -3341,7 +3635,7 @@ (compare:CC (match_dup 0) (const_int 0)))] "") - + ;; Rotate and shift insns, in all their variants. These support shifts, ;; field inserts and extracts, and various combinations thereof. (define_expand "insv" @@ -3519,7 +3813,7 @@ (match_operand:SI 3 "const_int_operand" "i,i")) (const_int 0))) (clobber (match_scratch:SI 4 "=r,r"))] - "! TARGET_POWERPC64" + "" "* { int start = INTVAL (operands[3]) & 31; @@ -3529,7 +3823,7 @@ if (which_alternative == 1) return \"#\"; - /* If the bitfield being tested fits in the upper or lower half of a + /* If the bit-field being tested fits in the upper or lower half of a word, it is possible to use andiu. or andil. to test it. This is useful because the condition register set-use delay is smaller for andi[ul]. than for rlinm. This doesn't work when the starting bit @@ -3561,7 +3855,7 @@ (match_operand:SI 3 "const_int_operand" "")) (const_int 0))) (clobber (match_scratch:SI 4 ""))] - "! TARGET_POWERPC64 && reload_completed" + "reload_completed" [(set (match_dup 4) (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3))) @@ -3578,7 +3872,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))] - "! TARGET_POWERPC64" + "" "* { int start = INTVAL (operands[3]) & 31; @@ -3588,9 +3882,11 @@ if (which_alternative == 1) return \"#\"; + /* Since we are using the output value, we can't ignore any need for + a shift. The bit-field must end at the LSB. */ if (start >= 16 && start + size == 32) { - operands[3] = GEN_INT ((1 << (32 - start)) - 1); + operands[3] = GEN_INT ((1 << size) - 1); return \"{andil.|andi.} %0,%1,%3\"; } @@ -3600,7 +3896,7 @@ operands[3] = GEN_INT (start + size); return \"{rlinm.|rlwinm.} %0,%1,%3,%s2,31\"; }" - [(set_attr "type" "delayed_compare") + [(set_attr "type" "compare") (set_attr "length" "4,8")]) (define_split @@ -3611,7 +3907,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))] - "! TARGET_POWERPC64 && reload_completed" + "reload_completed" [(set (match_dup 0) (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3))) (set (match_dup 4) @@ -3694,7 +3990,7 @@ (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r"))] - "! TARGET_POWERPC64" + "" "@ {rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffffffff #" @@ -3707,7 +4003,7 @@ (match_operand:SI 2 "reg_or_cint_operand" "")) (const_int 0))) (clobber (match_scratch:SI 3 ""))] - "! TARGET_POWERPC64 && reload_completed" + "reload_completed" [(set (match_dup 3) (rotate:SI (match_dup 1) (match_dup 2))) (set (match_dup 0) @@ -3722,7 +4018,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (rotate:SI (match_dup 1) (match_dup 2)))] - "! TARGET_POWERPC64" + "" "@ {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffffffff #" @@ -3736,7 +4032,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (rotate:SI (match_dup 1) (match_dup 2)))] - "! TARGET_POWERPC64 && reload_completed" + "reload_completed" [(set (match_dup 0) (rotate:SI (match_dup 1) (match_dup 2))) (set (match_dup 3) @@ -3748,7 +4044,7 @@ [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_cint_operand" "ri")) - (match_operand:SI 3 "mask_operand" "T")))] + (match_operand:SI 3 "mask_operand" "n")))] "" "{rl%I2nm|rlw%I2nm} %0,%1,%h2,%m3,%M3") @@ -3757,10 +4053,10 @@ (compare:CC (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) - (match_operand:SI 3 "mask_operand" "T,T")) + (match_operand:SI 3 "mask_operand" "n,n")) (const_int 0))) (clobber (match_scratch:SI 4 "=r,r"))] - "! TARGET_POWERPC64" + "" "@ {rl%I2nm.|rlw%I2nm.} %4,%1,%h2,%m3,%M3 #" @@ -3775,7 +4071,7 @@ (match_operand:SI 3 "mask_operand" "")) (const_int 0))) (clobber (match_scratch:SI 4 ""))] - "! TARGET_POWERPC64 && reload_completed" + "reload_completed" [(set (match_dup 4) (and:SI (rotate:SI (match_dup 1) (match_dup 2)) @@ -3790,11 +4086,11 @@ (compare:CC (and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) - (match_operand:SI 3 "mask_operand" "T,T")) + (match_operand:SI 3 "mask_operand" "n,n")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "! TARGET_POWERPC64" + "" "@ {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,%m3,%M3 #" @@ -3810,7 +4106,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "! TARGET_POWERPC64 && reload_completed" + "reload_completed" [(set (match_dup 0) (and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (set (match_dup 4) @@ -4128,7 +4424,7 @@ [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:SI 3 "mask_operand" "T")))] + (match_operand:SI 3 "mask_operand" "n")))] "includes_lshift_p (operands[2], operands[3])" "{rlinm|rlwinm} %0,%1,%h2,%m3,%M3") @@ -4137,10 +4433,10 @@ (compare:CC (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:SI 3 "mask_operand" "T,T")) + (match_operand:SI 3 "mask_operand" "n,n")) (const_int 0))) (clobber (match_scratch:SI 4 "=r,r"))] - "! TARGET_POWERPC64 && includes_lshift_p (operands[2], operands[3])" + "includes_lshift_p (operands[2], operands[3])" "@ {rlinm.|rlwinm.} %4,%1,%h2,%m3,%M3 #" @@ -4155,7 +4451,7 @@ (match_operand:SI 3 "mask_operand" "")) (const_int 0))) (clobber (match_scratch:SI 4 ""))] - "! TARGET_POWERPC64 && includes_lshift_p (operands[2], operands[3]) && reload_completed" + "includes_lshift_p (operands[2], operands[3]) && reload_completed" [(set (match_dup 4) (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3))) @@ -4169,11 +4465,11 @@ (compare:CC (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:SI 3 "mask_operand" "T,T")) + (match_operand:SI 3 "mask_operand" "n,n")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "! TARGET_POWERPC64 && includes_lshift_p (operands[2], operands[3])" + "includes_lshift_p (operands[2], operands[3])" "@ {rlinm.|rlwinm.} %0,%1,%h2,%m3,%M3 #" @@ -4189,7 +4485,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "! TARGET_POWERPC64 && includes_lshift_p (operands[2], operands[3]) && reload_completed" + "includes_lshift_p (operands[2], operands[3]) && reload_completed" [(set (match_dup 0) (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (set (match_dup 4) @@ -4367,7 +4663,7 @@ [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:SI 3 "mask_operand" "T")))] + (match_operand:SI 3 "mask_operand" "n")))] "includes_rshift_p (operands[2], operands[3])" "{rlinm|rlwinm} %0,%1,%s2,%m3,%M3") @@ -4376,10 +4672,10 @@ (compare:CC (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:SI 3 "mask_operand" "T,T")) + (match_operand:SI 3 "mask_operand" "n,n")) (const_int 0))) (clobber (match_scratch:SI 4 "=r,r"))] - "! TARGET_POWERPC64 && includes_rshift_p (operands[2], operands[3])" + "includes_rshift_p (operands[2], operands[3])" "@ {rlinm.|rlwinm.} %4,%1,%s2,%m3,%M3 #" @@ -4394,7 +4690,7 @@ (match_operand:SI 3 "mask_operand" "")) (const_int 0))) (clobber (match_scratch:SI 4 ""))] - "! TARGET_POWERPC64 && includes_rshift_p (operands[2], operands[3]) && reload_completed" + "includes_rshift_p (operands[2], operands[3]) && reload_completed" [(set (match_dup 4) (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3))) @@ -4408,11 +4704,11 @@ (compare:CC (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:SI 3 "mask_operand" "T,T")) + (match_operand:SI 3 "mask_operand" "n,n")) (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "! TARGET_POWERPC64 && includes_rshift_p (operands[2], operands[3])" + "includes_rshift_p (operands[2], operands[3])" "@ {rlinm.|rlwinm.} %0,%1,%s2,%m3,%M3 #" @@ -4428,7 +4724,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "! TARGET_POWERPC64 && includes_rshift_p (operands[2], operands[3]) && reload_completed" + "includes_rshift_p (operands[2], operands[3]) && reload_completed" [(set (match_dup 0) (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (set (match_dup 4) @@ -4794,7 +5090,7 @@ (define_insn "extendsfdf2" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS" "* { if (REGNO (operands[0]) == REGNO (operands[1])) @@ -4807,35 +5103,47 @@ (define_insn "truncdfsf2" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS" "frsp %0,%1" [(set_attr "type" "fp")]) (define_insn "aux_truncdfsf2" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] 0))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT" + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS" "frsp %0,%1" [(set_attr "type" "fp")]) -(define_insn "negsf2" +(define_expand "negsf2" + [(set (match_operand:SF 0 "gpc_reg_operand" "") + (neg:SF (match_operand:SF 1 "gpc_reg_operand" "")))] + "TARGET_HARD_FLOAT" + "") + +(define_insn "*negsf2" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS" "fneg %0,%1" [(set_attr "type" "fp")]) -(define_insn "abssf2" +(define_expand "abssf2" + [(set (match_operand:SF 0 "gpc_reg_operand" "") + (abs:SF (match_operand:SF 1 "gpc_reg_operand" "")))] + "TARGET_HARD_FLOAT" + "") + +(define_insn "*abssf2" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS" "fabs %0,%1" [(set_attr "type" "fp")]) (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (neg:SF (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f"))))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS" "fnabs %0,%1" [(set_attr "type" "fp")]) @@ -4850,7 +5158,7 @@ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")))] - "TARGET_POWERPC && TARGET_HARD_FLOAT" + "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS" "fadds %0,%1,%2" [(set_attr "type" "fp")]) @@ -4858,7 +5166,7 @@ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT" + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS" "{fa|fadd} %0,%1,%2" [(set_attr "type" "fp")]) @@ -4873,7 +5181,7 @@ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f") (match_operand:SF 2 "gpc_reg_operand" "f")))] - "TARGET_POWERPC && TARGET_HARD_FLOAT" + "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS" "fsubs %0,%1,%2" [(set_attr "type" "fp")]) @@ -4881,7 +5189,7 @@ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (minus:SF (match_operand:SF 1 "gpc_reg_operand" "f") (match_operand:SF 2 "gpc_reg_operand" "f")))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT" + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS" "{fs|fsub} %0,%1,%2" [(set_attr "type" "fp")]) @@ -4896,7 +5204,7 @@ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")))] - "TARGET_POWERPC && TARGET_HARD_FLOAT" + "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS" "fmuls %0,%1,%2" [(set_attr "type" "fp")]) @@ -4904,7 +5212,7 @@ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f") (match_operand:SF 2 "gpc_reg_operand" "f")))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT" + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS" "{fm|fmul} %0,%1,%2" [(set_attr "type" "dmul")]) @@ -4919,7 +5227,7 @@ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (div:SF (match_operand:SF 1 "gpc_reg_operand" "f") (match_operand:SF 2 "gpc_reg_operand" "f")))] - "TARGET_POWERPC && TARGET_HARD_FLOAT" + "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS" "fdivs %0,%1,%2" [(set_attr "type" "sdiv")]) @@ -4927,7 +5235,7 @@ [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (div:SF (match_operand:SF 1 "gpc_reg_operand" "f") (match_operand:SF 2 "gpc_reg_operand" "f")))] - "! TARGET_POWERPC && TARGET_HARD_FLOAT" + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS" "{fd|fdiv} %0,%1,%2" [(set_attr "type" "ddiv")]) @@ -4936,7 +5244,7 @@ (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_FUSED_MADD" + "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD" "fmadds %0,%1,%2,%3" [(set_attr "type" "fp")]) @@ -4945,7 +5253,7 @@ (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_FUSED_MADD" + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD" "{fma|fmadd} %0,%1,%2,%3" [(set_attr "type" "dmul")]) @@ -4954,7 +5262,7 @@ (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_FUSED_MADD" + "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD" "fmsubs %0,%1,%2,%3" [(set_attr "type" "fp")]) @@ -4963,7 +5271,7 @@ (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_FUSED_MADD" + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD" "{fms|fmsub} %0,%1,%2,%3" [(set_attr "type" "dmul")]) @@ -4972,7 +5280,18 @@ (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_FUSED_MADD" + "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD + && HONOR_SIGNED_ZEROS (SFmode)" + "fnmadds %0,%1,%2,%3" + [(set_attr "type" "fp")]) + +(define_insn "" + [(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")) + (match_operand:SF 3 "gpc_reg_operand" "f")))] + "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD + && ! HONOR_SIGNED_ZEROS (SFmode)" "fnmadds %0,%1,%2,%3" [(set_attr "type" "fp")]) @@ -4981,7 +5300,17 @@ (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_FUSED_MADD" + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD" + "{fnma|fnmadd} %0,%1,%2,%3" + [(set_attr "type" "dmul")]) + +(define_insn "" + [(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")) + (match_operand:SF 3 "gpc_reg_operand" "f")))] + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD + && ! HONOR_SIGNED_ZEROS (SFmode)" "{fnma|fnmadd} %0,%1,%2,%3" [(set_attr "type" "dmul")]) @@ -4990,7 +5319,18 @@ (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_FUSED_MADD" + "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD + && HONOR_SIGNED_ZEROS (SFmode)" + "fnmsubs %0,%1,%2,%3" + [(set_attr "type" "fp")]) + +(define_insn "" + [(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") + (match_operand:SF 2 "gpc_reg_operand" "f"))))] + "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD + && ! HONOR_SIGNED_ZEROS (SFmode)" "fnmsubs %0,%1,%2,%3" [(set_attr "type" "fp")]) @@ -4999,27 +5339,37 @@ (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_FUSED_MADD" + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD" "{fnms|fnmsub} %0,%1,%2,%3" [(set_attr "type" "dmul")]) +(define_insn "" + [(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") + (match_operand:SF 2 "gpc_reg_operand" "f"))))] + "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD + && ! HONOR_SIGNED_ZEROS (SFmode)" + "{fnms|fnmsub} %0,%1,%2,%3" + [(set_attr "type" "fp")]) + (define_expand "sqrtsf2" [(set (match_operand:SF 0 "gpc_reg_operand" "") (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))] - "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT" + "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS" "") (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))] - "TARGET_PPC_GPOPT && TARGET_HARD_FLOAT" + "TARGET_PPC_GPOPT && TARGET_HARD_FLOAT && TARGET_FPRS" "fsqrts %0,%1" [(set_attr "type" "ssqrt")]) (define_insn "" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))] - "TARGET_POWER2 && TARGET_HARD_FLOAT" + "TARGET_POWER2 && TARGET_HARD_FLOAT && TARGET_FPRS" "fsqrt %0,%1" [(set_attr "type" "dsqrt")]) @@ -5033,7 +5383,7 @@ (match_operand:SF 2 "gpc_reg_operand" "")) (match_dup 1) (match_dup 2)))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS" "{ rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); DONE;}") (define_expand "minsf3" @@ -5042,7 +5392,7 @@ (match_operand:SF 2 "gpc_reg_operand" "")) (match_dup 2) (match_dup 1)))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS" "{ rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]); DONE;}") (define_split @@ -5050,7 +5400,7 @@ (match_operator:SF 3 "min_max_operator" [(match_operand:SF 1 "gpc_reg_operand" "") (match_operand:SF 2 "gpc_reg_operand" "")]))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS" [(const_int 0)] " { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]), @@ -5058,12 +5408,60 @@ 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" + " +{ + if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) + DONE; + else + FAIL; +}") + +;; We use the BASE_REGS for the isel input operands because, if rA is +;; 0, the value of 0 is placed in rD upon truth. Similarly for rB +;; because we may switch the operands and rB may end up being rA. +;; +;; We need 2 patterns: an unsigned and a signed pattern. We could +;; 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 + (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" + "* +{ 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 + (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" + "* +{ return output_isel (operands); }" + [(set_attr "length" "4")]) + (define_expand "movsfcc" [(set (match_operand:SF 0 "gpc_reg_operand" "") (if_then_else:SF (match_operand 1 "comparison_operator" "") (match_operand:SF 2 "gpc_reg_operand" "") (match_operand:SF 3 "gpc_reg_operand" "")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS" " { if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) @@ -5078,7 +5476,7 @@ (match_operand:SF 4 "zero_fp_constant" "F")) (match_operand:SF 2 "gpc_reg_operand" "f") (match_operand:SF 3 "gpc_reg_operand" "f")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS" "fsel %0,%1,%2,%3" [(set_attr "type" "fp")]) @@ -5088,28 +5486,28 @@ (match_operand:DF 4 "zero_fp_constant" "F")) (match_operand:SF 2 "gpc_reg_operand" "f") (match_operand:SF 3 "gpc_reg_operand" "f")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS" "fsel %0,%1,%2,%3" [(set_attr "type" "fp")]) (define_insn "negdf2" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS" "fneg %0,%1" [(set_attr "type" "fp")]) (define_insn "absdf2" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS" "fabs %0,%1" [(set_attr "type" "fp")]) (define_insn "" [(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_HARD_FLOAT && TARGET_FPRS" "fnabs %0,%1" [(set_attr "type" "fp")]) @@ -5117,7 +5515,7 @@ [(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_HARD_FLOAT && TARGET_FPRS" "{fa|fadd} %0,%1,%2" [(set_attr "type" "fp")]) @@ -5125,7 +5523,7 @@ [(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_HARD_FLOAT && TARGET_FPRS" "{fs|fsub} %0,%1,%2" [(set_attr "type" "fp")]) @@ -5133,7 +5531,7 @@ [(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_HARD_FLOAT && TARGET_FPRS" "{fm|fmul} %0,%1,%2" [(set_attr "type" "dmul")]) @@ -5141,7 +5539,7 @@ [(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_HARD_FLOAT && TARGET_FPRS" "{fd|fdiv} %0,%1,%2" [(set_attr "type" "ddiv")]) @@ -5150,7 +5548,7 @@ (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_FUSED_MADD" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD" "{fma|fmadd} %0,%1,%2,%3" [(set_attr "type" "dmul")]) @@ -5159,7 +5557,7 @@ (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_FUSED_MADD" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD" "{fms|fmsub} %0,%1,%2,%3" [(set_attr "type" "dmul")]) @@ -5168,7 +5566,18 @@ (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"))))] - "TARGET_HARD_FLOAT && TARGET_FUSED_MADD" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD + && HONOR_SIGNED_ZEROS (DFmode)" + "{fnma|fnmadd} %0,%1,%2,%3" + [(set_attr "type" "dmul")]) + +(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")))] + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD + && ! HONOR_SIGNED_ZEROS (DFmode)" "{fnma|fnmadd} %0,%1,%2,%3" [(set_attr "type" "dmul")]) @@ -5177,14 +5586,25 @@ (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"))))] - "TARGET_HARD_FLOAT && TARGET_FUSED_MADD" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD + && HONOR_SIGNED_ZEROS (DFmode)" + "{fnms|fnmsub} %0,%1,%2,%3" + [(set_attr "type" "dmul")]) + +(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"))))] + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD + && ! HONOR_SIGNED_ZEROS (DFmode)" "{fnms|fnmsub} %0,%1,%2,%3" [(set_attr "type" "dmul")]) (define_insn "sqrtdf2" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "f")))] - "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT" + "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS" "fsqrt %0,%1" [(set_attr "type" "dsqrt")]) @@ -5197,7 +5617,7 @@ (match_operand:DF 2 "gpc_reg_operand" "")) (match_dup 1) (match_dup 2)))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS" "{ rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); DONE;}") (define_expand "mindf3" @@ -5206,7 +5626,7 @@ (match_operand:DF 2 "gpc_reg_operand" "")) (match_dup 2) (match_dup 1)))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS" "{ rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]); DONE;}") (define_split @@ -5214,7 +5634,7 @@ (match_operator:DF 3 "min_max_operator" [(match_operand:DF 1 "gpc_reg_operand" "") (match_operand:DF 2 "gpc_reg_operand" "")]))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS" [(const_int 0)] " { rs6000_emit_minmax (operands[0], GET_CODE (operands[3]), @@ -5227,7 +5647,7 @@ (if_then_else:DF (match_operand 1 "comparison_operator" "") (match_operand:DF 2 "gpc_reg_operand" "") (match_operand:DF 3 "gpc_reg_operand" "")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS" " { if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) @@ -5242,7 +5662,7 @@ (match_operand:DF 4 "zero_fp_constant" "F")) (match_operand:DF 2 "gpc_reg_operand" "f") (match_operand:DF 3 "gpc_reg_operand" "f")))] - "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS" "fsel %0,%1,%2,%3" [(set_attr "type" "fp")]) @@ -5258,6 +5678,18 @@ ;; Conversions to and from floating-point. +(define_expand "fixunssfsi2" + [(set (match_operand:SI 0 "gpc_reg_operand" "") + (unsigned_fix:SI (fix:SF (match_operand:SF 1 "gpc_reg_operand" ""))))] + "TARGET_HARD_FLOAT && !TARGET_FPRS" + "") + +(define_expand "fix_truncsfsi2" + [(set (match_operand:SI 0 "gpc_reg_operand" "") + (fix:SI (match_operand:SF 1 "gpc_reg_operand" "")))] + "TARGET_HARD_FLOAT && !TARGET_FPRS" + "") + ; 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, @@ -5271,7 +5703,7 @@ (clobber (match_dup 4)) (clobber (match_dup 5)) (clobber (match_dup 6))])] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS" " { if (TARGET_POWERPC64) @@ -5284,7 +5716,7 @@ } operands[2] = force_reg (SImode, GEN_INT (0x43300000)); - operands[3] = force_reg (DFmode, rs6000_float_const (\"4503601774854144\", DFmode)); + operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode)); operands[4] = assign_stack_temp (DFmode, GET_MODE_SIZE (DFmode), 0); operands[5] = gen_reg_rtx (DFmode); operands[6] = gen_reg_rtx (SImode); @@ -5298,7 +5730,7 @@ (clobber (match_operand:DF 4 "memory_operand" "=o")) (clobber (match_operand:DF 5 "gpc_reg_operand" "=f")) (clobber (match_operand:SI 6 "gpc_reg_operand" "=r"))] - "! TARGET_POWERPC64 && TARGET_HARD_FLOAT" + "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS" "#" [(set_attr "length" "24")]) @@ -5310,7 +5742,7 @@ (clobber (match_operand:DF 4 "offsettable_mem_operand" "")) (clobber (match_operand:DF 5 "gpc_reg_operand" "")) (clobber (match_operand:SI 6 "gpc_reg_operand" ""))] - "! TARGET_POWERPC64 && TARGET_HARD_FLOAT" + "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS" [(set (match_operand:DF 0 "gpc_reg_operand" "") (float:DF (match_operand:SI 1 "gpc_reg_operand" ""))) (use (match_operand:SI 2 "gpc_reg_operand" "")) @@ -5340,6 +5772,12 @@ DONE; }") +(define_expand "floatunssisf2" + [(set (match_operand:SF 0 "gpc_reg_operand" "") + (unsigned_float:SF (match_operand:SI 1 "gpc_reg_operand" "")))] + "TARGET_HARD_FLOAT && !TARGET_FPRS" + "") + (define_expand "floatunssidf2" [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "") (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" ""))) @@ -5347,7 +5785,7 @@ (use (match_dup 3)) (clobber (match_dup 4)) (clobber (match_dup 5))])] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS" " { if (TARGET_POWERPC64) @@ -5361,7 +5799,7 @@ } operands[2] = force_reg (SImode, GEN_INT (0x43300000)); - operands[3] = force_reg (DFmode, rs6000_float_const (\"4503599627370496\", DFmode)); + operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode)); operands[4] = assign_stack_temp (DFmode, GET_MODE_SIZE (DFmode), 0); operands[5] = gen_reg_rtx (DFmode); }") @@ -5373,7 +5811,7 @@ (use (match_operand:DF 3 "gpc_reg_operand" "f")) (clobber (match_operand:DF 4 "memory_operand" "=o")) (clobber (match_operand:DF 5 "gpc_reg_operand" "=f"))] - "! TARGET_POWERPC64 && TARGET_HARD_FLOAT" + "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS" "#" [(set_attr "length" "20")]) @@ -5384,7 +5822,7 @@ (use (match_operand:DF 3 "gpc_reg_operand" "")) (clobber (match_operand:DF 4 "offsettable_mem_operand" "")) (clobber (match_operand:DF 5 "gpc_reg_operand" ""))] - "! TARGET_POWERPC64 && TARGET_HARD_FLOAT" + "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS" [(set (match_operand:DF 0 "gpc_reg_operand" "") (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" ""))) (use (match_operand:SI 2 "gpc_reg_operand" "")) @@ -5416,7 +5854,7 @@ (fix:SI (match_operand:DF 1 "gpc_reg_operand" ""))) (clobber (match_dup 2)) (clobber (match_dup 3))])] - "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT" + "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS" " { operands[2] = gen_reg_rtx (DImode); @@ -5426,9 +5864,9 @@ (define_insn "*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")) + (clobber (match_operand:DI 2 "gpc_reg_operand" "=f")) (clobber (match_operand:DI 3 "memory_operand" "=o"))] - "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT" + "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS" "#" [(set_attr "length" "16")]) @@ -5437,7 +5875,7 @@ (fix:SI (match_operand:DF 1 "gpc_reg_operand" ""))) (clobber (match_operand:DI 2 "gpc_reg_operand" "")) (clobber (match_operand:DI 3 "offsettable_mem_operand" ""))] - "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT" + "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS" [(set (match_operand:SI 0 "gpc_reg_operand" "") (fix:SI (match_operand:DF 1 "gpc_reg_operand" ""))) (clobber (match_operand:DI 2 "gpc_reg_operand" "")) @@ -5464,14 +5902,20 @@ (define_insn "fctiwz" [(set (match_operand:DI 0 "gpc_reg_operand" "=*f") (unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))] 10))] - "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT" + "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS" "{fcirz|fctiwz} %0,%1" [(set_attr "type" "fp")]) +(define_expand "floatsisf2" + [(set (match_operand:SF 0 "gpc_reg_operand" "") + (float:SF (match_operand:SI 1 "gpc_reg_operand" "")))] + "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")))] - "TARGET_POWERPC64 && TARGET_HARD_FLOAT" + "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS" "fcfid %0,%1" [(set_attr "type" "fp")]) @@ -5481,7 +5925,7 @@ (clobber (match_operand:DI 2 "memory_operand" "=o")) (clobber (match_operand:DI 3 "gpc_reg_operand" "=r")) (clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))] - "TARGET_POWERPC64 && TARGET_HARD_FLOAT" + "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS" "#" "" [(set (match_dup 3) (sign_extend:DI (match_dup 1))) @@ -5496,7 +5940,7 @@ (clobber (match_operand:DI 2 "memory_operand" "=o")) (clobber (match_operand:DI 3 "gpc_reg_operand" "=r")) (clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))] - "TARGET_POWERPC64 && TARGET_HARD_FLOAT" + "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS" "#" "" [(set (match_dup 3) (zero_extend:DI (match_dup 1))) @@ -5508,9 +5952,72 @@ (define_insn "fix_truncdfdi2" [(set (match_operand:DI 0 "gpc_reg_operand" "=*f") (fix:DI (match_operand:DF 1 "gpc_reg_operand" "f")))] - "TARGET_POWERPC64 && TARGET_HARD_FLOAT" + "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS" "fctidz %0,%1" [(set_attr "type" "fp")]) + +(define_expand "floatdisf2" + [(set (match_operand:SF 0 "gpc_reg_operand" "") + (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))] + "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS" + " +{ + if (!flag_unsafe_math_optimizations) + { + rtx label = gen_label_rtx (); + emit_insn (gen_floatdisf2_internal2 (operands[1], label)); + emit_label (label); + } + emit_insn (gen_floatdisf2_internal1 (operands[0], operands[1])); + DONE; +}") + +;; This is not IEEE compliant if rounding mode is "round to nearest". +;; If the DI->DF conversion is inexact, then it's possible to suffer +;; 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"))) + (clobber (match_scratch:DF 2 "=f"))] + "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS" + "#" + "&& reload_completed" + [(set (match_dup 2) + (float:DF (match_dup 1))) + (set (match_dup 0) + (float_truncate:SF (match_dup 2)))] + "") + +;; Twiddles bits to avoid double rounding. +;; Bits that might be trucated when converting to DFmode are replaced +;; by a bit that won't be lost at that stage, but is below the SFmode +;; rounding position. +(define_expand "floatdisf2_internal2" + [(parallel [(set (match_dup 4) + (compare:CC (and:DI (match_operand:DI 0 "" "") + (const_int 2047)) + (const_int 0))) + (set (match_dup 2) (and:DI (match_dup 0) (const_int 2047))) + (clobber (match_scratch:CC 7 ""))]) + (set (match_dup 3) (ashiftrt:DI (match_dup 0) (const_int 53))) + (set (match_dup 3) (plus:DI (match_dup 3) (const_int 1))) + (set (pc) (if_then_else (eq (match_dup 4) (const_int 0)) + (label_ref (match_operand:DI 1 "" "")) + (pc))) + (set (match_dup 5) (compare:CCUNS (match_dup 3) (const_int 2))) + (set (pc) (if_then_else (ltu (match_dup 5) (const_int 0)) + (label_ref (match_dup 1)) + (pc))) + (set (match_dup 0) (xor:DI (match_dup 0) (match_dup 2))) + (set (match_dup 0) (ior:DI (match_dup 0) (const_int 2048)))] + "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS" + " +{ + operands[2] = gen_reg_rtx (DImode); + operands[3] = gen_reg_rtx (DImode); + operands[4] = gen_reg_rtx (CCmode); + operands[5] = gen_reg_rtx (CCUNSmode); +}") ;; Define the DImode operations that can be done in a small number ;; of instructions. The & constraints are to prevent the register @@ -5838,6 +6345,16 @@ {srai|srawi} %0,%1,31\;{srai|srawi} %L0,%1,%h2 sraiq %0,%1,%h2\;srliq %L0,%L1,%h2" [(set_attr "length" "8")]) + +(define_insn "ashrdi3_no_power" + [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r") + (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:SI 2 "const_int_operand" "M,i")))] + "TARGET_32BIT && !TARGET_POWER" + "@ + {srai|srawi} %0,%1,31\;{srai|srawi} %L0,%1,%h2 + {sri|srwi} %L0,%L1,%h2\;insrwi %L0,%1,%h2,0\;{srai|srawi} %0,%1,%h2" + [(set_attr "length" "8,12")]) ;; PowerPC64 DImode operations. @@ -5861,7 +6378,7 @@ ? operands[0] : gen_reg_rtx (DImode)); HOST_WIDE_INT val = INTVAL (operands[2]); - HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000); + HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; HOST_WIDE_INT rest = trunc_int_for_mode (val - low, DImode); if (!CONST_OK_FOR_LETTER_P (rest, 'L')) @@ -5964,7 +6481,7 @@ " { HOST_WIDE_INT val = INTVAL (operands[2]); - HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000); + HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; HOST_WIDE_INT rest = trunc_int_for_mode (val - low, DImode); operands[4] = GEN_INT (low); @@ -6119,37 +6636,25 @@ } }") -(define_insn "absdi2" +(define_insn_and_split "absdi2" [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r") - (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))) + (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))) (clobber (match_scratch:DI 2 "=&r,&r"))] "TARGET_POWERPC64" - "sradi %2,%1,63\;xor %0,%2,%1\;subf %0,%2,%0" - [(set_attr "length" "12")]) - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (abs:DI (match_operand:DI 1 "gpc_reg_operand" ""))) - (clobber (match_scratch:DI 2 ""))] - "TARGET_POWERPC64 && reload_completed" + "#" + "&& reload_completed" [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 63))) (set (match_dup 0) (xor:DI (match_dup 2) (match_dup 1))) (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))] "") -(define_insn "*nabsdi2" +(define_insn_and_split "*nabsdi2" [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r") - (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))) + (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))) (clobber (match_scratch:DI 2 "=&r,&r"))] "TARGET_POWERPC64" - "sradi %2,%1,63\;xor %0,%2,%1\;subf %0,%0,%2" - [(set_attr "length" "12")]) - -(define_split - [(set (match_operand:DI 0 "gpc_reg_operand" "") - (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "")))) - (clobber (match_scratch:DI 2 ""))] - "TARGET_POWERPC64 && reload_completed" + "#" + "&& reload_completed" [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 63))) (set (match_dup 0) (xor:DI (match_dup 2) (match_dup 1))) (set (match_dup 0) (minus:DI (match_dup 2) (match_dup 0)))] @@ -6445,7 +6950,7 @@ [(set (match_operand:DI 0 "gpc_reg_operand" "=r") (and:DI (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r") (match_operand:DI 2 "reg_or_cint_operand" "ri")) - (match_operand:DI 3 "mask64_operand" "S")))] + (match_operand:DI 3 "mask64_operand" "n")))] "TARGET_POWERPC64" "rld%I2c%B3 %0,%1,%H2,%S3") @@ -6454,7 +6959,7 @@ (compare:CC (and:DI (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) - (match_operand:DI 3 "mask64_operand" "S,S")) + (match_operand:DI 3 "mask64_operand" "n,n")) (const_int 0))) (clobber (match_scratch:DI 4 "=r,r"))] "TARGET_POWERPC64" @@ -6487,7 +6992,7 @@ (compare:CC (and:DI (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) - (match_operand:DI 3 "mask64_operand" "S,S")) + (match_operand:DI 3 "mask64_operand" "n,n")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] @@ -6902,7 +7407,7 @@ [(set (match_operand:DI 0 "gpc_reg_operand" "=r") (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:DI 3 "mask64_operand" "S")))] + (match_operand:DI 3 "mask64_operand" "n")))] "TARGET_POWERPC64 && includes_rldicr_lshift_p (operands[2], operands[3])" "rldicr %0,%1,%H2,%S3") @@ -6911,7 +7416,7 @@ (compare:CC (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:DI 3 "mask64_operand" "S,S")) + (match_operand:DI 3 "mask64_operand" "n,n")) (const_int 0))) (clobber (match_scratch:DI 4 "=r,r"))] "TARGET_POWERPC64 && includes_rldicr_lshift_p (operands[2], operands[3])" @@ -6944,7 +7449,7 @@ (compare:CC (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "const_int_operand" "i,i")) - (match_operand:DI 3 "mask64_operand" "S,S")) + (match_operand:DI 3 "mask64_operand" "n,n")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] @@ -7059,7 +7564,7 @@ [(set (match_operand:DI 0 "gpc_reg_operand" "") (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "") (match_operand:SI 2 "reg_or_cint_operand" "")))] - "TARGET_POWERPC64 || TARGET_POWER" + "" " { if (TARGET_POWERPC64) @@ -7069,6 +7574,11 @@ emit_insn (gen_ashrdi3_power (operands[0], operands[1], operands[2])); DONE; } + else if (TARGET_32BIT && GET_CODE (operands[2]) == CONST_INT) + { + emit_insn (gen_ashrdi3_no_power (operands[0], operands[1], operands[2])); + DONE; + } else FAIL; }") @@ -7137,24 +7647,47 @@ "") (define_insn "anddi3" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") - (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r") - (match_operand:DI 2 "and64_operand" "?r,S,K,J"))) - (clobber (match_scratch:CC 3 "=X,X,x,x"))] + [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r") + (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r") + (match_operand:DI 2 "and64_2_operand" "?r,S,K,J,t"))) + (clobber (match_scratch:CC 3 "=X,X,x,x,X"))] "TARGET_POWERPC64" "@ and %0,%1,%2 rldic%B2 %0,%1,0,%S2 andi. %0,%1,%b2 - andis. %0,%1,%u2") + andis. %0,%1,%u2 + #" + [(set_attr "length" "4,4,4,4,8")]) + +(define_split + [(set (match_operand:DI 0 "gpc_reg_operand" "") + (and:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "mask64_2_operand" ""))) + (clobber (match_scratch:CC 3 ""))] + "TARGET_POWERPC64 + && (fixed_regs[CR0_REGNO] || !logical_operand (operands[2], DImode)) + && !mask64_operand (operands[2], DImode)" + [(set (match_dup 0) + (and:DI (rotate:DI (match_dup 1) + (match_dup 4)) + (match_dup 5))) + (set (match_dup 0) + (and:DI (rotate:DI (match_dup 0) + (match_dup 6)) + (match_dup 7)))] + " +{ + build_mask64_2_operands (operands[2], &operands[4]); +}") (define_insn "*anddi3_internal2" - [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,?y,?y,??y,??y") - (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,") - (match_operand:DI 2 "and64_operand" "r,S,K,J,r,S,K,J")) + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x,?y,?y,??y,??y,?y") + (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r") + (match_operand:DI 2 "and64_2_operand" "r,S,K,J,t,r,S,K,J,t")) (const_int 0))) - (clobber (match_scratch:DI 3 "=r,r,r,r,r,r,r,r")) - (clobber (match_scratch:CC 4 "=X,X,X,X,X,X,x,x"))] + (clobber (match_scratch:DI 3 "=r,r,r,r,r,r,r,r,r,r")) + (clobber (match_scratch:CC 4 "=X,X,X,X,X,X,X,x,x,X"))] "TARGET_POWERPC64" "@ and. %3,%1,%2 @@ -7164,9 +7697,11 @@ # # # + # + # #" - [(set_attr "type" "compare,delayed_compare,compare,compare,compare,delayed_compare,compare,compare") - (set_attr "length" "4,4,4,4,8,8,8,8")]) + [(set_attr "type" "compare,delayed_compare,compare,compare,delayed_compare,compare,compare,compare,compare,compare") + (set_attr "length" "4,4,4,4,8,8,8,8,8,12")]) (define_split [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") @@ -7185,14 +7720,39 @@ (const_int 0)))] "") +(define_split + [(set (match_operand:CC 0 "cc_reg_operand" "") + (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "mask64_2_operand" "")) + (const_int 0))) + (clobber (match_scratch:DI 3 "")) + (clobber (match_scratch:CC 4 ""))] + "TARGET_POWERPC64 && reload_completed + && (fixed_regs[CR0_REGNO] || !logical_operand (operands[2], DImode)) + && !mask64_operand (operands[2], DImode)" + [(set (match_dup 3) + (and:DI (rotate:DI (match_dup 1) + (match_dup 5)) + (match_dup 6))) + (parallel [(set (match_dup 0) + (compare:CC (and:DI (rotate:DI (match_dup 3) + (match_dup 7)) + (match_dup 8)) + (const_int 0))) + (clobber (match_dup 3))])] + " +{ + build_mask64_2_operands (operands[2], &operands[5]); +}") + (define_insn "*anddi3_internal3" - [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,?y,?y,??y,??y") - (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r") - (match_operand:DI 2 "and64_operand" "r,S,K,J,r,S,K,J")) + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,x,?y,?y,??y,??y,?y") + (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r") + (match_operand:DI 2 "and64_2_operand" "r,S,K,J,t,r,S,K,J,t")) (const_int 0))) - (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r") + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r") (and:DI (match_dup 1) (match_dup 2))) - (clobber (match_scratch:CC 4 "=X,X,X,X,X,X,x,x"))] + (clobber (match_scratch:CC 4 "=X,X,X,X,X,X,X,x,x,X"))] "TARGET_POWERPC64" "@ and. %0,%1,%2 @@ -7202,9 +7762,11 @@ # # # + # + # #" - [(set_attr "type" "compare,delayed_compare,compare,compare,compare,delayed_compare,compare,compare") - (set_attr "length" "4,4,4,4,8,8,8,8")]) + [(set_attr "type" "compare,delayed_compare,compare,compare,delayed_compare,compare,compare,compare,compare,compare") + (set_attr "length" "4,4,4,4,8,8,8,8,8,12")]) (define_split [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "") @@ -7223,6 +7785,35 @@ (const_int 0)))] "") +(define_split + [(set (match_operand:CC 3 "cc_reg_operand" "") + (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "") + (match_operand:DI 2 "mask64_2_operand" "")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (and:DI (match_dup 1) (match_dup 2))) + (clobber (match_scratch:CC 4 ""))] + "TARGET_POWERPC64 && reload_completed + && (fixed_regs[CR0_REGNO] || !logical_operand (operands[2], DImode)) + && !mask64_operand (operands[2], DImode)" + [(set (match_dup 0) + (and:DI (rotate:DI (match_dup 1) + (match_dup 5)) + (match_dup 6))) + (parallel [(set (match_dup 3) + (compare:CC (and:DI (rotate:DI (match_dup 0) + (match_dup 7)) + (match_dup 8)) + (const_int 0))) + (set (match_dup 0) + (and:DI (rotate:DI (match_dup 0) + (match_dup 7)) + (match_dup 8)))])] + " +{ + build_mask64_2_operands (operands[2], &operands[5]); +}") + (define_expand "iordi3" [(set (match_operand:DI 0 "gpc_reg_operand" "") (ior:DI (match_operand:DI 1 "gpc_reg_operand" "") @@ -7622,7 +8213,7 @@ (define_insn "movsi_low" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (mem:SI (lo_sum:SI (match_operand:SI 1 "register_operand" "b") + (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") (match_operand 2 "" ""))))] "TARGET_MACHO && ! TARGET_64BIT" "{l|lwz} %0,lo16(%2)(%1)" @@ -7630,7 +8221,7 @@ (set_attr "length" "4")]) (define_insn "movsi_low_st" - [(set (mem:SI (lo_sum:SI (match_operand:SI 1 "register_operand" "b") + [(set (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") (match_operand 2 "" ""))) (match_operand:SI 0 "gpc_reg_operand" "r"))] "TARGET_MACHO && ! TARGET_64BIT" @@ -7640,9 +8231,9 @@ (define_insn "movdf_low" [(set (match_operand:DF 0 "gpc_reg_operand" "=f,!r") - (mem:DF (lo_sum:SI (match_operand:SI 1 "register_operand" "b,b") + (mem:DF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b") (match_operand 2 "" ""))))] - "TARGET_MACHO && TARGET_HARD_FLOAT && ! TARGET_64BIT" + "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_64BIT" "* { switch (which_alternative) @@ -7670,19 +8261,19 @@ (set_attr "length" "4,12")]) (define_insn "movdf_low_st" - [(set (mem:DF (lo_sum:SI (match_operand:SI 1 "register_operand" "b") + [(set (mem:DF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") (match_operand 2 "" ""))) (match_operand:DF 0 "gpc_reg_operand" "f"))] - "TARGET_MACHO && TARGET_HARD_FLOAT && ! TARGET_64BIT" + "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_64BIT" "stfd %0,lo16(%2)(%1)" [(set_attr "type" "store") (set_attr "length" "4")]) (define_insn "movsf_low" [(set (match_operand:SF 0 "gpc_reg_operand" "=f,!r") - (mem:SF (lo_sum:SI (match_operand:SI 1 "register_operand" "b,b") + (mem:SF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b") (match_operand 2 "" ""))))] - "TARGET_MACHO && TARGET_HARD_FLOAT && ! TARGET_64BIT" + "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_64BIT" "@ lfs %0,lo16(%2)(%1) {l|lwz} %0,lo16(%2)(%1)" @@ -7690,10 +8281,10 @@ (set_attr "length" "4")]) (define_insn "movsf_low_st" - [(set (mem:SF (lo_sum:SI (match_operand:SI 1 "register_operand" "b,b") + [(set (mem:SF (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,b") (match_operand 2 "" ""))) (match_operand:SF 0 "gpc_reg_operand" "f,!r"))] - "TARGET_MACHO && TARGET_HARD_FLOAT && ! TARGET_64BIT" + "TARGET_MACHO && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_64BIT" "@ stfs %0,lo16(%2)(%1) {st|stw} %0,lo16(%2)(%1)" @@ -7718,7 +8309,7 @@ mt%0 %1 mt%0 %1 mt%0 %1 - cror 0,0,0" + {cror 0,0,0|nop}" [(set_attr "type" "*,*,load,store,*,*,*,*,*,*,mtjmpr,*,*") (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")]) @@ -7736,9 +8327,12 @@ (ior:SI (match_dup 0) (match_dup 3)))] " -{ - operands[2] = GEN_INT (INTVAL (operands[1]) & (~ (HOST_WIDE_INT) 0xffff)); - operands[3] = GEN_INT (INTVAL (operands[1]) & 0xffff); +{ rtx tem = rs6000_emit_set_const (operands[0], SImode, operands[1], 2); + + if (tem == operands[0]) + DONE; + else + FAIL; }") (define_insn "*movsi_internal2" @@ -7771,7 +8365,7 @@ "" "{ rs6000_emit_move (operands[0], operands[1], HImode); DONE; }") -(define_insn "" +(define_insn "*movhi_internal" [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h") (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,r,0"))] "gpc_reg_operand (operands[0], HImode) @@ -7784,7 +8378,7 @@ mf%1 %0 mt%0 %1 mt%0 %1 - cror 0,0,0" + {cror 0,0,0|nop}" [(set_attr "type" "*,load,store,*,*,*,mtjmpr,*")]) (define_expand "movqi" @@ -7793,7 +8387,7 @@ "" "{ rs6000_emit_move (operands[0], operands[1], QImode); DONE; }") -(define_insn "" +(define_insn "*movqi_internal" [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h") (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,r,0"))] "gpc_reg_operand (operands[0], QImode) @@ -7806,7 +8400,7 @@ mf%1 %0 mt%0 %1 mt%0 %1 - cror 0,0,0" + {cror 0,0,0|nop}" [(set_attr "type" "*,load,store,*,*,*,mtjmpr,*")]) ;; Here is how to move condition codes around. When we store CC data in @@ -7818,9 +8412,9 @@ "" "") -(define_insn "" - [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,y,r,r,r,r,m") - (match_operand:CC 1 "nonimmediate_operand" "y,r,r,x,y,r,m,r"))] +(define_insn "*movcc_internal1" + [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,y,r,r,r,cl,q,r,r,m") + (match_operand:CC 1 "nonimmediate_operand" "y,r,r,x,y,r,r,r,h,m,r"))] "register_operand (operands[0], CCmode) || register_operand (operands[1], CCmode)" "@ @@ -7830,10 +8424,13 @@ mfcr %0 mfcr %0\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000 mr %0,%1 + mt%0 %1 + mt%0 %1 + mf%1 %0 {l%U1%X1|lwz%U1%X1} %0,%1 {st%U0%U1|stw%U0%U1} %1,%0" - [(set_attr "type" "*,*,*,compare,*,*,load,store") - (set_attr "length" "*,*,12,*,8,*,*,*")]) + [(set_attr "type" "cr_logical,cr_logical,cr_logical,cr_logical,cr_logical,*,*,mtjmpr,*,load,store") + (set_attr "length" "4,4,12,4,8,4,4,4,4,4,4")]) ;; For floating-point, we normally deal with the floating-point registers ;; unless -msoft-float is used. The sole exception is that parameter passing @@ -7868,14 +8465,15 @@ else operands[2] = gen_lowpart (SImode, operands[0]); - operands[3] = GEN_INT (trunc_int_for_mode (l, SImode)); + operands[3] = gen_int_mode (l, SImode); }") (define_insn "*movsf_hardfloat" - [(set (match_operand:SF 0 "nonimmediate_operand" "=!r,!r,m,f,f,m,!r,!r") - (match_operand:SF 1 "input_operand" "r,m,r,f,m,f,G,Fn"))] + [(set (match_operand:SF 0 "nonimmediate_operand" "=!r,!r,m,f,f,m,!cl,!q,!r,!r,!r") + (match_operand:SF 1 "input_operand" "r,m,r,f,m,f,r,r,h,G,Fn"))] "(gpc_reg_operand (operands[0], SFmode) - || gpc_reg_operand (operands[1], SFmode)) && TARGET_HARD_FLOAT" + || gpc_reg_operand (operands[1], SFmode)) + && (TARGET_HARD_FLOAT && TARGET_FPRS)" "@ mr %0,%1 {l%U1%X1|lwz%U1%X1} %0,%1 @@ -7883,18 +8481,25 @@ fmr %0,%1 lfs%U1%X1 %0,%1 stfs%U0%X0 %1,%0 + mt%0 %1 + mt%0 %1 + mf%1 %0 # #" - [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*") - (set_attr "length" "4,4,4,4,4,4,4,8")]) + [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,mtjmpr,*,*,*") + (set_attr "length" "4,4,4,4,4,4,4,4,4,4,8")]) (define_insn "*movsf_softfloat" - [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,r") - (match_operand:SF 1 "input_operand" "r,m,r,I,L,R,G,Fn"))] + [(set (match_operand:SF 0 "nonimmediate_operand" "=r,cl,q,r,r,m,r,r,r,r,r") + (match_operand:SF 1 "input_operand" "r,r,r,h,m,r,I,L,R,G,Fn"))] "(gpc_reg_operand (operands[0], SFmode) - || gpc_reg_operand (operands[1], SFmode)) && TARGET_SOFT_FLOAT" + || gpc_reg_operand (operands[1], SFmode)) + && (TARGET_SOFT_FLOAT || !TARGET_FPRS)" "@ mr %0,%1 + mt%0 %1 + mt%0 %1 + mf%1 %0 {l%U1%X1|lwz%U1%X1} %0,%1 {st%U0%X0|stw%U0%X0} %1,%0 {lil|li} %0,%1 @@ -7902,8 +8507,8 @@ {cal|la} %0,%a1 # #" - [(set_attr "type" "*,load,store,*,*,*,*,*") - (set_attr "length" "4,4,4,4,4,4,4,8")]) + [(set_attr "type" "*,mtjmpr,*,*,load,store,*,*,*,*,*") + (set_attr "length" "4,4,4,4,4,4,4,4,4,4,8")]) (define_expand "movdf" @@ -7933,7 +8538,7 @@ operands[4] = (value & 0x80000000) ? constm1_rtx : const0_rtx; #else operands[4] = GEN_INT (value >> 32); - operands[1] = GEN_INT ((value & 0x7fffffff) - (value & 0x80000000)); + operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); #endif }") @@ -7958,8 +8563,8 @@ operands[2] = operand_subword (operands[0], endian, 0, DFmode); operands[3] = operand_subword (operands[0], 1 - endian, 0, DFmode); - operands[4] = GEN_INT (trunc_int_for_mode (l[endian], SImode)); - operands[5] = GEN_INT (trunc_int_for_mode (l[1 - endian], SImode)); + operands[4] = gen_int_mode (l[endian], SImode); + operands[5] = gen_int_mode (l[1 - endian], SImode); }") (define_split @@ -7984,10 +8589,10 @@ operands[2] = gen_lowpart (DImode, operands[0]); /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */ #if HOST_BITS_PER_WIDE_INT >= 64 - val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32 | - ((HOST_WIDE_INT)(unsigned long)l[1 - endian])); + val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32 + | ((HOST_WIDE_INT)(unsigned long)l[1 - endian])); - operands[3] = immed_double_const (val, -(val < 0), DImode); + operands[3] = gen_int_mode (val, DImode); #else operands[3] = immed_double_const (l[1 - endian], l[endian], DImode); #endif @@ -8000,9 +8605,9 @@ ;; 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,!r,!r,!r,f,f,m") - (match_operand:DF 1 "input_operand" "r,m,r,G,H,F,f,m,f"))] - "! TARGET_POWERPC64 && TARGET_HARD_FLOAT + [(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"))] + "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && (gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode))" "* @@ -8078,24 +8683,24 @@ return \"\"; } case 3: + return \"fmr %0,%1\"; case 4: + return \"lfd%U1%X1 %0,%1\"; case 5: - return \"#\"; + return \"stfd%U0%X0 %1,%0\"; case 6: - return \"fmr %0,%1\"; case 7: - return \"lfd%U1%X1 %0,%1\"; case 8: - return \"stfd%U0%X0 %1,%0\"; + return \"#\"; } }" - [(set_attr "type" "*,load,store,*,*,*,fp,fpload,fpstore") - (set_attr "length" "8,16,16,8,12,16,*,*,*")]) + [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*,*") + (set_attr "length" "8,16,16,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_SOFT_FLOAT + "! TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS) && (gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode))" "* @@ -8134,50 +8739,56 @@ (set_attr "length" "8,8,8,8,12,16")]) (define_insn "*movdf_hardfloat64" - [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,!r,!r,!r,f,f,m") - (match_operand:DF 1 "input_operand" "r,m,r,G,H,F,f,m,f"))] - "TARGET_POWERPC64 && TARGET_HARD_FLOAT + [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,f,f,m,!cl,!r,!r,!r,!r") + (match_operand:DF 1 "input_operand" "r,m,r,f,m,f,r,h,G,H,F"))] + "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && (gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode))" "@ mr %0,%1 ld%U1%X1 %0,%1 std%U0%X0 %1,%0 - # - # - # fmr %0,%1 lfd%U1%X1 %0,%1 - stfd%U0%X0 %1,%0" - [(set_attr "type" "*,load,store,*,*,*,fp,fpload,fpstore") - (set_attr "length" "4,4,4,8,12,16,4,4,4")]) + stfd%U0%X0 %1,%0 + mt%0 %1 + mf%1 %0 + # + # + #" + [(set_attr "type" "*,load,store,fp,fpload,fpstore,mtjmpr,*,*,*,*") + (set_attr "length" "4,4,4,4,4,4,4,4,8,12,16")]) (define_insn "*movdf_softfloat64" - [(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_SOFT_FLOAT + [(set (match_operand:DF 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r") + (match_operand:DF 1 "input_operand" "r,r,h,m,r,G,H,F"))] + "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS) && (gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode))" "@ mr %0,%1 + mt%0 %1 + mf%1 %0 ld%U1%X1 %0,%1 std%U0%X0 %1,%0 # # #" - [(set_attr "type" "*,load,store,*,*,*") - (set_attr "length" "*,*,*,8,12,16")]) + [(set_attr "type" "*,*,*,load,store,*,*,*") + (set_attr "length" "4,4,4,4,4,8,12,16")]) (define_expand "movtf" [(set (match_operand:TF 0 "general_operand" "") (match_operand:TF 1 "any_operand" ""))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" + "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_LONG_DOUBLE_128" "{ rs6000_emit_move (operands[0], operands[1], TFmode); DONE; }") (define_insn "*movtf_internal" [(set (match_operand:TF 0 "nonimmediate_operand" "=f,f,m,!r,!r,!r") (match_operand:TF 1 "input_operand" "f,m,f,G,H,F"))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128 + "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_LONG_DOUBLE_128 && (gpc_reg_operand (operands[0], TFmode) || gpc_reg_operand (operands[1], TFmode))" "* @@ -8195,9 +8806,9 @@ else return \"fmr %0,%1\;fmr %L0,%L1\"; case 1: - return \"lfd %0,%1\;lfd %L0,%L1\"; + return \"lfd %0,%1\;lfd %L0,%Y1\"; case 2: - return \"stfd %1,%0\;stfd %L1,%L0\"; + return \"stfd %1,%0\;stfd %L1,%Y0\"; case 3: case 4: case 5: @@ -8209,104 +8820,185 @@ (define_split [(set (match_operand:TF 0 "gpc_reg_operand" "") - (match_operand:TF 1 "const_double_operand" ""))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" - [(set (match_dup 3) (match_dup 1)) - (set (match_dup 0) - (float_extend:TF (match_dup 3)))] + (match_operand:TF 1 "easy_fp_constant" ""))] + "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) + && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_POWERPC64 + && TARGET_LONG_DOUBLE_128 && reload_completed + && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) + || (GET_CODE (operands[0]) == SUBREG + && GET_CODE (SUBREG_REG (operands[0])) == REG + && REGNO (SUBREG_REG (operands[0])) <= 31))" + [(set (match_dup 2) (match_dup 6)) + (set (match_dup 3) (match_dup 7)) + (set (match_dup 4) (match_dup 8)) + (set (match_dup 5) (match_dup 9))] " { - operands[2] = operand_subword (operands[1], 0, 0, DFmode); - operands[3] = gen_reg_rtx (DFmode); + long l[4]; + REAL_VALUE_TYPE rv; + + REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); + REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, l); + + operands[2] = operand_subword (operands[0], 0, 0, TFmode); + operands[3] = operand_subword (operands[0], 1, 0, TFmode); + operands[4] = operand_subword (operands[0], 2, 0, TFmode); + operands[5] = operand_subword (operands[0], 3, 0, TFmode); + operands[6] = gen_int_mode (l[0], SImode); + operands[7] = gen_int_mode (l[1], SImode); + operands[8] = gen_int_mode (l[2], SImode); + operands[9] = gen_int_mode (l[3], SImode); }") -(define_insn_and_split "extenddftf2" - [(set (match_operand:TF 0 "gpc_reg_operand" "=f") - (float_extend:TF (match_operand:DF 1 "gpc_reg_operand" "f")))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" - "#" - "" - [(set (match_dup 2) (match_dup 3))] +(define_split + [(set (match_operand:TF 0 "gpc_reg_operand" "") + (match_operand:TF 1 "easy_fp_constant" ""))] + "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 + && TARGET_LONG_DOUBLE_128 && reload_completed + && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) + || (GET_CODE (operands[0]) == SUBREG + && GET_CODE (SUBREG_REG (operands[0])) == REG + && REGNO (SUBREG_REG (operands[0])) <= 31))" + [(set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 5))] " { - operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0] + 1)); - operands[3] = CONST0_RTX (DFmode); + long l[4]; + REAL_VALUE_TYPE rv; + HOST_WIDE_INT val; + + REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); + REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, l); + + operands[2] = gen_lowpart (DImode, operands[0]); + operands[3] = gen_highpart (DImode, operands[0]); +#if HOST_BITS_PER_WIDE_INT >= 64 + val = ((HOST_WIDE_INT)(unsigned long)l[0] << 32 + | ((HOST_WIDE_INT)(unsigned long)l[1])); + operands[4] = gen_int_mode (val, DImode); + + val = ((HOST_WIDE_INT)(unsigned long)l[2] << 32 + | ((HOST_WIDE_INT)(unsigned long)l[3])); + operands[5] = gen_int_mode (val, DImode); +#else + operands[4] = immed_double_const (l[1], l[0], DImode); + operands[5] = immed_double_const (l[3], l[2], DImode); +#endif }") -(define_insn_and_split "extendsftf2" +(define_insn "extenddftf2" + [(set (match_operand:TF 0 "gpc_reg_operand" "=f") + (float_extend:TF (match_operand:DF 1 "gpc_reg_operand" "f")))] + "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_LONG_DOUBLE_128" + "* +{ + if (REGNO (operands[0]) == REGNO (operands[1])) + return \"fsub %L0,%L0,%L0\"; + else + return \"fmr %0,%1\;fsub %L0,%L0,%L0\"; +}" + [(set_attr "type" "fp")]) + +(define_insn "extendsftf2" [(set (match_operand:TF 0 "gpc_reg_operand" "=f") (float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "f")))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" - "#" - "" - [(set (match_dup 2) (match_dup 3))] - " + "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_LONG_DOUBLE_128" + "* { - operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0] + 1)); - operands[3] = CONST0_RTX (SFmode); -}") + if (REGNO (operands[0]) == REGNO (operands[1])) + return \"fsub %L0,%L0,%L0\"; + else + return \"fmr %0,%1\;fsub %L0,%L0,%L0\"; +}" + [(set_attr "type" "fp")]) (define_insn "trunctfdf2" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "f")))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" + "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_LONG_DOUBLE_128" "fadd %0,%1,%L1" [(set_attr "type" "fp") (set_attr "length" "8")]) (define_insn_and_split "trunctfsf2" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") - (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "f")))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" + (float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "f"))) + (clobber (match_scratch:DF 2 "=f"))] + "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT + && TARGET_FPRS && TARGET_LONG_DOUBLE_128" "#" - "" + "&& reload_completed" [(set (match_dup 2) (float_truncate:DF (match_dup 1))) (set (match_dup 0) (float_truncate:SF (match_dup 2)))] - " -{ - operands[2] = gen_reg_rtx (DFmode); -}") + "") -(define_expand "floatditf2" +(define_insn_and_split "floatditf2" + [(set (match_operand:TF 0 "gpc_reg_operand" "=f") + (float:TF (match_operand:DI 1 "gpc_reg_operand" "*f"))) + (clobber (match_scratch:DF 2 "=f"))] + "DEFAULT_ABI == ABI_AIX && TARGET_POWERPC64 + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" + "#" + "&& reload_completed" [(set (match_dup 2) - (float:DF (match_operand:DI 1 "gpc_reg_operand" ""))) - (set (match_operand:TF 0 "gpc_reg_operand" "") + (float:DF (match_dup 1))) + (set (match_dup 0) (float_extend:TF (match_dup 2)))] - "DEFAULT_ABI == ABI_AIX && TARGET_POWERPC64 - && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" - "{ operands[2] = gen_reg_rtx (DFmode); }") + "") -(define_expand "floatsitf2" +(define_insn_and_split "floatsitf2" + [(set (match_operand:TF 0 "gpc_reg_operand" "=f") + (float:TF (match_operand:SI 1 "gpc_reg_operand" "r"))) + (clobber (match_scratch:DF 2 "=f"))] + "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_LONG_DOUBLE_128" + "#" + "&& reload_completed" [(set (match_dup 2) - (float:DF (match_operand:SI 1 "gpc_reg_operand" ""))) - (set (match_operand:TF 0 "gpc_reg_operand" "") + (float:DF (match_dup 1))) + (set (match_dup 0) (float_extend:TF (match_dup 2)))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" - "{ operands[2] = gen_reg_rtx (DFmode); }") + "") -(define_expand "fix_trunctfdi2" - [(set (match_dup 2) - (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" ""))) - (set (match_operand:DI 0 "gpc_reg_operand" "") - (fix:SI (match_dup 2)))] +(define_insn_and_split "fix_trunctfdi2" + [(set (match_operand:DI 0 "gpc_reg_operand" "=*f") + (fix:DI (match_operand:TF 1 "gpc_reg_operand" "f"))) + (clobber (match_scratch:DF 2 "=f"))] "DEFAULT_ABI == ABI_AIX && TARGET_POWERPC64 - && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" - "{ operands[2] = gen_reg_rtx (DFmode); }") + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" + "#" + "&& reload_completed" + [(set (match_dup 2) + (float_truncate:DF (match_dup 1))) + (set (match_dup 0) + (fix:DI (match_dup 2)))] + "") -(define_expand "fix_trunctfsi2" +(define_insn_and_split "fix_trunctfsi2" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (fix:SI (match_operand:TF 1 "gpc_reg_operand" "f"))) + (clobber (match_scratch:DF 2 "=f"))] + "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_LONG_DOUBLE_128" + "#" + "&& reload_completed" [(set (match_dup 2) - (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" ""))) - (set (match_operand:SI 0 "gpc_reg_operand" "") + (float_truncate:DF (match_dup 1))) + (set (match_dup 0) (fix:SI (match_dup 2)))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" - "{ operands[2] = gen_reg_rtx (DFmode); }") + "") (define_insn "negtf2" [(set (match_operand:TF 0 "gpc_reg_operand" "=f") (neg:TF (match_operand:TF 1 "gpc_reg_operand" "f")))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" + "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_LONG_DOUBLE_128" "* { if (REGNO (operands[0]) == REGNO (operands[1]) + 1) @@ -8320,7 +9012,8 @@ (define_insn "abstf2" [(set (match_operand:TF 0 "gpc_reg_operand" "=f") (abs:TF (match_operand:TF 1 "gpc_reg_operand" "f")))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" + "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_LONG_DOUBLE_128" "* { if (REGNO (operands[0]) == REGNO (operands[1]) + 1) @@ -8334,7 +9027,8 @@ (define_insn "" [(set (match_operand:TF 0 "gpc_reg_operand" "=f") (neg:TF (abs:TF (match_operand:TF 1 "gpc_reg_operand" "f"))))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" + "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_LONG_DOUBLE_128" "* { if (REGNO (operands[0]) == REGNO (operands[1]) + 1) @@ -8400,7 +9094,7 @@ } }" [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*,*,*,*") - (set_attr "length" "8,8,8,*,*,*,8,12,8,12,16")]) + (set_attr "length" "8,8,8,4,4,4,8,12,8,12,16")]) (define_split [(set (match_operand:DI 0 "gpc_reg_operand" "") @@ -8419,7 +9113,7 @@ operands[4] = (value & 0x80000000) ? constm1_rtx : const0_rtx; #else operands[4] = GEN_INT (value >> 32); - operands[1] = GEN_INT ((value & 0x7fffffff) - (value & 0x80000000)); + operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); #endif }") @@ -8439,8 +9133,34 @@ operands[5] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); }") +(define_split + [(set (match_operand:TI 0 "gpc_reg_operand" "") + (match_operand:TI 1 "const_double_operand" ""))] + "TARGET_POWERPC64" + [(set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 5))] + " +{ + operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0, + TImode); + operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0, + TImode); + if (GET_CODE (operands[1]) == CONST_DOUBLE) + { + operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1])); + operands[5] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); + } + else if (GET_CODE (operands[1]) == CONST_INT) + { + operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0)); + operands[5] = operands[1]; + } + else + FAIL; +}") + (define_insn "*movdi_internal64" - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,f,f,m,r,*h,*h") + [(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"))] "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], DImode) @@ -8458,7 +9178,7 @@ stfd%U0%X0 %1,%0 mf%1 %0 mt%0 %1 - cror 0,0,0" + {cror 0,0,0|nop}" [(set_attr "type" "*,load,store,*,*,*,*,fp,fpload,fpstore,*,mtjmpr,*") (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4")]) @@ -8615,12 +9335,11 @@ } }" [(set_attr "type" "store,store,*,load,load") - (set_attr "length" "*,16,16,*,16")]) + (set_attr "length" "4,16,16,4,16")]) (define_insn "*movti_string" - [(set (match_operand:TI 0 "reg_or_mem_operand" "=m,????r,????r") - (match_operand:TI 1 "reg_or_mem_operand" "r,r,m")) - (clobber (match_scratch:SI 2 "=X,X,X"))] + [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r") + (match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))] "TARGET_STRING && ! TARGET_POWER && ! TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))" "* @@ -8631,9 +9350,10 @@ abort (); case 0: - return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\"; - + return \"{stsi|stswi} %1,%P0,16\"; case 1: + return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\"; + case 2: /* Normally copy registers with lowest numbered register copied first. But copy in the other order if the first register of the output is the second, third, or fourth register in the input. */ @@ -8642,7 +9362,13 @@ return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\"; else return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\"; - case 2: + case 3: + /* If the address is not used in the output, we can use lsi. Otherwise, + fall through to generating four loads. */ + if (! reg_overlap_mentioned_p (operands[0], operands[1])) + return \"{lsi|lswi} %0,%P1,16\"; + /* ... fall through ... */ + case 4: /* If the address register is the same as the register for the lowest- addressed word, load it last. Similarly for the next two words. Otherwise load lowest address to highest. */ @@ -8659,8 +9385,8 @@ return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\"; } }" - [(set_attr "type" "store,*,load") - (set_attr "length" "16,16,16")]) + [(set_attr "type" "store,store,*,load,load") + (set_attr "length" "4,16,16,4,16")]) (define_insn "*movti_ppc64" [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m") @@ -8731,7 +9457,7 @@ for (i = 0; i < count; i++) XVECEXP (operands[3], 0, i) = gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, regno + i), - adjust_address (op1, SImode, i * 4)); + adjust_address_nv (op1, SImode, i * 4)); }") (define_insn "*ldmsi8" @@ -8881,14 +9607,14 @@ op0 = replace_equiv_address (operands[0], to); XVECEXP (operands[3], 0, 0) - = gen_rtx_SET (VOIDmode, adjust_address (op0, SImode, 0), operands[1]); + = gen_rtx_SET (VOIDmode, adjust_address_nv (op0, SImode, 0), operands[1]); XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)); for (i = 1; i < count; i++) XVECEXP (operands[3], 0, i + 1) = gen_rtx_SET (VOIDmode, - adjust_address (op0, SImode, i * 4), + adjust_address_nv (op0, SImode, i * 4), gen_rtx_REG (SImode, regno + i)); }") @@ -9426,7 +10152,7 @@ (match_operand:SI 2 "reg_or_short_operand" "r,I")))) (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_HARD_FLOAT && TARGET_UPDATE" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE" "@ lfsux %3,%0,%2 lfsu %3,%2(%0)" @@ -9438,7 +10164,7 @@ (match_operand:SF 3 "gpc_reg_operand" "f,f")) (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_HARD_FLOAT && TARGET_UPDATE" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE" "@ stfsux %3,%0,%2 stfsu %3,%2(%0)" @@ -9450,7 +10176,7 @@ (match_operand:SI 2 "reg_or_short_operand" "r,I")))) (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_SOFT_FLOAT && TARGET_UPDATE" + "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE" "@ {lux|lwzux} %3,%0,%2 {lu|lwzu} %3,%2(%0)" @@ -9462,7 +10188,7 @@ (match_operand:SF 3 "gpc_reg_operand" "r,r")) (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_SOFT_FLOAT && TARGET_UPDATE" + "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE" "@ {stux|stwux} %3,%0,%2 {stu|stwu} %3,%2(%0)" @@ -9474,7 +10200,7 @@ (match_operand:SI 2 "reg_or_short_operand" "r,I")))) (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_HARD_FLOAT && TARGET_UPDATE" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE" "@ lfdux %3,%0,%2 lfdu %3,%2(%0)" @@ -9486,7 +10212,7 @@ (match_operand:DF 3 "gpc_reg_operand" "f,f")) (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") (plus:SI (match_dup 1) (match_dup 2)))] - "TARGET_HARD_FLOAT && TARGET_UPDATE" + "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE" "@ stfdux %3,%0,%2 stfdu %3,%2(%0)" @@ -9500,7 +10226,7 @@ (set (match_operand:DF 2 "gpc_reg_operand" "=f") (match_operand:DF 3 "memory_operand" ""))] "TARGET_POWER2 - && TARGET_HARD_FLOAT + && TARGET_HARD_FLOAT && TARGET_FPRS && registers_ok_for_quad_peep (operands[0], operands[2]) && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3]) && addrs_ok_for_quad_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))" @@ -9512,7 +10238,7 @@ (set (match_operand:DF 2 "memory_operand" "") (match_operand:DF 3 "gpc_reg_operand" "f"))] "TARGET_POWER2 - && TARGET_HARD_FLOAT + && TARGET_HARD_FLOAT && TARGET_FPRS && registers_ok_for_quad_peep (operands[1], operands[3]) && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2]) && addrs_ok_for_quad_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))" @@ -9697,7 +10423,7 @@ (match_operand:SI 1 "immediate_operand" "s")) (unspec [(match_dup 1)] 7)] "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2" - "bl %1\\n%1:" + "bcl 20,31,%1\\n%1:" [(set_attr "type" "branch") (set_attr "length" "4")]) @@ -9706,13 +10432,13 @@ (match_operand:SI 1 "immediate_operand" "s")) (unspec [(match_dup 1) (match_operand 2 "immediate_operand" "s")] 6)] "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2" - "bl %1\\n\\t.long %2-%1+4\\n%1:" + "bcl 20,31,%1\\n\\t.long %2-%1+4\\n%1:" [(set_attr "type" "branch") (set_attr "length" "8")]) (define_insn "load_toc_v4_PIC_2" - [(set (match_operand:SI 0 "register_operand" "=r") - (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "b") + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") (minus:SI (match_operand:SI 2 "immediate_operand" "s") (match_operand:SI 3 "immediate_operand" "s")))))] "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2" @@ -9721,30 +10447,53 @@ (define_insn "load_macho_picbase" [(set (match_operand:SI 0 "register_operand" "=l") - (unspec:SI [(const_int 0)] 15))] + (unspec:SI [(match_operand:SI 1 "immediate_operand" "s")] 15))] "(DEFAULT_ABI == ABI_DARWIN) && flag_pic" - "* -{ -#if TARGET_MACHO - char *picbase = machopic_function_base_name (); - operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (picbase, -1)); -#endif - return \"bcl 20,31,%1\\n%1:\"; -}" + "bcl 20,31,%1\\n%1:" [(set_attr "type" "branch") (set_attr "length" "4")]) +(define_insn "macho_correct_pic" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (plus:SI (match_operand:SI 1 "gpc_reg_operand" "=r") + (unspec:SI [(match_operand:SI 2 "immediate_operand" "s") + (match_operand:SI 3 "immediate_operand" "s")] + 16)))] + "DEFAULT_ABI == ABI_DARWIN" + "addis %0,%1,ha16(%2-%3)\n\taddi %1,%1,lo16(%2-%3)" + [(set_attr "length" "8")]) + ;; If the TOC is shared over a translation unit, as happens with all ;; the kinds of PIC that we support, we need to restore the TOC ;; pointer only when jumping over units of translation. +;; On Darwin, we need to reload the picbase. (define_expand "builtin_setjmp_receiver" [(use (label_ref (match_operand 0 "" "")))] "(DEFAULT_ABI == ABI_V4 && flag_pic == 1) - || (TARGET_TOC && TARGET_MINIMAL_TOC)" + || (TARGET_TOC && TARGET_MINIMAL_TOC) + || (DEFAULT_ABI == ABI_DARWIN && flag_pic)" " { - rs6000_emit_load_toc_table (FALSE); +#if TARGET_MACHO + if (DEFAULT_ABI == ABI_DARWIN) + { + char *picbase = machopic_function_base_name (); + rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (picbase, -1)); + rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM); + rtx tmplabrtx; + char tmplab[20]; + + ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\", + CODE_LABEL_NUMBER (operands[0])); + tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (tmplab, -1)); + + emit_insn (gen_load_macho_picbase (picreg, tmplabrtx)); + emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx)); + } + else +#endif + rs6000_emit_load_toc_table (FALSE); DONE; }") @@ -9943,7 +10692,7 @@ }") ;; Call to function in current module. No TOC pointer reload needed. -;; Operand2 is non-zero if we are using the V.4 calling sequence and +;; Operand2 is nonzero if we are using the V.4 calling sequence and ;; either the function was not prototyped, or it was prototyped as a ;; variable argument function. It is > 0 if FP registers were passed ;; and < 0 if they were not. @@ -10029,7 +10778,7 @@ ;; Call to function which may be in another module. Restore the TOC ;; pointer (r2) after the call unless this is System V. -;; Operand2 is non-zero if we are using the V.4 calling sequence and +;; Operand2 is nonzero if we are using the V.4 calling sequence and ;; either the function was not prototyped, or it was prototyped as a ;; variable argument function. It is > 0 if FP registers were passed ;; and < 0 if they were not. @@ -10048,7 +10797,7 @@ (set_attr "length" "8")]) (define_insn "*call_nonlocal_aix32" - [(call (mem:SI (match_operand:SI 0 "call_operand" "s")) + [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s")) (match_operand 1 "" "g")) (use (match_operand:SI 2 "immediate_operand" "O")) (clobber (match_scratch:SI 3 "=l"))] @@ -10073,7 +10822,7 @@ (set_attr "length" "8")]) (define_insn "*call_nonlocal_aix64" - [(call (mem:SI (match_operand:DI 0 "call_operand" "s")) + [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s")) (match_operand 1 "" "g")) (use (match_operand:SI 2 "immediate_operand" "O")) (clobber (match_scratch:SI 3 "=l"))] @@ -10100,7 +10849,7 @@ (define_insn "*call_value_nonlocal_aix32" [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:SI 1 "call_operand" "s")) + (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s")) (match_operand 2 "" "g"))) (use (match_operand:SI 3 "immediate_operand" "O")) (clobber (match_scratch:SI 4 "=l"))] @@ -10127,7 +10876,7 @@ (define_insn "*call_value_nonlocal_aix64" [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:DI 1 "call_operand" "s")) + (call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s")) (match_operand 2 "" "g"))) (use (match_operand:SI 3 "immediate_operand" "O")) (clobber (match_scratch:SI 4 "=l"))] @@ -10144,68 +10893,89 @@ ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument ;; which indicates how to set cr1 -(define_insn "*call_nonlocal_sysv" - [(call (mem:SI (match_operand:SI 0 "call_operand" "cl,cl,s,s")) - (match_operand 1 "" "g,g,g,g")) - (use (match_operand:SI 2 "immediate_operand" "O,n,O,n")) - (clobber (match_scratch:SI 3 "=l,l,l,l"))] +(define_insn "*call_indirect_nonlocal_sysv" + [(call (mem:SI (match_operand:SI 0 "register_operand" "cl,cl")) + (match_operand 1 "" "g,g")) + (use (match_operand:SI 2 "immediate_operand" "O,n")) + (clobber (match_scratch:SI 3 "=l,l"))] "DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_DARWIN" - "* { if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) - output_asm_insn (\"crxor 6,6,6\", operands); + output_asm_insn ("crxor 6,6,6", operands); else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn (\"creqv 6,6,6\", operands); + output_asm_insn ("creqv 6,6,6", operands); - switch (which_alternative) - { - default: - abort (); - case 0: - case 1: - return \"b%T0l\"; - case 2: - case 3: - return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@plt\" : \"bl %z0\"; - } -}" - [(set_attr "type" "jmpreg,jmpreg,branch,branch") - (set_attr "length" "4,8,4,8")]) + return "b%T0l"; +} + [(set_attr "type" "jmpreg,jmpreg") + (set_attr "length" "4,8")]) -(define_insn "*call_value_nonlocal_sysv" +(define_insn "*call_nonlocal_sysv" + [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s,s")) + (match_operand 1 "" "g,g")) + (use (match_operand:SI 2 "immediate_operand" "O,n")) + (clobber (match_scratch:SI 3 "=l,l"))] + "(DEFAULT_ABI == ABI_AIX_NODESC + || DEFAULT_ABI == ABI_V4 + || DEFAULT_ABI == ABI_DARWIN) + && (INTVAL (operands[2]) & CALL_LONG) == 0" +{ + if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) + output_asm_insn ("crxor 6,6,6", operands); + + else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) + output_asm_insn ("creqv 6,6,6", operands); + + return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@plt" : "bl %z0"; +} + [(set_attr "type" "branch,branch") + (set_attr "length" "4,8")]) + +(define_insn "*call_value_indirect_nonlocal_sysv" [(set (match_operand 0 "" "") - (call (mem:SI (match_operand:SI 1 "call_operand" "cl,cl,s,s")) - (match_operand 2 "" "g,g,g,g"))) - (use (match_operand:SI 3 "immediate_operand" "O,n,O,n")) - (clobber (match_scratch:SI 4 "=l,l,l,l"))] + (call (mem:SI (match_operand:SI 1 "register_operand" "cl,cl")) + (match_operand 2 "" "g,g"))) + (use (match_operand:SI 3 "immediate_operand" "O,n")) + (clobber (match_scratch:SI 4 "=l,l"))] "DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_DARWIN" - "* { if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) - output_asm_insn (\"crxor 6,6,6\", operands); + output_asm_insn ("crxor 6,6,6", operands); else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) - output_asm_insn (\"creqv 6,6,6\", operands); + output_asm_insn ("creqv 6,6,6", operands); - switch (which_alternative) - { - default: - abort (); - case 0: - case 1: - return \"b%T1l\"; - case 2: - case 3: - return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@plt\" : \"bl %z1\"; - } -}" - [(set_attr "type" "jmpreg,jmpreg,branch,branch") - (set_attr "length" "4,8,4,8")]) + return "b%T1l"; +} + [(set_attr "type" "jmpreg,jmpreg") + (set_attr "length" "4,8")]) + +(define_insn "*call_value_nonlocal_sysv" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s,s")) + (match_operand 2 "" "g,g"))) + (use (match_operand:SI 3 "immediate_operand" "O,n")) + (clobber (match_scratch:SI 4 "=l,l"))] + "(DEFAULT_ABI == ABI_AIX_NODESC + || DEFAULT_ABI == ABI_V4 + || DEFAULT_ABI == ABI_DARWIN) + && (INTVAL (operands[3]) & CALL_LONG) == 0" +{ + if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) + output_asm_insn ("crxor 6,6,6", operands); + + else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) + output_asm_insn ("creqv 6,6,6", operands); + + return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@plt" : "bl %z1"; +} + [(set_attr "type" "branch,branch") + (set_attr "length" "4,8")]) ;; Call subroutine returning any type. (define_expand "untyped_call" @@ -10235,6 +11005,247 @@ DONE; }") +;; sibling call patterns +(define_expand "sibcall" + [(parallel [(call (mem:SI (match_operand 0 "address_operand" "")) + (match_operand 1 "" "")) + (use (match_operand 2 "" "")) + (use (scratch:SI)) + (return)])] + "" + " +{ +#if TARGET_MACHO + if (flag_pic) + operands[0] = machopic_indirect_call_target (operands[0]); +#endif + + if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != CONST_INT) + abort (); + + operands[0] = XEXP (operands[0], 0); + +}") + +;; this and similar patterns must be marked as using LR, otherwise +;; dataflow will try to delete the store into it. This is true +;; even when the actual reg to jump to is in CTR, when LR was +;; saved and restored around the PIC-setting BCL. +(define_insn "*sibcall_local32" + [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s")) + (match_operand 1 "" "g,g")) + (use (match_operand:SI 2 "immediate_operand" "O,n")) + (use (match_scratch:SI 3 "=l,l")) + (return)] + "(INTVAL (operands[2]) & CALL_LONG) == 0" + "* +{ + if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) + output_asm_insn (\"crxor 6,6,6\", operands); + + else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) + output_asm_insn (\"creqv 6,6,6\", operands); + + return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\"; +}" + [(set_attr "type" "branch") + (set_attr "length" "4,8")]) + +(define_insn "*sibcall_local64" + [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s")) + (match_operand 1 "" "g,g")) + (use (match_operand:SI 2 "immediate_operand" "O,n")) + (use (match_scratch:SI 3 "=l,l")) + (return)] + "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0" + "* +{ + if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) + output_asm_insn (\"crxor 6,6,6\", operands); + + else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) + output_asm_insn (\"creqv 6,6,6\", operands); + + return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\"; +}" + [(set_attr "type" "branch") + (set_attr "length" "4,8")]) + +(define_insn "*sibcall_value_local32" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s")) + (match_operand 2 "" "g,g"))) + (use (match_operand:SI 3 "immediate_operand" "O,n")) + (use (match_scratch:SI 4 "=l,l")) + (return)] + "(INTVAL (operands[3]) & CALL_LONG) == 0" + "* +{ + if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) + output_asm_insn (\"crxor 6,6,6\", operands); + + else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) + output_asm_insn (\"creqv 6,6,6\", operands); + + return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\"; +}" + [(set_attr "type" "branch") + (set_attr "length" "4,8")]) + + +(define_insn "*sibcall_value_local64" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s")) + (match_operand 2 "" "g,g"))) + (use (match_operand:SI 3 "immediate_operand" "O,n")) + (use (match_scratch:SI 4 "=l,l")) + (return)] + "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0" + "* +{ + if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) + output_asm_insn (\"crxor 6,6,6\", operands); + + else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) + output_asm_insn (\"creqv 6,6,6\", operands); + + return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\"; +}" + [(set_attr "type" "branch") + (set_attr "length" "4,8")]) + +(define_insn "*sibcall_nonlocal_aix32" + [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s")) + (match_operand 1 "" "g")) + (use (match_operand:SI 2 "immediate_operand" "O")) + (use (match_scratch:SI 3 "=l")) + (return)] + "TARGET_32BIT + && DEFAULT_ABI == ABI_AIX + && (INTVAL (operands[2]) & CALL_LONG) == 0" + "b %z0" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*sibcall_nonlocal_aix64" + [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s")) + (match_operand 1 "" "g")) + (use (match_operand:SI 2 "immediate_operand" "O")) + (use (match_scratch:SI 3 "=l")) + (return)] + "TARGET_64BIT + && DEFAULT_ABI == ABI_AIX + && (INTVAL (operands[2]) & CALL_LONG) == 0" + "b %z0" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*sibcall_value_nonlocal_aix32" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s")) + (match_operand 2 "" "g"))) + (use (match_operand:SI 3 "immediate_operand" "O")) + (use (match_scratch:SI 4 "=l")) + (return)] + "TARGET_32BIT + && DEFAULT_ABI == ABI_AIX + && (INTVAL (operands[3]) & CALL_LONG) == 0" + "b %z1" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*sibcall_value_nonlocal_aix64" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s")) + (match_operand 2 "" "g"))) + (use (match_operand:SI 3 "immediate_operand" "O")) + (use (match_scratch:SI 4 "=l")) + (return)] + "TARGET_64BIT + && DEFAULT_ABI == ABI_AIX + && (INTVAL (operands[3]) & CALL_LONG) == 0" + "b %z1" + [(set_attr "type" "branch") + (set_attr "length" "4")]) + +(define_insn "*sibcall_nonlocal_sysv" + [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s,s")) + (match_operand 1 "" "")) + (use (match_operand 2 "immediate_operand" "O,n")) + (use (match_scratch:SI 3 "=l,l")) + (return)] + "(DEFAULT_ABI == ABI_DARWIN + || DEFAULT_ABI == ABI_V4 + || DEFAULT_ABI == ABI_AIX_NODESC) + && (INTVAL (operands[2]) & CALL_LONG) == 0" + "* +{ + if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) + output_asm_insn (\"crxor 6,6,6\", operands); + + else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) + output_asm_insn (\"creqv 6,6,6\", operands); + + return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@plt\" : \"b %z0\"; +}" + [(set_attr "type" "branch,branch") + (set_attr "length" "4,8")]) + +(define_expand "sibcall_value" + [(parallel [(set (match_operand 0 "register_operand" "") + (call (mem:SI (match_operand 1 "address_operand" "")) + (match_operand 2 "" ""))) + (use (match_operand 3 "" "")) + (use (scratch:SI)) + (return)])] + "" + " +{ +#if TARGET_MACHO + if (flag_pic) + operands[1] = machopic_indirect_call_target (operands[1]); +#endif + + if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != CONST_INT) + abort (); + + operands[1] = XEXP (operands[1], 0); + +}") + +(define_insn "*sibcall_value_nonlocal_sysv" + [(set (match_operand 0 "" "") + (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s,s")) + (match_operand 2 "" ""))) + (use (match_operand:SI 3 "immediate_operand" "O,n")) + (use (match_scratch:SI 4 "=l,l")) + (return)] + "(DEFAULT_ABI == ABI_DARWIN + || DEFAULT_ABI == ABI_V4 + || DEFAULT_ABI == ABI_AIX_NODESC) + && (INTVAL (operands[3]) & CALL_LONG) == 0" + "* +{ + if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) + output_asm_insn (\"crxor 6,6,6\", operands); + + else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) + output_asm_insn (\"creqv 6,6,6\", operands); + + return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@plt\" : \"b %z1\"; +}" + [(set_attr "type" "branch,branch") + (set_attr "length" "4,8")]) + +(define_expand "sibcall_epilogue" + [(use (const_int 0))] + "TARGET_SCHED_PROLOG" + " +{ + rs6000_emit_epilogue (TRUE); + DONE; +}") + ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and ;; all of memory. This blocks insns from being moved across this point. @@ -10302,7 +11313,7 @@ (define_expand "cmpdf" [(set (cc0) (compare (match_operand:DF 0 "gpc_reg_operand" "") (match_operand:DF 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS" " { rs6000_compare_op0 = operands[0]; @@ -10314,7 +11325,8 @@ (define_expand "cmptf" [(set (cc0) (compare (match_operand:TF 0 "gpc_reg_operand" "") (match_operand:TF 1 "gpc_reg_operand" "")))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" + "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT + && TARGET_FPRS && TARGET_LONG_DOUBLE_128" " { rs6000_compare_op0 = operands[0]; @@ -10549,7 +11561,7 @@ with C to get the sign-extended value. */ HOST_WIDE_INT c = INTVAL (operands[2]); - HOST_WIDE_INT sextc = (c & 0x7fff) - (c & 0x8000); + HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000; HOST_WIDE_INT xorv = c ^ sextc; operands[4] = GEN_INT (xorv); @@ -10621,7 +11633,7 @@ [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") (compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "f") (match_operand:SF 2 "gpc_reg_operand" "f")))] - "TARGET_HARD_FLOAT" + "TARGET_HARD_FLOAT && TARGET_FPRS" "fcmpu %0,%1,%2" [(set_attr "type" "fpcompare")]) @@ -10629,7 +11641,7 @@ [(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_HARD_FLOAT && TARGET_FPRS" "fcmpu %0,%1,%2" [(set_attr "type" "fpcompare")]) @@ -10638,7 +11650,8 @@ [(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")))] - "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" + "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_LONG_DOUBLE_128" "fcmpu %0,%1,%2\;bne %0,$+4\;fcmpu %0,%L1,%L2" [(set_attr "type" "fpcompare") (set_attr "length" "12")]) @@ -10657,6 +11670,15 @@ (const_int 0)]))] "" "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1" + [(set_attr "type" "cr_logical") + (set_attr "length" "12")]) + +;; Same as above, but get the OV/ORDERED bit. +(define_insn "move_from_CR_ov_bit" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] 724))] + "TARGET_ISEL" + "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%t1,1" [(set_attr "length" "12")]) (define_insn "" @@ -10666,7 +11688,8 @@ (const_int 0)]))] "TARGET_POWERPC64" "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1" - [(set_attr "length" "12")]) + [(set_attr "type" "cr_logical") + (set_attr "length" "12")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") @@ -10722,7 +11745,8 @@ return \"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%4,%5,%5\"; }" - [(set_attr "length" "12")]) + [(set_attr "type" "cr_logical") + (set_attr "length" "12")]) (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") @@ -10735,7 +11759,7 @@ (set (match_operand:SI 4 "gpc_reg_operand" "=r,r") (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)]) (match_dup 3)))] - "! TARGET_POWERPC64" + "" "* { int is_bit = ccr_bit (operands[1], 1); @@ -10770,7 +11794,7 @@ (set (match_operand:SI 4 "gpc_reg_operand" "") (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)]) (match_dup 3)))] - "! TARGET_POWERPC64 && reload_completed" + "reload_completed" [(set (match_dup 4) (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)]) (match_dup 3))) @@ -10791,9 +11815,10 @@ (match_operator:SI 4 "scc_comparison_operator" [(match_operand 5 "cc_reg_operand" "y") (const_int 0)]))] - "REGNO (operands[2]) != REGNO (operands[5])" - "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1" - [(set_attr "length" "20")]) + "REGNO (operands[2]) != REGNO (operands[5])" + "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1" + [(set_attr "type" "cr_logical") + (set_attr "length" "20")]) (define_peephole [(set (match_operand:DI 0 "gpc_reg_operand" "=r") @@ -10804,9 +11829,10 @@ (match_operator:DI 4 "scc_comparison_operator" [(match_operand 5 "cc_reg_operand" "y") (const_int 0)]))] - "TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])" - "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1" - [(set_attr "length" "20")]) + "TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])" + "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1" + [(set_attr "type" "cr_logical") + (set_attr "length" "20")]) ;; There are some scc insns that can be done directly, without a compare. ;; These are faster because they don't involve the communications between @@ -11069,7 +12095,7 @@ (lshiftrt:SI (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r"))) (const_int 31))) (clobber (match_scratch:SI 2 "=&r"))] - "! TARGET_POWER && ! TARGET_POWERPC64" + "! TARGET_POWER && ! TARGET_POWERPC64 && !TARGET_ISEL" "{ai|addic} %2,%1,-1\;{sfe|subfe} %0,%2,%1" [(set_attr "length" "8")]) @@ -11134,9 +12160,9 @@ (clobber (match_scratch:SI 4 ""))] "! TARGET_POWERPC64 && reload_completed" [(parallel [(set (match_dup 3) - (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) - (const_int 31)) - (match_dup 2))) + (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) + (const_int 31)) + (match_dup 2))) (clobber (match_dup 4))]) (set (match_dup 0) (compare:CC (match_dup 3) @@ -13028,7 +14054,7 @@ "cc_reg_operand" "y") (const_int 0)]) (const_int 0)))] - "" + "!TARGET_SPE" "{crnor %E0,%j1,%j1|crnot %E0,%j1}" [(set_attr "type" "cr_logical")]) @@ -13282,7 +14308,7 @@ return \"bdz $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "4,12,16")]) (define_insn "*ctrsi_internal2" [(set (pc) @@ -13306,7 +14332,7 @@ return \"{bdn|bdnz} $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "4,12,16")]) (define_insn "*ctrdi_internal1" [(set (pc) @@ -13330,7 +14356,7 @@ return \"bdz $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "4,12,16")]) (define_insn "*ctrdi_internal2" [(set (pc) @@ -13354,7 +14380,7 @@ return \"{bdn|bdnz} $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "4,12,16")]) ;; Similar, but we can use GE since we have a REG_NONNEG. @@ -13380,7 +14406,7 @@ return \"bdz $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "4,12,16")]) (define_insn "*ctrsi_internal4" [(set (pc) @@ -13404,7 +14430,7 @@ return \"{bdn|bdnz} $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "4,12,16")]) (define_insn "*ctrdi_internal3" [(set (pc) @@ -13428,7 +14454,7 @@ return \"bdz $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "4,12,16")]) (define_insn "*ctrdi_internal4" [(set (pc) @@ -13452,7 +14478,7 @@ return \"{bdn|bdnz} $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "4,12,16")]) ;; Similar but use EQ @@ -13478,7 +14504,7 @@ return \"{bdn|bdnz} $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "4,12,16")]) (define_insn "*ctrsi_internal6" [(set (pc) @@ -13502,7 +14528,7 @@ return \"bdz $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "4,12,16")]) (define_insn "*ctrdi_internal5" [(set (pc) @@ -13526,7 +14552,7 @@ return \"{bdn|bdnz} $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "4,12,16")]) (define_insn "*ctrdi_internal6" [(set (pc) @@ -13550,7 +14576,7 @@ return \"bdz $+8\;b %l0\"; }" [(set_attr "type" "branch") - (set_attr "length" "*,12,16")]) + (set_attr "length" "4,12,16")]) ;; Now the splitters if we could not allocate the CTR register @@ -13712,7 +14738,8 @@ (unspec:SI [(reg:CC 68) (reg:CC 69) (reg:CC 70) (reg:CC 71) (reg:CC 72) (reg:CC 73) (reg:CC 74) (reg:CC 75)] 19))] "" - "mfcr %0") + "mfcr %0" + [(set_attr "type" "cr_logical")]) (define_insn "*stmw" [(match_parallel 0 "stmw_operation" @@ -13763,17 +14790,17 @@ ; faster; for instance, on the 601 and 750. (define_expand "movsi_to_cr_one" - [(set (match_operand:CC 0 "cc_reg_operand" "=y") - (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") - (match_dup 2)] 20))] - "" - "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));") + [(set (match_operand:CC 0 "cc_reg_operand" "=y") + (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") + (match_dup 2)] 20))] + "" + "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));") (define_insn "*movsi_to_cr" - [(match_parallel 0 "mtcrf_operation" - [(set (match_operand:CC 1 "cc_reg_operand" "=y") - (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r") - (match_operand 3 "immediate_operand" "n")] + [(match_parallel 0 "mtcrf_operation" + [(set (match_operand:CC 1 "cc_reg_operand" "=y") + (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r") + (match_operand 3 "immediate_operand" "n")] 20))])] "" "* @@ -13784,28 +14811,30 @@ mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1)); operands[4] = GEN_INT (mask); return \"mtcrf %4,%2\"; -}") +}" + [(set_attr "type" "cr_logical")]) (define_insn "" - [(set (match_operand:CC 0 "cc_reg_operand" "=y") - (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand 2 "immediate_operand" "n")] 20))] - "GET_CODE (operands[0]) == REG - && CR_REGNO_P (REGNO (operands[0])) - && GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))" - "mtcrf %R0,%1") + [(set (match_operand:CC 0 "cc_reg_operand" "=y") + (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand 2 "immediate_operand" "n")] 20))] + "GET_CODE (operands[0]) == REG + && CR_REGNO_P (REGNO (operands[0])) + && GET_CODE (operands[2]) == CONST_INT + && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))" + "mtcrf %R0,%1" + [(set_attr "type" "cr_logical")]) ; The load-multiple instructions have similar properties. ; Note that "load_multiple" is a name known to the machine-independent ; code that actually corresponds to the powerpc load-string. (define_insn "*lmw" - [(match_parallel 0 "lmw_operation" - [(set (match_operand:SI 1 "gpc_reg_operand" "=r") - (match_operand:SI 2 "memory_operand" "m"))])] - "TARGET_MULTIPLE" - "{lm|lmw} %1,%2") + [(match_parallel 0 "lmw_operation" + [(set (match_operand:SI 1 "gpc_reg_operand" "=r") + (match_operand:SI 2 "memory_operand" "m"))])] + "TARGET_MULTIPLE" + "{lm|lmw} %1,%2") (define_insn "*return_internal_si" [(return) @@ -13846,19 +14875,17 @@ ; This is used in compiling the unwind routines. (define_expand "eh_return" - [(use (match_operand 0 "general_operand" "")) - (use (match_operand 1 "general_operand" ""))] + [(use (match_operand 0 "general_operand" ""))] "" " { #if TARGET_AIX - rs6000_emit_eh_toc_restore (operands[0]); + rs6000_emit_eh_toc_restore (EH_RETURN_STACKADJ_RTX); #endif if (TARGET_32BIT) - emit_insn (gen_eh_set_lr_si (operands[1])); + emit_insn (gen_eh_set_lr_si (operands[0])); else - emit_insn (gen_eh_set_lr_di (operands[1])); - emit_move_insn (EH_RETURN_STACKADJ_RTX, operands[0]); + emit_insn (gen_eh_set_lr_di (operands[0])); DONE; }") @@ -13921,1850 +14948,6 @@ return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\"; }" [(set_attr "type" "load")]) - -;; AltiVec patterns - -;; Generic LVX load instruction. -(define_insn "altivec_lvx_4si" - [(set (match_operand:V4SI 0 "altivec_register_operand" "=v") - (match_operand:V4SI 1 "memory_operand" "m"))] - "TARGET_ALTIVEC" - "lvx %0,%y1" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_lvx_8hi" - [(set (match_operand:V8HI 0 "altivec_register_operand" "=v") - (match_operand:V8HI 1 "memory_operand" "m"))] - "TARGET_ALTIVEC" - "lvx %0,%y1" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_lvx_16qi" - [(set (match_operand:V16QI 0 "altivec_register_operand" "=v") - (match_operand:V16QI 1 "memory_operand" "m"))] - "TARGET_ALTIVEC" - "lvx %0,%y1" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_lvx_4sf" - [(set (match_operand:V4SF 0 "altivec_register_operand" "=v") - (match_operand:V4SF 1 "memory_operand" "m"))] - "TARGET_ALTIVEC" - "lvx %0,%y1" - [(set_attr "type" "vecload")]) - -;; Generic STVX store instruction. -(define_insn "altivec_stvx_4si" - [(set (match_operand:V4SI 0 "memory_operand" "=m") - (match_operand:V4SI 1 "altivec_register_operand" "v"))] - "TARGET_ALTIVEC" - "stvx %1,%y0" - [(set_attr "type" "vecstore")]) - -(define_insn "altivec_stvx_8hi" - [(set (match_operand:V8HI 0 "memory_operand" "=m") - (match_operand:V8HI 1 "altivec_register_operand" "v"))] - "TARGET_ALTIVEC" - "stvx %1,%y0" - [(set_attr "type" "vecstore")]) - -(define_insn "altivec_stvx_16qi" - [(set (match_operand:V16QI 0 "memory_operand" "=m") - (match_operand:V16QI 1 "altivec_register_operand" "v"))] - "TARGET_ALTIVEC" - "stvx %1,%y0" - [(set_attr "type" "vecstore")]) - -(define_insn "altivec_stvx_4sf" - [(set (match_operand:V4SF 0 "memory_operand" "=m") - (match_operand:V4SF 1 "altivec_register_operand" "v"))] - "TARGET_ALTIVEC" - "stvx %1,%y0" - [(set_attr "type" "vecstore")]) - -;; Vector move instructions. -(define_expand "movv4si" - [(set (match_operand:V4SI 0 "nonimmediate_operand" "") - (match_operand:V4SI 1 "any_operand" ""))] - "TARGET_ALTIVEC" - "{ rs6000_emit_move (operands[0], operands[1], V4SImode); DONE; }") - -(define_insn "*movv4si_internal" - [(set (match_operand:V4SI 0 "nonimmediate_operand" "=m,v,v,o,r,r") - (match_operand:V4SI 1 "input_operand" "v,m,v,r,o,r"))] - "TARGET_ALTIVEC" - "@ - stvx %1,%y0 - lvx %0,%y1 - vor %0,%1,%1 - stw%U0 %1,%0\;stw %L1,%L0\;stw %Y1,%Y0\;stw %Z1,%Z0 - lwz%U1 %0,%1\;lwz %L0,%L1\;lwz %Y0,%Y1\;lwz %Z0,%Z1 - mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1" - [(set_attr "type" "altivec") - (set_attr "length" "*,*,*,16,16,16")]) - -(define_expand "movv8hi" - [(set (match_operand:V8HI 0 "nonimmediate_operand" "") - (match_operand:V8HI 1 "any_operand" ""))] - "TARGET_ALTIVEC" - "{ rs6000_emit_move (operands[0], operands[1], V8HImode); DONE; }") - -(define_insn "*movv8hi_internal1" - [(set (match_operand:V8HI 0 "nonimmediate_operand" "=m,v,v,o,r,r") - (match_operand:V8HI 1 "input_operand" "v,m,v,r,o,r"))] - "TARGET_ALTIVEC" - "@ - stvx %1,%y0 - lvx %0,%y1 - vor %0,%1,%1 - stw%U0 %1,%0\;stw %L1,%L0\;stw %Y1,%Y0\;stw %Z1,%Z0 - lwz%U1 %0,%1\;lwz %L0,%L1\;lwz %Y0,%Y1\;lwz %Z0,%Z1 - mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1" - [(set_attr "type" "altivec") - (set_attr "length" "*,*,*,16,16,16")]) - -(define_expand "movv16qi" - [(set (match_operand:V16QI 0 "nonimmediate_operand" "") - (match_operand:V16QI 1 "any_operand" ""))] - "TARGET_ALTIVEC" - "{ rs6000_emit_move (operands[0], operands[1], V16QImode); DONE; }") - -(define_insn "*movv16qi_internal1" - [(set (match_operand:V16QI 0 "nonimmediate_operand" "=m,v,v,o,r,r") - (match_operand:V16QI 1 "input_operand" "v,m,v,r,o,r"))] - "TARGET_ALTIVEC" - "@ - stvx %1,%y0 - lvx %0,%y1 - vor %0,%1,%1 - stw%U0 %1,%0\;stw %L1,%L0\;stw %Y1,%Y0\;stw %Z1,%Z0 - lwz%U1 %0,%1\;lwz %L0,%L1\;lwz %Y0,%Y1\;lwz %Z0,%Z1 - mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1" - [(set_attr "type" "altivec") - (set_attr "length" "*,*,*,16,16,16")]) - -(define_expand "movv4sf" - [(set (match_operand:V4SF 0 "nonimmediate_operand" "") - (match_operand:V4SF 1 "any_operand" ""))] - "TARGET_ALTIVEC" - "{ rs6000_emit_move (operands[0], operands[1], V4SFmode); DONE; }") - -(define_insn "*movv4sf_internal1" - [(set (match_operand:V4SF 0 "nonimmediate_operand" "=m,v,v,o,r,r") - (match_operand:V4SF 1 "input_operand" "v,m,v,r,o,r"))] - "TARGET_ALTIVEC" - "@ - stvx %1,%y0 - lvx %0,%y1 - vor %0,%1,%1 - stw%U0 %1,%0\;stw %L1,%L0\;stw %Y1,%Y0\;stw %Z1,%Z0 - lwz%U1 %0,%1\;lwz %L0,%L1\;lwz %Y0,%Y1\;lwz %Z0,%Z1 - mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1" - [(set_attr "type" "altivec") - (set_attr "length" "*,*,*,16,16,16")]) - -(define_insn "get_vrsave_internal" - [(set (match_operand:SI 0 "register_operand" "=r") - (unspec:SI [(reg:SI 109)] 214))] - "TARGET_ALTIVEC" - "* -{ - if (TARGET_MACHO) - return \"mtspr 256,%0\"; - else - return \"mtvrsave %0\"; -}" - [(set_attr "type" "altivec")]) - -(define_insn "*set_vrsave_internal" - [(match_parallel 0 "vrsave_operation" - [(set (reg:SI 109) - (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "r") - (reg:SI 109)] 30))])] - "TARGET_ALTIVEC" - "* -{ - if (TARGET_MACHO) - return \"mfspr %1,256\"; - else - return \"mtvrsave %1\"; -}" - [(set_attr "type" "altivec")]) - -;; Vector clears -(define_insn "*movv4si_const0" - [(set (match_operand:V4SI 0 "altivec_register_operand" "=v") - (match_operand:V4SI 1 "zero_constant" ""))] - "TARGET_ALTIVEC" - "vxor %0,%0,%0" - [(set_attr "type" "vecsimple")]) - -(define_insn "*movv4sf_const0" - [(set (match_operand:V4SF 0 "altivec_register_operand" "=v") - (match_operand:V4SF 1 "zero_constant" ""))] - - "TARGET_ALTIVEC" - "vxor %0,%0,%0" - [(set_attr "type" "vecsimple")]) - -(define_insn "*movv8hi_const0" - [(set (match_operand:V8HI 0 "altivec_register_operand" "=v") - (match_operand:V8HI 1 "zero_constant" ""))] - "TARGET_ALTIVEC" - "vxor %0,%0,%0" - [(set_attr "type" "vecsimple")]) - -(define_insn "*movv16qi_const0" - [(set (match_operand:V16QI 0 "altivec_register_operand" "=v") - (match_operand:V16QI 1 "zero_constant" ""))] - "TARGET_ALTIVEC" - "vxor %0,%0,%0" - [(set_attr "type" "vecsimple")]) - -;; Simple binary operations. - -(define_insn "addv16qi3" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (plus:V16QI (match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vaddubm %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "addv8hi3" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (plus:V8HI (match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vadduhm %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "addv4si3" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (plus:V4SI (match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vadduwm %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "addv4sf3" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (plus:V4SF (match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vaddfp %0,%1,%2" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vaddcuw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 35))] - "TARGET_ALTIVEC" - "vaddcuw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vaddubs" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 36))] - "TARGET_ALTIVEC" - "vaddubs %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vaddsbs" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 37))] - "TARGET_ALTIVEC" - "vaddsbs %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vadduhs" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 38))] - "TARGET_ALTIVEC" - "vadduhs %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vaddshs" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 39))] - "TARGET_ALTIVEC" - "vaddshs %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vadduws" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 40))] - "TARGET_ALTIVEC" - "vadduws %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vaddsws" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 41))] - "TARGET_ALTIVEC" - "vaddsws %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "andv4si3" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (and:V4SI (match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vand %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vandc" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (and:V4SI (match_operand:V4SI 1 "register_operand" "v") - (not:V4SI (match_operand:V4SI 2 "register_operand" "v"))))] - "TARGET_ALTIVEC" - "vandc %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vavgub" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 44))] - "TARGET_ALTIVEC" - "vavgub %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vavgsb" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 45))] - "TARGET_ALTIVEC" - "vavgsb %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vavguh" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 46))] - "TARGET_ALTIVEC" - "vavguh %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vavgsh" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 47))] - "TARGET_ALTIVEC" - "vavgsh %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vavguw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 48))] - "TARGET_ALTIVEC" - "vavguw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vavgsw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 49))] - "TARGET_ALTIVEC" - "vavgsw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vcmpbfp" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")] 50))] - "TARGET_ALTIVEC" - "vcmpbfp %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "altivec_vcmpequb" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 51))] - "TARGET_ALTIVEC" - "vcmpequb %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vcmpequh" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 52))] - "TARGET_ALTIVEC" - "vcmpequh %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vcmpequw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 53))] - "TARGET_ALTIVEC" - "vcmpequw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vcmpeqfp" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")] 54))] - "TARGET_ALTIVEC" - "vcmpeqfp %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "altivec_vcmpgefp" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")] 55))] - "TARGET_ALTIVEC" - "vcmpgefp %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "altivec_vcmpgtub" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 56))] - "TARGET_ALTIVEC" - "vcmpgtub %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vcmpgtsb" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 57))] - "TARGET_ALTIVEC" - "vcmpgtsb %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vcmpgtuh" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 58))] - "TARGET_ALTIVEC" - "vcmpgtuh %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vcmpgtsh" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 59))] - "TARGET_ALTIVEC" - "vcmpgtsh %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vcmpgtuw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 60))] - "TARGET_ALTIVEC" - "vcmpgtuw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vcmpgtsw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 61))] - "TARGET_ALTIVEC" - "vcmpgtsw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vcmpgtfp" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")] 62))] - "TARGET_ALTIVEC" - "vcmpgtfp %0,%1,%2" - [(set_attr "type" "veccmp")]) - -;; Fused multiply add -(define_insn "altivec_vmaddfp" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (plus:V4SF (mult:V4SF (match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")) - (match_operand:V4SF 3 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vmaddfp %0,%1,%2,%3" - [(set_attr "type" "vecfloat")]) - -;; The unspec here is a vec splat of 0. We do multiply as a fused -;; multiply-add with an add of a 0 vector. - -(define_expand "mulv4sf3" - [(set (match_dup 3) (unspec:V4SF [(const_int 0)] 142)) - (set (match_operand:V4SF 0 "register_operand" "=v") - (plus:V4SF (mult:V4SF (match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")) - (match_dup 3)))] - "TARGET_ALTIVEC && TARGET_FUSED_MADD" - " -{ operands[3] = gen_reg_rtx (V4SFmode); }") - -;; Fused multiply subtract -(define_insn "altivec_vnmsubfp" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (minus:V4SF (mult:V4SF (match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")) - (match_operand:V4SF 3 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vnmsubfp %0,%1,%2,%3" - [(set_attr "type" "vecfloat")]) - - -(define_insn "altivec_vmsumubm" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v") - (match_operand:V4SI 3 "register_operand" "v")] 65))] - "TARGET_ALTIVEC" - "vmsumubm %0, %1, %2, %3" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmsummbm" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v") - (match_operand:V4SI 3 "register_operand" "v")] 66))] - "TARGET_ALTIVEC" - "vmsumubm %0, %1, %2, %3" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmsumuhm" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:V4SI 3 "register_operand" "v")] 67))] - "TARGET_ALTIVEC" - "vmsumuhm %0, %1, %2, %3" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmsumshm" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:V4SI 3 "register_operand" "v")] 68))] - "TARGET_ALTIVEC" - "vmsumshm %0, %1, %2, %3" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmsumuhs" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:V4SI 3 "register_operand" "v")] 69))] - "TARGET_ALTIVEC" - "vmsumuhs %0, %1, %2, %3" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmsumshs" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:V4SI 3 "register_operand" "v")] 70))] - "TARGET_ALTIVEC" - "vmsumshs %0, %1, %2, %3" - [(set_attr "type" "veccomplex")]) - -(define_insn "umaxv16qi3" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (umax:V16QI (match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vmaxub %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "smaxv16qi3" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (smax:V16QI (match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vmaxsb %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "umaxv8hi3" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (umax:V8HI (match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vmaxuh %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "smaxv8hi3" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (smax:V8HI (match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vmaxsh %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "umaxv4si3" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (umax:V4SI (match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vmaxuw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "smaxv4si3" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (smax:V4SI (match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vmaxsw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "smaxv4sf3" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (smax:V4SF (match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vmaxfp %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "altivec_vmhaddshs" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:V8HI 3 "register_operand" "v")] 71))] - "TARGET_ALTIVEC" - "vmhaddshs %0, %1, %2, %3" - [(set_attr "type" "veccomplex")]) -(define_insn "altivec_vmhraddshs" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:V8HI 3 "register_operand" "v")] 72))] - "TARGET_ALTIVEC" - "vmhraddshs %0, %1, %2, %3" - [(set_attr "type" "veccomplex")]) -(define_insn "altivec_vmladduhm" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:V8HI 3 "register_operand" "v")] 73))] - "TARGET_ALTIVEC" - "vmladduhm %0, %1, %2, %3" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmrghb" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (vec_merge:V16QI (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "v") - (parallel [(const_int 8) - (const_int 9) - (const_int 10) - (const_int 11) - (const_int 12) - (const_int 13) - (const_int 14) - (const_int 15) - (const_int 0) - (const_int 1) - (const_int 2) - (const_int 3) - (const_int 4) - (const_int 5) - (const_int 6) - (const_int 7)])) - (match_operand:V16QI 2 "register_operand" "v") - (const_int 255)))] - "TARGET_ALTIVEC" - "vmrghb %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vmrghh" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (vec_merge:V8HI (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "v") - (parallel [(const_int 4) - (const_int 5) - (const_int 6) - (const_int 7) - (const_int 0) - (const_int 1) - (const_int 2) - (const_int 3)])) - (match_operand:V8HI 2 "register_operand" "v") - (const_int 15)))] - "TARGET_ALTIVEC" - "vmrghh %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vmrghw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (vec_merge:V4SI (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "v") - (parallel [(const_int 2) - (const_int 3) - (const_int 0) - (const_int 1)])) - (match_operand:V4SI 2 "register_operand" "v") - (const_int 12)))] - "TARGET_ALTIVEC" - "vmrghw %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vmrglb" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (vec_merge:V16QI (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "v") - (parallel [(const_int 8) - (const_int 9) - (const_int 10) - (const_int 11) - (const_int 12) - (const_int 13) - (const_int 14) - (const_int 15) - (const_int 0) - (const_int 1) - (const_int 2) - (const_int 3) - (const_int 4) - (const_int 5) - (const_int 6) - (const_int 7)])) - (match_operand:V16QI 1 "register_operand" "v") - (const_int 255)))] - "TARGET_ALTIVEC" - "vmrglb %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vmrglh" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (vec_merge:V8HI (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "v") - (parallel [(const_int 4) - (const_int 5) - (const_int 6) - (const_int 7) - (const_int 0) - (const_int 1) - (const_int 2) - (const_int 3)])) - (match_operand:V8HI 1 "register_operand" "v") - (const_int 15)))] - "TARGET_ALTIVEC" - "vmrglh %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vmrglw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (vec_merge:V4SI (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "v") - (parallel [(const_int 2) - (const_int 3) - (const_int 0) - (const_int 1)])) - (match_operand:V4SI 1 "register_operand" "v") - (const_int 12)))] - "TARGET_ALTIVEC" - "vmrglw %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "uminv16qi3" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (umin:V16QI (match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vminub %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "sminv16qi3" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (smin:V16QI (match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vminsb %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "uminv8hi3" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (umin:V8HI (match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vminuh %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "sminv8hi3" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (smin:V8HI (match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vminsh %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "uminv4si3" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (umin:V4SI (match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vminuw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "sminv4si3" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (smin:V4SI (match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vminsw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "sminv4sf3" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (smin:V4SF (match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vminfp %0,%1,%2" - [(set_attr "type" "veccmp")]) - -(define_insn "altivec_vmuleub" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 83))] - "TARGET_ALTIVEC" - "vmuleub %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmulesb" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 84))] - "TARGET_ALTIVEC" - "vmulesb %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmuleuh" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 85))] - "TARGET_ALTIVEC" - "vmuleuh %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmulesh" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 86))] - "TARGET_ALTIVEC" - "vmulesh %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmuloub" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 87))] - "TARGET_ALTIVEC" - "vmuloub %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmulosb" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 88))] - "TARGET_ALTIVEC" - "vmulosb %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmulouh" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 89))] - "TARGET_ALTIVEC" - "vmulouh %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vmulosh" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 90))] - "TARGET_ALTIVEC" - "vmulosh %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vnor" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (not:V4SI (ior:V4SI (match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v"))))] - "TARGET_ALTIVEC" - "vnor %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "iorv4si3" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (ior:V4SI (match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vor %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vpkuhum" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 93))] - "TARGET_ALTIVEC" - "vpkuhum %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkuwum" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 94))] - "TARGET_ALTIVEC" - "vpkuwum %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkpx" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 95))] - "TARGET_ALTIVEC" - "vpkpx %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkuhss" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 96))] - "TARGET_ALTIVEC" - "vpkuhss %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkshss" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 97))] - "TARGET_ALTIVEC" - "vpkshss %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkuwss" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 98))] - "TARGET_ALTIVEC" - "vpkuwss %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkswss" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 99))] - "TARGET_ALTIVEC" - "vpkswss %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkuhus" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 100))] - "TARGET_ALTIVEC" - "vpkuhus %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkshus" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 101))] - "TARGET_ALTIVEC" - "vpkshus %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkuwus" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 102))] - "TARGET_ALTIVEC" - "vpkuwus %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vpkswus" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 103))] - "TARGET_ALTIVEC" - "vpkswus %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vrlb" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 104))] - "TARGET_ALTIVEC" - "vrlb %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vrlh" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 105))] - "TARGET_ALTIVEC" - "vrlh %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vrlw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 106))] - "TARGET_ALTIVEC" - "vrlw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vslb" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 107))] - "TARGET_ALTIVEC" - "vslb %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vslh" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 108))] - "TARGET_ALTIVEC" - "vslh %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vslw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 109))] - "TARGET_ALTIVEC" - "vslw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsl" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 110))] - "TARGET_ALTIVEC" - "vsl %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vslo" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 111))] - "TARGET_ALTIVEC" - "vslo %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vsrb" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 112))] - "TARGET_ALTIVEC" - "vsrb %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsrh" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 113))] - "TARGET_ALTIVEC" - "vsrh %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsrw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 114))] - "TARGET_ALTIVEC" - "vsrw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsrab" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 115))] - "TARGET_ALTIVEC" - "vsrab %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsrah" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 116))] - "TARGET_ALTIVEC" - "vsrah %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsraw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 117))] - "TARGET_ALTIVEC" - "vsraw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsr" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 118))] - "TARGET_ALTIVEC" - "vsr %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vsro" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 119))] - "TARGET_ALTIVEC" - "vsro %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "subv16qi3" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (minus:V16QI (match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vsububm %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "subv8hi3" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (minus:V8HI (match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vsubuhm %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "subv4si3" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (minus:V4SI (match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vsubuwm %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "subv4sf3" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (minus:V4SF (match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vsubfp %0,%1,%2" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vsubcuw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 124))] - "TARGET_ALTIVEC" - "vsubcuw %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsububs" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 125))] - "TARGET_ALTIVEC" - "vsububs %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsubsbs" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v")] 126))] - "TARGET_ALTIVEC" - "vsubsbs %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsubuhs" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 127))] - "TARGET_ALTIVEC" - "vsubuhs %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsubshs" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v")] 128))] - "TARGET_ALTIVEC" - "vsubshs %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsubuws" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 129))] - "TARGET_ALTIVEC" - "vsubuws %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsubsws" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 130))] - "TARGET_ALTIVEC" - "vsubsws %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vsum4ubs" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 131))] - "TARGET_ALTIVEC" - "vsum4ubs %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vsum4sbs" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 132))] - "TARGET_ALTIVEC" - "vsum4sbs %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vsum4shs" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 133))] - "TARGET_ALTIVEC" - "vsum4shs %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vsum2sws" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 134))] - "TARGET_ALTIVEC" - "vsum2sws %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "altivec_vsumsws" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")] 135))] - "TARGET_ALTIVEC" - "vsumsws %0,%1,%2" - [(set_attr "type" "veccomplex")]) - -(define_insn "xorv4si3" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (xor:V4SI (match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vxor %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vspltb" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:QI 2 "immediate_operand" "i")] 136))] - "TARGET_ALTIVEC" - "vspltb %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vsplth" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:QI 2 "immediate_operand" "i")] 137))] - "TARGET_ALTIVEC" - "vsplth %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vspltw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:QI 2 "immediate_operand" "i")] 138))] - "TARGET_ALTIVEC" - "vspltw %0,%1,%2" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vspltisb" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:QI 1 "immediate_operand" "i")] 139))] - "TARGET_ALTIVEC" - "vspltisb %0, %1" - [(set_attr "type" "vecsimple")]) - - -(define_insn "altivec_vspltish" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:QI 1 "immediate_operand" "i")] 140))] - "TARGET_ALTIVEC" - "vspltish %0, %1" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_vspltisw" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:QI 1 "immediate_operand" "i")] 141))] - "TARGET_ALTIVEC" - "vspltisw %0, %1" - [(set_attr "type" "vecsimple")]) - -(define_insn "" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:QI 1 "immediate_operand" "i")] 142))] - "TARGET_ALTIVEC" - "vspltisw %0, %1" - [(set_attr "type" "vecsimple")]) - -(define_insn "ftruncv4sf2" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (fix:V4SF (match_operand:V4SF 1 "register_operand" "v")))] - "TARGET_ALTIVEC" - "vrfiz %0, %1" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vperm_4si" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v") - (match_operand:V16QI 3 "register_operand" "v")] 144))] - "TARGET_ALTIVEC" - "vperm %0,%1,%2,%3" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vperm_4sf" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v") - (match_operand:V16QI 3 "register_operand" "v")] 145))] - "TARGET_ALTIVEC" - "vperm %0,%1,%2,%3" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vperm_8hi" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:V16QI 3 "register_operand" "v")] 146))] - "TARGET_ALTIVEC" - "vperm %0,%1,%2,%3" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vperm_16qi" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v") - (match_operand:V16QI 3 "register_operand" "v")] 147))] - "TARGET_ALTIVEC" - "vperm %0,%1,%2,%3" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vrfip" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 148))] - "TARGET_ALTIVEC" - "vrfip %0, %1" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vrfin" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 149))] - "TARGET_ALTIVEC" - "vrfin %0, %1" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vrfim" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 150))] - "TARGET_ALTIVEC" - "vrfim %0, %1" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vcfux" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:QI 2 "immediate_operand" "i")] 151))] - "TARGET_ALTIVEC" - "vcfux %0, %1, %2" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vcfsx" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:QI 2 "immediate_operand" "i")] 152))] - "TARGET_ALTIVEC" - "vcfsx %0, %1, %2" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vctuxs" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") - (match_operand:QI 2 "immediate_operand" "i")] 153))] - "TARGET_ALTIVEC" - "vctuxs %0, %1, %2" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vctsxs" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SF 1 "register_operand" "v") - (match_operand:QI 2 "immediate_operand" "i")] 154))] - "TARGET_ALTIVEC" - "vctsxs %0, %1, %2" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vlogefp" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 155))] - "TARGET_ALTIVEC" - "vlogefp %0, %1" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vexptefp" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 156))] - "TARGET_ALTIVEC" - "vexptefp %0, %1" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vrsqrtefp" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 157))] - "TARGET_ALTIVEC" - "vrsqrtefp %0, %1" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vrefp" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 158))] - "TARGET_ALTIVEC" - "vrefp %0, %1" - [(set_attr "type" "vecfloat")]) - -(define_insn "altivec_vsel_4si" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v") - (match_operand:V4SI 3 "register_operand" "v")] 159))] - "TARGET_ALTIVEC" - "vsel %0,%1,%2,%3" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vsel_4sf" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v") - (match_operand:V4SI 3 "register_operand" "v")] 160))] - "TARGET_ALTIVEC" - "vsel %0,%1,%2,%3" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vsel_8hi" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:V8HI 3 "register_operand" "v")] 161))] - "TARGET_ALTIVEC" - "vsel %0,%1,%2,%3" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vsel_16qi" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v") - (match_operand:V16QI 3 "register_operand" "v")] 162))] - "TARGET_ALTIVEC" - "vsel %0,%1,%2,%3" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vsldoi_4si" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v") - (match_operand:QI 3 "immediate_operand" "i")] 163))] - "TARGET_ALTIVEC" - "vsldoi %0, %1, %2, %3" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vsldoi_4sf" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v") - (match_operand:QI 3 "immediate_operand" "i")] 164))] - "TARGET_ALTIVEC" - "vsldoi %0, %1, %2, %3" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vsldoi_8hi" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand:QI 3 "immediate_operand" "i")] 165))] - "TARGET_ALTIVEC" - "vsldoi %0, %1, %2, %3" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vsldoi_16qi" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v") - (match_operand:QI 3 "immediate_operand" "i")] 166))] - "TARGET_ALTIVEC" - "vsldoi %0, %1, %2, %3" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vupkhsb" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")] 167))] - "TARGET_ALTIVEC" - "vupkhsb %0, %1" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vupkhpx" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 168))] - "TARGET_ALTIVEC" - "vupkhpx %0, %1" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vupkhsh" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 169))] - "TARGET_ALTIVEC" - "vupkhsh %0, %1" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vupklsb" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")] 170))] - "TARGET_ALTIVEC" - "vupklsb %0, %1" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vupklpx" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 171))] - "TARGET_ALTIVEC" - "vupklpx %0, %1" - [(set_attr "type" "vecperm")]) - -(define_insn "altivec_vupklsh" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 172))] - "TARGET_ALTIVEC" - "vupklsh %0, %1" - [(set_attr "type" "vecperm")]) - -;; AltiVec predicates. - -(define_expand "cr6_test_for_zero" - [(set (match_operand:SI 0 "register_operand" "=r") - (eq:SI (reg:CC 74) - (const_int 0)))] - "TARGET_ALTIVEC" - "") - -(define_expand "cr6_test_for_zero_reverse" - [(set (match_operand:SI 0 "register_operand" "=r") - (eq:SI (reg:CC 74) - (const_int 0))) - (set (match_dup 0) (minus:SI (const_int 1) (match_dup 0)))] - "TARGET_ALTIVEC" - "") -(define_expand "cr6_test_for_lt" - [(set (match_operand:SI 0 "register_operand" "=r") - (lt:SI (reg:CC 74) - (const_int 0)))] - "TARGET_ALTIVEC" - "") - -(define_expand "cr6_test_for_lt_reverse" - [(set (match_operand:SI 0 "register_operand" "=r") - (lt:SI (reg:CC 74) - (const_int 0))) - (set (match_dup 0) (minus:SI (const_int 1) (match_dup 0)))] - "TARGET_ALTIVEC" - "") - -;; We can get away with generating the opcode on the fly (%3 below) -;; because all the predicates have the same scheduling parameters. - -(define_insn "altivec_predicate_v4si" - [(set (reg:CC 74) - (unspec:CC [(match_operand:V4SI 1 "register_operand" "v") - (match_operand:V4SI 2 "register_operand" "v") - (match_operand 3 "any_operand" "")] 173)) - (clobber (match_scratch:V4SI 0 "=v"))] - "TARGET_ALTIVEC" - "%3 %0,%1,%2" -[(set_attr "type" "veccmp")]) - -(define_insn "altivec_predicate_v4sf" - [(set (reg:CC 74) - (unspec:CC [(match_operand:V4SF 1 "register_operand" "v") - (match_operand:V4SF 2 "register_operand" "v") - (match_operand 3 "any_operand" "")] 174)) - (clobber (match_scratch:V4SF 0 "=v"))] - "TARGET_ALTIVEC" - "%3 %0,%1,%2" -[(set_attr "type" "veccmp")]) - -(define_insn "altivec_predicate_v8hi" - [(set (reg:CC 74) - (unspec:CC [(match_operand:V8HI 1 "register_operand" "v") - (match_operand:V8HI 2 "register_operand" "v") - (match_operand 3 "any_operand" "")] 175)) - (clobber (match_scratch:V8HI 0 "=v"))] - "TARGET_ALTIVEC" - "%3 %0,%1,%2" -[(set_attr "type" "veccmp")]) - -(define_insn "altivec_predicate_v16qi" - [(set (reg:CC 74) - (unspec:CC [(match_operand:V16QI 1 "register_operand" "v") - (match_operand:V16QI 2 "register_operand" "v") - (match_operand 3 "any_operand" "")] 175)) - (clobber (match_scratch:V16QI 0 "=v"))] - "TARGET_ALTIVEC" - "%3 %0,%1,%2" -[(set_attr "type" "veccmp")]) - -(define_insn "altivec_mtvscr" - [(unspec [(match_operand:V4SI 0 "register_operand" "v")] 186)] - "TARGET_ALTIVEC" - "mtvscr %0" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_mfvscr" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(const_int 0)] 187))] - "TARGET_ALTIVEC" - "mfvscr %0" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_dssall" - [(unspec [(const_int 0)] 188)] - "TARGET_ALTIVEC" - "dssall" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_dss" - [(unspec [(match_operand:QI 0 "immediate_operand" "i")] 189)] - "TARGET_ALTIVEC" - "dss %0" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_dst" - [(unspec [(match_operand:SI 0 "register_operand" "b") - (match_operand:SI 1 "register_operand" "r") - (match_operand:QI 2 "immediate_operand" "i")] 190)] - "TARGET_ALTIVEC" - "dst %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_dstt" - [(unspec [(match_operand:SI 0 "register_operand" "b") - (match_operand:SI 1 "register_operand" "r") - (match_operand:QI 2 "immediate_operand" "i")] 191)] - "TARGET_ALTIVEC" - "dstt %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_dstst" - [(unspec [(match_operand:SI 0 "register_operand" "b") - (match_operand:SI 1 "register_operand" "r") - (match_operand:QI 2 "immediate_operand" "i")] 192)] - "TARGET_ALTIVEC" - "dstst %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_dststt" - [(unspec [(match_operand:SI 0 "register_operand" "b") - (match_operand:SI 1 "register_operand" "r") - (match_operand:QI 2 "immediate_operand" "i")] 193)] - "TARGET_ALTIVEC" - "dststt %0,%1,%2" - [(set_attr "type" "vecsimple")]) - -(define_insn "altivec_lvsl" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:SI 1 "register_operand" "b") - (match_operand:SI 2 "register_operand" "r")] 194))] - "TARGET_ALTIVEC" - "lvsl %0,%1,%2" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_lvsr" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:SI 1 "register_operand" "b") - (match_operand:SI 2 "register_operand" "r")] 195))] - "TARGET_ALTIVEC" - "lvsr %0,%1,%2" - [(set_attr "type" "vecload")]) - -;; Parallel some of the LVE* and STV*'s with unspecs because some have -;; identical rtl but different instructions-- and gcc gets confused. - -(define_insn "altivec_lvebx" - [(parallel - [(set (match_operand:V16QI 0 "register_operand" "=v") - (mem:V16QI (plus:SI (match_operand:SI 1 "register_operand" "b") - (match_operand:SI 2 "register_operand" "r")))) - (unspec [(const_int 0)] 196)])] - "TARGET_ALTIVEC" - "lvebx %0,%1,%2" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_lvehx" - [(parallel - [(set (match_operand:V8HI 0 "register_operand" "=v") - (mem:V8HI - (and:SI (plus:SI (match_operand:SI 1 "register_operand" "b") - (match_operand:SI 2 "register_operand" "r")) - (const_int -2)))) - (unspec [(const_int 0)] 197)])] - "TARGET_ALTIVEC" - "lvehx %0,%1,%2" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_lvewx" - [(parallel - [(set (match_operand:V4SI 0 "register_operand" "=v") - (mem:V4SI - (and:SI (plus:SI (match_operand:SI 1 "register_operand" "b") - (match_operand:SI 2 "register_operand" "r")) - (const_int -4)))) - (unspec [(const_int 0)] 198)])] - "TARGET_ALTIVEC" - "lvewx %0,%1,%2" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_lvxl" - [(parallel - [(set (match_operand:V4SI 0 "register_operand" "=v") - (mem:V4SI (plus:SI (match_operand:SI 1 "register_operand" "b") - (match_operand:SI 2 "register_operand" "r")))) - (unspec [(const_int 0)] 213)])] - "TARGET_ALTIVEC" - "lvxl %0,%1,%2" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_lvx" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (mem:V4SI (plus:SI (match_operand:SI 1 "register_operand" "b") - (match_operand:SI 2 "register_operand" "r"))))] - "TARGET_ALTIVEC" - "lvx %0,%1,%2" - [(set_attr "type" "vecload")]) - -(define_insn "altivec_stvx" - [(parallel - [(set (mem:V4SI - (and:SI (plus:SI (match_operand:SI 0 "register_operand" "b") - (match_operand:SI 1 "register_operand" "r")) - (const_int -16))) - (match_operand:V4SI 2 "register_operand" "v")) - (unspec [(const_int 0)] 201)])] - "TARGET_ALTIVEC" - "stvx %2,%0,%1" - [(set_attr "type" "vecstore")]) - -(define_insn "altivec_stvxl" - [(parallel - [(set (mem:V4SI - (and:SI (plus:SI (match_operand:SI 0 "register_operand" "b") - (match_operand:SI 1 "register_operand" "r")) - (const_int -16))) - (match_operand:V4SI 2 "register_operand" "v")) - (unspec [(const_int 0)] 202)])] - "TARGET_ALTIVEC" - "stvxl %2,%0,%1" - [(set_attr "type" "vecstore")]) - -(define_insn "altivec_stvebx" - [(parallel - [(set (mem:V16QI - (plus:SI (match_operand:SI 0 "register_operand" "b") - (match_operand:SI 1 "register_operand" "r"))) - (match_operand:V16QI 2 "register_operand" "v")) - (unspec [(const_int 0)] 203)])] - "TARGET_ALTIVEC" - "stvebx %2,%0,%1" - [(set_attr "type" "vecstore")]) - -(define_insn "altivec_stvehx" - [(parallel - [(set (mem:V8HI - (and:SI (plus:SI (match_operand:SI 0 "register_operand" "b") - (match_operand:SI 1 "register_operand" "r")) - (const_int -2))) - (match_operand:V8HI 2 "register_operand" "v")) - (unspec [(const_int 0)] 204)])] - "TARGET_ALTIVEC" - "stvehx %2,%0,%1" - [(set_attr "type" "vecstore")]) - -(define_insn "altivec_stvewx" - [(parallel - [(set (mem:V4SI - (and:SI (plus:SI (match_operand:SI 0 "register_operand" "b") - (match_operand:SI 1 "register_operand" "r")) - (const_int -4))) - (match_operand:V4SI 2 "register_operand" "v")) - (unspec [(const_int 0)] 205)])] - "TARGET_ALTIVEC" - "stvewx %2,%0,%1" - [(set_attr "type" "vecstore")]) - -(define_insn "absv16qi2" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (abs:V16QI (match_operand:V16QI 1 "register_operand" "v"))) - (clobber (match_scratch:V16QI 2 "=v")) - (clobber (match_scratch:V16QI 3 "=v"))] - "TARGET_ALTIVEC" - "vspltisb %2,0\;vsububm %3,%2,%1\;vmaxsb %0,%1,%3" - [(set_attr "type" "altivec") - (set_attr "length" "12")]) - -(define_insn "absv8hi2" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (abs:V8HI (match_operand:V8HI 1 "register_operand" "v"))) - (clobber (match_scratch:V8HI 2 "=v")) - (clobber (match_scratch:V8HI 3 "=v"))] - "TARGET_ALTIVEC" - "vspltisb %2,0\;vsubuhm %3,%2,%1\;vmaxsh %0,%1,%3" - [(set_attr "type" "altivec") - (set_attr "length" "12")]) - -(define_insn "absv4si2" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (abs:V4SI (match_operand:V4SI 1 "register_operand" "v"))) - (clobber (match_scratch:V4SI 2 "=v")) - (clobber (match_scratch:V4SI 3 "=v"))] - "TARGET_ALTIVEC" - "vspltisb %2,0\;vsubuwm %3,%2,%1\;vmaxsw %0,%1,%3" - [(set_attr "type" "altivec") - (set_attr "length" "12")]) - -(define_insn "absv4sf2" - [(set (match_operand:V4SF 0 "register_operand" "=v") - (abs:V4SF (match_operand:V4SF 1 "register_operand" "v"))) - (clobber (match_scratch:V4SF 2 "=v")) - (clobber (match_scratch:V4SF 3 "=v"))] - "TARGET_ALTIVEC" - "vspltisw %2, -1\;vslw %3,%2,%2\;vandc %0,%1,%3" - [(set_attr "type" "altivec") - (set_attr "length" "12")]) - -(define_insn "altivec_abss_v16qi" - [(set (match_operand:V16QI 0 "register_operand" "=v") - (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")] 210)) - (clobber (match_scratch:V16QI 2 "=v")) - (clobber (match_scratch:V16QI 3 "=v"))] - "TARGET_ALTIVEC" - "vspltisb %2,0\;vsubsbs %3,%2,%1\;vmaxsb %0,%1,%3" - [(set_attr "type" "altivec") - (set_attr "length" "12")]) - -(define_insn "altivec_abss_v8hi" - [(set (match_operand:V8HI 0 "register_operand" "=v") - (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "v")] 211)) - (clobber (match_scratch:V8HI 2 "=v")) - (clobber (match_scratch:V8HI 3 "=v"))] - "TARGET_ALTIVEC" - "vspltisb %2,0\;vsubshs %3,%2,%1\;vmaxsh %0,%1,%3" - [(set_attr "type" "altivec") - (set_attr "length" "12")]) - -(define_insn "altivec_abss_v4si" - [(set (match_operand:V4SI 0 "register_operand" "=v") - (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "v")] 212)) - (clobber (match_scratch:V4SI 2 "=v")) - (clobber (match_scratch:V4SI 3 "=v"))] - "TARGET_ALTIVEC" - "vspltisb %2,0\;vsubsws %3,%2,%1\;vmaxsw %0,%1,%3" - [(set_attr "type" "altivec") - (set_attr "length" "12")]) +(include "altivec.md") +(include "spe.md") |