diff options
Diffstat (limited to 'gcc/config/rs6000/rs6000.md')
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 1158 |
1 files changed, 880 insertions, 278 deletions
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 34ccacf9c2d..23a9715f9be 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -1,5 +1,6 @@ ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler -;; Copyright (C) 1990, 91-98, 1999 Free Software Foundation, Inc. +;; Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +;; 2000, 2001 Free Software Foundation, Inc. ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ;; This file is part of GNU CC. @@ -27,12 +28,14 @@ (const_string "integer")) ;; Length (in bytes). +; '(pc)' in the following doesn't include the instruction itself; it is +; calculated as if the instruction had zero size. (define_attr "length" "" (if_then_else (eq_attr "type" "branch") - (if_then_else (and (ge (minus (pc) (match_dup 0)) + (if_then_else (and (ge (minus (match_dup 0) (pc)) (const_int -32768)) - (lt (minus (pc) (match_dup 0)) - (const_int 32767))) + (lt (minus (match_dup 0) (pc)) + (const_int 32764))) (const_int 8) (const_int 12)) (const_int 4))) @@ -931,7 +934,7 @@ (match_operand:SI 2 "reg_or_short_operand" "r,I,r,I")) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r,r,r"))] - "" + "! TARGET_POWERPC64" "@ {cax.|add.} %3,%1,%2 {ai.|addic.} %3,%1,%2 @@ -946,7 +949,7 @@ (match_operand:SI 2 "reg_or_short_operand" "")) (const_int 0))) (clobber (match_scratch:SI 3 ""))] - "reload_completed" + "! TARGET_POWERPC64 && reload_completed" [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2))) @@ -963,7 +966,7 @@ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r") (plus:SI (match_dup 1) (match_dup 2)))] - "" + "! TARGET_POWERPC64" "@ {cax.|add.} %0,%1,%2 {ai.|addic.} %0,%1,%2 @@ -979,7 +982,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (plus:SI (match_dup 1) (match_dup 2)))] - "reload_completed" + "! TARGET_POWERPC64 && reload_completed" [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2))) @@ -1022,7 +1025,7 @@ (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:SI 2 "=r,r"))] - "" + "! TARGET_POWERPC64" "@ nor. %2,%1,%1 #" @@ -1034,7 +1037,7 @@ (compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:SI 2 ""))] - "reload_completed" + "! TARGET_POWERPC64 && reload_completed" [(set (match_dup 2) (not:SI (match_dup 1))) (set (match_dup 0) @@ -1048,7 +1051,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (not:SI (match_dup 1)))] - "" + "! TARGET_POWERPC64" "@ nor. %0,%1,%1 #" @@ -1061,7 +1064,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r") (not:SI (match_dup 1)))] - "reload_completed" + "! TARGET_POWERPC64 && reload_completed" [(set (match_dup 0) (not:SI (match_dup 1))) (set (match_dup 2) @@ -1104,7 +1107,7 @@ (match_operand:SI 2 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r"))] - "TARGET_POWERPC" + "TARGET_POWERPC && ! TARGET_POWERPC64" "@ subf. %3,%2,%1 #" @@ -1117,7 +1120,7 @@ (match_operand:SI 2 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:SI 3 ""))] - "reload_completed" + "! TARGET_POWERPC64 && reload_completed" [(set (match_dup 3) (minus:SI (match_dup 1) (match_dup 2))) @@ -1148,7 +1151,7 @@ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (minus:SI (match_dup 1) (match_dup 2)))] - "TARGET_POWERPC" + "TARGET_POWERPC && ! TARGET_POWERPC64" "@ subf. %0,%2,%1 #" @@ -1163,7 +1166,7 @@ (set (match_operand:SI 0 "gpc_reg_operand" "") (minus:SI (match_dup 1) (match_dup 2)))] - "reload_completed" + "! TARGET_POWERPC64 && reload_completed" [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2))) @@ -1324,7 +1327,7 @@ "" " { - if (!TARGET_POWER) + if (! TARGET_POWER) { emit_insn (gen_abssi2_nopower (operands[0], operands[1])); DONE; @@ -1341,7 +1344,7 @@ [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r") (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0"))) (clobber (match_scratch:SI 2 "=&r,&r"))] - "!TARGET_POWER" + "! TARGET_POWER" "* { return (TARGET_POWERPC) @@ -1354,7 +1357,7 @@ [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r") (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0"))) (clobber (match_scratch:SI 2 "=&r,&r"))] - "!TARGET_POWER && reload_completed" + "! TARGET_POWER && 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)))] @@ -1370,7 +1373,7 @@ [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r") (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0")))) (clobber (match_scratch:SI 2 "=&r,&r"))] - "!TARGET_POWER" + "! TARGET_POWER" "* { return (TARGET_POWERPC) @@ -1383,7 +1386,7 @@ [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r") (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0")))) (clobber (match_scratch:SI 2 "=&r,&r"))] - "!TARGET_POWER && reload_completed" + "! TARGET_POWER && 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)))] @@ -1400,7 +1403,7 @@ (compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r")) (const_int 0))) (clobber (match_scratch:SI 2 "=r"))] - "" + "! TARGET_POWERPC64" "neg. %2,%1" [(set_attr "type" "compare")]) @@ -1410,7 +1413,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r") (neg:SI (match_dup 1)))] - "" + "! TARGET_POWERPC64" "neg. %0,%1" [(set_attr "type" "compare")]) @@ -1874,7 +1877,7 @@ (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" "@ and. %3,%1,%2 {andil.|andi.} %3,%1,%b2 @@ -1894,7 +1897,7 @@ (const_int 0))) (clobber (match_scratch:SI 3 "")) (clobber (match_scratch:CC 4 ""))] - "reload_completed" + "! TARGET_POWERPC64 && reload_completed" [(parallel [(set (match_dup 3) (and:SI (match_dup 1) (match_dup 2))) @@ -1913,7 +1916,7 @@ (and:SI (match_dup 1) (match_dup 2))) (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))] - "" + "! TARGET_POWERPC64" "@ and. %0,%1,%2 {andil.|andi.} %0,%1,%b2 @@ -1935,7 +1938,7 @@ (and:SI (match_dup 1) (match_dup 2))) (clobber (match_scratch:CC 4 ""))] - "reload_completed" + "! TARGET_POWERPC64 && reload_completed" [(parallel [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2))) @@ -1983,7 +1986,7 @@ (match_operand:SI 2 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r"))] - "" + "! TARGET_POWERPC64" "@ or. %3,%1,%2 #" @@ -1996,7 +1999,7 @@ (match_operand:SI 2 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:SI 3 ""))] - "reload_completed" + "! TARGET_POWERPC64 && reload_completed" [(set (match_dup 3) (ior:SI (match_dup 1) (match_dup 2))) @@ -2013,7 +2016,7 @@ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (ior:SI (match_dup 1) (match_dup 2)))] - "" + "! TARGET_POWERPC64" "@ or. %0,%1,%2 #" @@ -2027,7 +2030,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (ior:SI (match_dup 1) (match_dup 2)))] - "reload_completed" + "! TARGET_POWERPC64 && reload_completed" [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2))) @@ -2090,7 +2093,7 @@ (match_operand:SI 2 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r"))] - "" + "! TARGET_POWERPC64" "@ xor. %3,%1,%2 #" @@ -2103,7 +2106,7 @@ (match_operand:SI 2 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:SI 3 ""))] - "reload_completed" + "! TARGET_POWERPC64 && reload_completed" [(set (match_dup 3) (xor:SI (match_dup 1) (match_dup 2))) @@ -2120,7 +2123,7 @@ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (xor:SI (match_dup 1) (match_dup 2)))] - "" + "! TARGET_POWERPC64" "@ xor. %0,%1,%2 #" @@ -2134,7 +2137,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "") (xor:SI (match_dup 1) (match_dup 2)))] - "reload_completed" + "! TARGET_POWERPC64 && reload_completed" [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2))) @@ -2172,7 +2175,7 @@ (match_operand:SI 2 "gpc_reg_operand" "r,r"))) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r"))] - "" + "! TARGET_POWERPC64" "@ eqv. %3,%1,%2 #" @@ -2185,7 +2188,7 @@ (match_operand:SI 2 "gpc_reg_operand" ""))) (const_int 0))) (clobber (match_scratch:SI 3 ""))] - "reload_completed" + "! TARGET_POWERPC64 && reload_completed" [(set (match_dup 3) (not:SI (xor:SI (match_dup 1) (match_dup 2)))) @@ -2201,7 +2204,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (not:SI (xor:SI (match_dup 1) (match_dup 2))))] - "" + "! TARGET_POWERPC64" "@ eqv. %0,%1,%2 #" @@ -2216,7 +2219,7 @@ (set (match_operand:SI 0 "gpc_reg_operand" "") (not:SI (xor:SI (match_dup 1) (match_dup 2))))] - "reload_completed" + "! TARGET_POWERPC64 && reload_completed" [(set (match_dup 0) (not:SI (xor:SI (match_dup 1) (match_dup 2)))) @@ -2238,7 +2241,7 @@ (match_operand:SI 2 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r"))] - "" + "! TARGET_POWERPC64" "@ andc. %3,%2,%1 #" @@ -2251,7 +2254,7 @@ (match_operand:SI 2 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:SI 3 ""))] - "reload_completed" + "! TARGET_POWERPC64 && reload_completed" [(set (match_dup 3) (and:SI (not:SI (match_dup 1)) (match_dup 2))) @@ -2268,7 +2271,7 @@ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (and:SI (not:SI (match_dup 1)) (match_dup 2)))] - "" + "! TARGET_POWERPC64" "@ andc. %0,%2,%1 #" @@ -2283,7 +2286,7 @@ (set (match_operand:SI 0 "gpc_reg_operand" "") (and:SI (not:SI (match_dup 1)) (match_dup 2)))] - "reload_completed" + "! TARGET_POWERPC64 && reload_completed" [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2))) @@ -2305,7 +2308,7 @@ (match_operand:SI 2 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r"))] - "" + "! TARGET_POWERPC64" "@ orc. %3,%2,%1 #" @@ -2318,7 +2321,7 @@ (match_operand:SI 2 "gpc_reg_operand" "")) (const_int 0))) (clobber (match_scratch:SI 3 ""))] - "reload_completed" + "! TARGET_POWERPC64 && reload_completed" [(set (match_dup 3) (ior:SI (not:SI (match_dup 1)) (match_dup 2))) @@ -2334,7 +2337,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (ior:SI (not:SI (match_dup 1)) (match_dup 2)))] - "" + "! TARGET_POWERPC64" "@ orc. %0,%2,%1 #" @@ -2348,7 +2351,7 @@ (set (match_operand:SI 0 "gpc_reg_operand" "") (ior:SI (not:SI (match_dup 1)) (match_dup 2)))] - "reload_completed" + "! TARGET_POWERPC64 && reload_completed" [(set (match_dup 0) (ior:SI (not:SI (match_dup 1)) (match_dup 2))) @@ -2370,7 +2373,7 @@ (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r"))) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r"))] - "" + "! TARGET_POWERPC64" "@ nand. %3,%1,%2 #" @@ -2383,7 +2386,7 @@ (not:SI (match_operand:SI 2 "gpc_reg_operand" ""))) (const_int 0))) (clobber (match_scratch:SI 3 ""))] - "reload_completed" + "! TARGET_POWERPC64 && reload_completed" [(set (match_dup 3) (ior:SI (not:SI (match_dup 1)) (not:SI (match_dup 2)))) @@ -2400,7 +2403,7 @@ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (ior:SI (not:SI (match_dup 1)) (not:SI (match_dup 2))))] - "" + "! TARGET_POWERPC64" "@ nand. %0,%1,%2 #" @@ -2415,7 +2418,7 @@ (set (match_operand:SI 0 "gpc_reg_operand" "") (ior:SI (not:SI (match_dup 1)) (not:SI (match_dup 2))))] - "reload_completed" + "! TARGET_POWERPC64 && reload_completed" [(set (match_dup 0) (ior:SI (not:SI (match_dup 1)) (not:SI (match_dup 2)))) @@ -2437,7 +2440,7 @@ (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r"))) (const_int 0))) (clobber (match_scratch:SI 3 "=r,r"))] - "" + "! TARGET_POWERPC64" "@ nor. %3,%1,%2 #" @@ -2450,7 +2453,7 @@ (not:SI (match_operand:SI 2 "gpc_reg_operand" ""))) (const_int 0))) (clobber (match_scratch:SI 3 ""))] - "reload_completed" + "! TARGET_POWERPC64 && reload_completed" [(set (match_dup 3) (and:SI (not:SI (match_dup 1)) (not:SI (match_dup 2)))) @@ -2467,7 +2470,7 @@ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (and:SI (not:SI (match_dup 1)) (not:SI (match_dup 2))))] - "" + "! TARGET_POWERPC64" "@ nor. %0,%1,%2 #" @@ -2482,7 +2485,7 @@ (set (match_operand:SI 0 "gpc_reg_operand" "") (and:SI (not:SI (match_dup 1)) (not:SI (match_dup 2))))] - "reload_completed" + "! TARGET_POWERPC64 && reload_completed" [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (not:SI (match_dup 2)))) @@ -2594,10 +2597,10 @@ ;; Rotate and shift insns, in all their variants. These support shifts, ;; field inserts and extracts, and various combinations thereof. (define_expand "insv" - [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") - (match_operand:SI 1 "const_int_operand" "i") - (match_operand:SI 2 "const_int_operand" "i")) - (match_operand:SI 3 "gpc_reg_operand" "r"))] + [(set (zero_extract (match_operand 0 "gpc_reg_operand" "") + (match_operand:SI 1 "const_int_operand" "") + (match_operand:SI 2 "const_int_operand" "")) + (match_operand 3 "gpc_reg_operand" ""))] "" " { @@ -2607,9 +2610,15 @@ if (GET_CODE (operands[0]) == SUBREG && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD)) FAIL; + + if (TARGET_POWERPC64 && GET_MODE (operands[0]) == DImode) + emit_insn (gen_insvdi (operands[0], operands[1], operands[2], operands[3])); + else + emit_insn (gen_insvsi (operands[0], operands[1], operands[2], operands[3])); + DONE; }") -(define_insn "" +(define_insn "insvsi" [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") (match_operand:SI 1 "const_int_operand" "i") (match_operand:SI 2 "const_int_operand" "i")) @@ -2625,7 +2634,7 @@ return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\"; }") -(define_insn "" +(define_insn "*insvsi_internal1" [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") (match_operand:SI 1 "const_int_operand" "i") (match_operand:SI 2 "const_int_operand" "i")) @@ -2643,7 +2652,7 @@ return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\"; }") -(define_insn "" +(define_insn "*insvsi_internal2" [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") (match_operand:SI 1 "const_int_operand" "i") (match_operand:SI 2 "const_int_operand" "i")) @@ -2661,7 +2670,7 @@ return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\"; }") -(define_insn "" +(define_insn "*insvsi_internal3" [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") (match_operand:SI 1 "const_int_operand" "i") (match_operand:SI 2 "const_int_operand" "i")) @@ -2679,7 +2688,7 @@ return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\"; }") -(define_insn "" +(define_insn "*insvsi_internal4" [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") (match_operand:SI 1 "const_int_operand" "i") (match_operand:SI 2 "const_int_operand" "i")) @@ -2700,10 +2709,10 @@ return \"{rlimi|rlwimi} %0,%3,%h5,%h2,%h1\"; }") -(define_insn "" +(define_insn "insvdi" [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r") - (match_operand:DI 1 "const_int_operand" "i") - (match_operand:DI 2 "const_int_operand" "i")) + (match_operand:SI 1 "const_int_operand" "i") + (match_operand:SI 2 "const_int_operand" "i")) (match_operand:DI 3 "gpc_reg_operand" "r"))] "TARGET_POWERPC64" "* @@ -2711,15 +2720,15 @@ int start = INTVAL (operands[2]) & 63; int size = INTVAL (operands[1]) & 63; - operands[2] = GEN_INT (64 - start - size); - return \"rldimi %0,%3,%H2,%H1\"; + operands[1] = GEN_INT (64 - start - size); + return \"rldimi %0,%3,%H1,%H2\"; }") (define_expand "extzv" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "const_int_operand" "i") - (match_operand:SI 3 "const_int_operand" "i")))] + [(set (match_operand 0 "gpc_reg_operand" "") + (zero_extract (match_operand 1 "gpc_reg_operand" "") + (match_operand:SI 2 "const_int_operand" "") + (match_operand:SI 3 "const_int_operand" "")))] "" " { @@ -2729,9 +2738,15 @@ if (GET_CODE (operands[0]) == SUBREG && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD)) FAIL; + + if (TARGET_POWERPC64 && GET_MODE (operands[1]) == DImode) + emit_insn (gen_extzvdi (operands[0], operands[1], operands[2], operands[3])); + else + emit_insn (gen_extzvsi (operands[0], operands[1], operands[2], operands[3])); + DONE; }") -(define_insn "" +(define_insn "extzvsi" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "const_int_operand" "i") @@ -2749,14 +2764,14 @@ return \"{rlinm|rlwinm} %0,%1,%3,%s2,31\"; }") -(define_insn "" +(define_insn "*extzvsi_internal1" [(set (match_operand:CC 0 "cc_reg_operand" "=x") (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "const_int_operand" "i") (match_operand:SI 3 "const_int_operand" "i")) (const_int 0))) (clobber (match_scratch:SI 4 "=r"))] - "" + "! TARGET_POWERPC64" "* { int start = INTVAL (operands[3]) & 31; @@ -2786,7 +2801,7 @@ }" [(set_attr "type" "compare")]) -(define_insn "" +(define_insn "*extzvsi_internal2" [(set (match_operand:CC 4 "cc_reg_operand" "=x") (compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "const_int_operand" "i") @@ -2794,7 +2809,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r") (zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))] - "" + "! TARGET_POWERPC64" "* { int start = INTVAL (operands[3]) & 31; @@ -2814,11 +2829,11 @@ }" [(set_attr "type" "delayed_compare")]) -(define_insn "" +(define_insn "extzvdi" [(set (match_operand:DI 0 "gpc_reg_operand" "=r") (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "const_int_operand" "i") - (match_operand:DI 3 "const_int_operand" "i")))] + (match_operand:SI 2 "const_int_operand" "i") + (match_operand:SI 3 "const_int_operand" "i")))] "TARGET_POWERPC64" "* { @@ -2833,11 +2848,11 @@ return \"rldicl %0,%1,%3,%2\"; }") -(define_insn "" +(define_insn "*extzvdi_internal1" [(set (match_operand:CC 0 "gpc_reg_operand" "=x") (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "const_int_operand" "i") - (match_operand:DI 3 "const_int_operand" "i")) + (match_operand:SI 2 "const_int_operand" "i") + (match_operand:SI 3 "const_int_operand" "i")) (const_int 0))) (clobber (match_scratch:DI 4 "=r"))] "TARGET_POWERPC64" @@ -2854,11 +2869,11 @@ return \"rldicl. %4,%1,%3,%2\"; }") -(define_insn "" +(define_insn "*extzvdi_internal2" [(set (match_operand:CC 4 "gpc_reg_operand" "=x") (compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "const_int_operand" "i") - (match_operand:DI 3 "const_int_operand" "i")) + (match_operand:SI 2 "const_int_operand" "i") + (match_operand:SI 3 "const_int_operand" "i")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "=r") (zero_extract:DI (match_dup 1) (match_dup 2) (match_dup 3)))] @@ -2889,7 +2904,7 @@ (match_operand:SI 2 "reg_or_cint_operand" "ri")) (const_int 0))) (clobber (match_scratch:SI 3 "=r"))] - "" + "! TARGET_POWERPC64" "{rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffffffff" [(set_attr "type" "delayed_compare")]) @@ -2900,7 +2915,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r") (rotate:SI (match_dup 1) (match_dup 2)))] - "" + "! TARGET_POWERPC64" "{rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffffffff" [(set_attr "type" "delayed_compare")]) @@ -2920,7 +2935,7 @@ (match_operand:SI 3 "mask_operand" "T")) (const_int 0))) (clobber (match_scratch:SI 4 "=r"))] - "" + "! TARGET_POWERPC64" "{rl%I2nm.|rlw%I2nm.} %4,%1,%h2,%m3,%M3" [(set_attr "type" "delayed_compare")]) @@ -2933,7 +2948,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=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" [(set_attr "type" "delayed_compare")]) @@ -3030,16 +3045,14 @@ "TARGET_POWER" "@ sle %0,%1,%2 - {sli|slwi} %0,%1,%h2" - [(set_attr "length" "8")]) + {sli|slwi} %0,%1,%h2") (define_insn "ashlsi3_no_power" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_cint_operand" "ri")))] "! TARGET_POWER" - "{sl|slw}%I2 %0,%1,%h2" - [(set_attr "length" "8")]) + "{sl|slw}%I2 %0,%1,%h2") (define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,x") @@ -3060,7 +3073,7 @@ (match_operand:SI 2 "reg_or_cint_operand" "ri")) (const_int 0))) (clobber (match_scratch:SI 3 "=r"))] - "! TARGET_POWER" + "! TARGET_POWER && ! TARGET_POWERPC64" "{sl|slw}%I2. %3,%1,%h2" [(set_attr "type" "delayed_compare")]) @@ -3085,7 +3098,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r") (ashift:SI (match_dup 1) (match_dup 2)))] - "! TARGET_POWER" + "! TARGET_POWER && ! TARGET_POWERPC64" "{sl|slw}%I2. %0,%1,%h2" [(set_attr "type" "delayed_compare")]) @@ -3105,7 +3118,7 @@ (match_operand:SI 3 "mask_operand" "T")) (const_int 0))) (clobber (match_scratch:SI 4 "=r"))] - "includes_lshift_p (operands[2], operands[3])" + "! TARGET_POWERPC64 && includes_lshift_p (operands[2], operands[3])" "{rlinm.|rlwinm.} %4,%1,%h2,%m3,%M3" [(set_attr "type" "delayed_compare")]) @@ -3118,7 +3131,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r") (and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "includes_lshift_p (operands[2], operands[3])" + "! TARGET_POWERPC64 && includes_lshift_p (operands[2], operands[3])" "{rlinm.|rlwinm.} %0,%1,%h2,%m3,%M3" [(set_attr "type" "delayed_compare")]) @@ -3178,7 +3191,7 @@ (match_operand:SI 2 "reg_or_cint_operand" "O,ri")) (const_int 0))) (clobber (match_scratch:SI 3 "=X,r"))] - "! TARGET_POWER" + "! TARGET_POWER && ! TARGET_POWERPC64" "@ mr. %1,%1 {sr|srw}%I2. %3,%1,%h2" @@ -3206,7 +3219,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (lshiftrt:SI (match_dup 1) (match_dup 2)))] - "! TARGET_POWER" + "! TARGET_POWER && ! TARGET_POWERPC64" "@ mr. %0,%1 {sr|srw}%I2. %0,%1,%h2" @@ -3228,7 +3241,7 @@ (match_operand:SI 3 "mask_operand" "T")) (const_int 0))) (clobber (match_scratch:SI 4 "=r"))] - "includes_rshift_p (operands[2], operands[3])" + "! TARGET_POWERPC64 && includes_rshift_p (operands[2], operands[3])" "{rlinm.|rlwinm.} %4,%1,%s2,%m3,%M3" [(set_attr "type" "delayed_compare")]) @@ -3241,7 +3254,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r") (and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "includes_rshift_p (operands[2], operands[3])" + "! TARGET_POWERPC64 && includes_rshift_p (operands[2], operands[3])" "{rlinm.|rlwinm.} %0,%1,%s2,%m3,%M3" [(set_attr "type" "delayed_compare")]) @@ -3733,10 +3746,10 @@ "") (define_expand "movsfcc" - [(set (match_operand:SF 0 "gpc_reg_operand" "=f") + [(set (match_operand:SF 0 "gpc_reg_operand" "") (if_then_else:SF (match_operand 1 "comparison_operator" "") - (match_operand:SF 2 "gpc_reg_operand" "f") - (match_operand:SF 3 "gpc_reg_operand" "f")))] + (match_operand:SF 2 "gpc_reg_operand" "") + (match_operand:SF 3 "gpc_reg_operand" "")))] "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" " { @@ -3980,10 +3993,10 @@ "") (define_expand "movdfcc" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f") + [(set (match_operand:DF 0 "gpc_reg_operand" "") (if_then_else:DF (match_operand 1 "comparison_operator" "") - (match_operand:DF 2 "gpc_reg_operand" "f") - (match_operand:DF 3 "gpc_reg_operand" "f")))] + (match_operand:DF 2 "gpc_reg_operand" "") + (match_operand:DF 3 "gpc_reg_operand" "")))] "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT" " { @@ -4079,7 +4092,7 @@ (clobber (match_dup 4)) (clobber (match_dup 5)) (clobber (reg:DF 76))])] - "TARGET_HARD_FLOAT" + "! TARGET_POWERPC64 && TARGET_HARD_FLOAT" " { operands[2] = force_reg (SImode, GEN_INT (0x43300000)); @@ -4096,7 +4109,7 @@ (clobber (match_operand:SI 4 "gpc_reg_operand" "=r")) (clobber (match_operand 5 "gpc_reg_operand" "=b")) (clobber (reg:DF 76))] - "TARGET_HARD_FLOAT" + "! TARGET_POWERPC64 && TARGET_HARD_FLOAT" "#" [(set_attr "length" "24")]) @@ -4108,7 +4121,7 @@ (clobber (match_operand:SI 4 "gpc_reg_operand" "")) (clobber (match_operand 5 "gpc_reg_operand" "")) (clobber (reg:DF 76))] - "TARGET_HARD_FLOAT" + "! TARGET_POWERPC64 && TARGET_HARD_FLOAT" [(set (match_dup 4) (xor:SI (match_dup 1) (match_dup 6))) @@ -4140,7 +4153,7 @@ (use (match_dup 3)) (clobber (match_dup 4)) (clobber (reg:DF 76))])] - "TARGET_HARD_FLOAT" + "! TARGET_POWERPC64 && TARGET_HARD_FLOAT" " { operands[2] = force_reg (SImode, GEN_INT (0x43300000)); @@ -4155,7 +4168,7 @@ (use (match_operand:DF 3 "gpc_reg_operand" "f")) (clobber (match_operand 4 "gpc_reg_operand" "=b")) (clobber (reg:DF 76))] - "TARGET_HARD_FLOAT" + "! TARGET_POWERPC64 && TARGET_HARD_FLOAT" "#" [(set_attr "length" "20")]) @@ -4166,7 +4179,7 @@ (use (match_operand:DF 3 "gpc_reg_operand" "")) (clobber (match_operand 4 "gpc_reg_operand" "")) (clobber (reg:DF 76))] - "TARGET_HARD_FLOAT" + "! TARGET_POWERPC64 && TARGET_HARD_FLOAT" [(set (match_dup 4) (unspec [(const_int 0)] 11)) (set (match_dup 5) @@ -4294,7 +4307,7 @@ "TARGET_HARD_FLOAT" " { - if (!TARGET_POWER2 && !TARGET_POWERPC) + if (! TARGET_POWER2 && ! TARGET_POWERPC) { emit_insn (gen_trunc_call (operands[0], operands[1], gen_rtx_SYMBOL_REF (Pmode, RS6000_ITRUNC))); @@ -4323,8 +4336,9 @@ (clobber (match_operand 3 "gpc_reg_operand" "")) (clobber (reg:DI 76))] "TARGET_HARD_FLOAT" - [(set (match_dup 2) - (sign_extend:DI (fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))) + [(clobber (match_dup 2)) + (set (subreg:SI (match_dup 2) 0) + (fix:SI (match_operand:DF 1 "gpc_reg_operand" ""))) (set (match_dup 3) (unspec [(const_int 0)] 11)) (set (match_dup 4) @@ -4433,8 +4447,8 @@ }") (define_insn "*fctiwz" - [(set (match_operand:DI 0 "gpc_reg_operand" "=f") - (sign_extend:DI (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))))] + [(set (subreg:SI (match_operand:DI 0 "gpc_reg_operand" "=f") 0) + (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))] "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT" "{fcirz|fctiwz} %0,%1" [(set_attr "type" "fp")]) @@ -5452,41 +5466,41 @@ (define_insn "*anddi3_internal2" [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x") (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r") - (match_operand:DI 2 "and64_operand" "r,K,J,S")) + (match_operand:DI 2 "and64_operand" "r,S,K,J")) (const_int 0))) (clobber (match_scratch:DI 3 "=r,r,r,r"))] "TARGET_POWERPC64" "@ and. %3,%1,%2 + rldic%B2. %3,%1,0,%S2 andi. %3,%1,%b2 - andis. %3,%1,%u2 - rldic%B2. %3,%1,0,%S2" - [(set_attr "type" "compare,compare,compare,delayed_compare")]) + andis. %3,%1,%u2" + [(set_attr "type" "compare,delayed_compare,compare,compare")]) (define_insn "*anddi3_internal3" [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x") (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r") - (match_operand:DI 2 "and64_operand" "r,K,J,S")) + (match_operand:DI 2 "and64_operand" "r,S,K,J")) (const_int 0))) (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") (and:DI (match_dup 1) (match_dup 2)))] "TARGET_POWERPC64" "@ and. %0,%1,%2 + rldic%B2. %0,%1,0,%S2 andi. %0,%1,%b2 - andis. %0,%1,%u2 - rldic%B2. %0,%1,0,%S2" - [(set_attr "type" "compare,compare,compare,delayed_compare")]) + andis. %0,%1,%u2" + [(set_attr "type" "compare,delayed_compare,compare,compare")]) (define_expand "iordi3" [(set (match_operand:DI 0 "gpc_reg_operand" "") (ior:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")))] + (match_operand:DI 2 "reg_or_u_cint_operand" "")))] "TARGET_POWERPC64" " { if (GET_CODE (operands[2]) == CONST_INT - && ! logical_operand (operands[2], DImode)) + && ! logical_u_operand (operands[2], DImode)) { HOST_WIDE_INT value = INTVAL (operands[2]); rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1])) @@ -5497,12 +5511,26 @@ emit_insn (gen_iordi3 (operands[0], tmp, GEN_INT (value & 0xffff))); DONE; } + else if (GET_CODE (operands[2]) == CONST_DOUBLE + && ! logical_u_operand (operands[2], DImode)) + { + HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]); + rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1])) + ? operands[0] : gen_reg_rtx (DImode)); + + emit_insn (gen_iordi3 (tmp, operands[1], + immed_double_const (value + & (~ (HOST_WIDE_INT) 0xffff), + 0, DImode))); + emit_insn (gen_iordi3 (operands[0], tmp, GEN_INT (value & 0xffff))); + DONE; + } }") (define_insn "*iordi3_internal1" [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r") (ior:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r") - (match_operand:DI 2 "logical_operand" "r,K,J")))] + (match_operand:DI 2 "logical_u_operand" "r,K,JF")))] "TARGET_POWERPC64" "@ or %0,%1,%2 @@ -5536,25 +5564,36 @@ (define_split [(set (match_operand:DI 0 "gpc_reg_operand" "") (ior:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "non_logical_cint_operand" "")))] + (match_operand:DI 2 "non_logical_u_cint_operand" "")))] "TARGET_POWERPC64" [(set (match_dup 0) (ior:DI (match_dup 1) (match_dup 3))) (set (match_dup 0) (ior:DI (match_dup 0) (match_dup 4)))] " { - operands[3] = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff)); - operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff); + if (GET_CODE (operands[2]) == CONST_DOUBLE) + { + HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]); + operands[3] = immed_double_const (value & (~ (HOST_WIDE_INT) 0xffff), + 0, DImode); + operands[4] = GEN_INT (value & 0xffff); + } + else + { + operands[3] = GEN_INT (INTVAL (operands[2]) + & (~ (HOST_WIDE_INT) 0xffff)); + operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff); + } }") (define_expand "xordi3" [(set (match_operand:DI 0 "gpc_reg_operand" "") (xor:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "reg_or_cint_operand" "")))] + (match_operand:DI 2 "reg_or_u_cint_operand" "")))] "TARGET_POWERPC64" " { if (GET_CODE (operands[2]) == CONST_INT - && ! logical_operand (operands[2], DImode)) + && ! logical_u_operand (operands[2], DImode)) { HOST_WIDE_INT value = INTVAL (operands[2]); rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1])) @@ -5565,12 +5604,26 @@ emit_insn (gen_xordi3 (operands[0], tmp, GEN_INT (value & 0xffff))); DONE; } + else if (GET_CODE (operands[2]) == CONST_DOUBLE + && ! logical_u_operand (operands[2], DImode)) + { + HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]); + rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1])) + ? operands[0] : gen_reg_rtx (DImode)); + + emit_insn (gen_xordi3 (tmp, operands[1], + immed_double_const (value + & (~ (HOST_WIDE_INT) 0xffff), + 0, DImode))); + emit_insn (gen_xordi3 (operands[0], tmp, GEN_INT (value & 0xffff))); + DONE; + } }") (define_insn "*xordi3_internal1" [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r") (xor:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r") - (match_operand:DI 2 "logical_operand" "r,K,J")))] + (match_operand:DI 2 "logical_u_operand" "r,K,JF")))] "TARGET_POWERPC64" "@ xor %0,%1,%2 @@ -5604,14 +5657,25 @@ (define_split [(set (match_operand:DI 0 "gpc_reg_operand" "") (xor:DI (match_operand:DI 1 "gpc_reg_operand" "") - (match_operand:DI 2 "non_logical_cint_operand" "")))] + (match_operand:DI 2 "non_logical_u_cint_operand" "")))] "TARGET_POWERPC64" [(set (match_dup 0) (xor:DI (match_dup 1) (match_dup 3))) (set (match_dup 0) (xor:DI (match_dup 0) (match_dup 4)))] " { - operands[3] = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff)); - operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff); + if (GET_CODE (operands[2]) == CONST_DOUBLE) + { + HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]); + operands[3] = immed_double_const (value & (~ (HOST_WIDE_INT) 0xffff), + 0, DImode); + operands[4] = GEN_INT (value & 0xffff); + } + else + { + operands[3] = GEN_INT (INTVAL (operands[2]) + & (~ (HOST_WIDE_INT) 0xffff)); + operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff); + } }") (define_insn "*eqvdi3_internal1" @@ -5763,14 +5827,14 @@ (define_insn "elf_high" [(set (match_operand:SI 0 "gpc_reg_operand" "=b") (high:SI (match_operand 1 "" "")))] - "TARGET_ELF && !TARGET_64BIT" + "TARGET_ELF && ! TARGET_64BIT" "{liu|lis} %0,%1@ha") (define_insn "elf_low" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") (match_operand 2 "" "")))] - "TARGET_ELF && !TARGET_64BIT" + "TARGET_ELF && ! TARGET_64BIT" "{cal|la} %0,%2@l(%1)") ;; Set up a register with a value from the GOT table @@ -5809,21 +5873,6 @@ "{l|lwz} %0,%a1@got(%2)" [(set_attr "type" "load")]) -;; Sometimes, though, the GOT `register' will be on the stack. Deal with -;; this case specially. -;; Force final to split this insn (if it hasn't been split already) to -;; avoid having to create a suitable output template. -(define_insn "*movsi_got_internal_mem" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (unspec [(match_operand:SI 1 "got_no_const_operand" "") - (match_operand:SI 2 "memory_operand" "m")] 8))] - "(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) - && flag_pic == 1 - && (reload_in_progress || reload_completed)" - "#" - [(set_attr "type" "load") - (set_attr "length" "8")]) - ;; Used by sched, shorten_branches and final when the GOT pseudo reg ;; didn't get allocated to a hard register. (define_split @@ -6018,7 +6067,7 @@ (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r") (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r") (match_dup 1))] - "" + "! TARGET_POWERPC64" "mr. %0,%1" [(set_attr "type" "compare")]) @@ -6160,7 +6209,8 @@ operands[1] = force_reg (SFmode, operands[1]); } - if (CONSTANT_P (operands[1]) && TARGET_HARD_FLOAT) + if (CONSTANT_P (operands[1]) && TARGET_HARD_FLOAT + && ! easy_fp_constant (operands[1], SFmode)) { operands[1] = force_const_mem (SFmode, operands[1]); if (! memory_address_p (SFmode, XEXP (operands[1], 0)) @@ -6322,8 +6372,8 @@ ;; The "??" is a kludge until we can figure out a more reasonable way ;; of handling these non-offsettable values. (define_insn "*movdf_hardfloat32" - [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,!r,!r,f,f,m") - (match_operand:DF 1 "input_operand" "r,o,r,G,H,F,f,m,f"))] + [(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 && (gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode))" @@ -6335,24 +6385,70 @@ abort (); case 0: /* We normally copy the low-numbered register first. However, if - the first register operand 0 is the same as the second register of - operand 1, we must copy in the opposite order. */ + the first register operand 0 is the same as the second register + of operand 1, we must copy in the opposite order. */ if (REGNO (operands[0]) == REGNO (operands[1]) + 1) return \"mr %L0,%L1\;mr %0,%1\"; else return \"mr %0,%1\;mr %L0,%L1\"; case 1: - /* If the low-address word is used in the address, we must load it - last. Otherwise, load it first. Note that we cannot have - auto-increment in that case since the address register is known to be - dead. */ - if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, - operands [1], 0)) - return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\"; + if (offsettable_memref_p (operands[1]) + || (GET_CODE (operands[1]) == MEM + && (GET_CODE (XEXP (operands[1], 0)) == LO_SUM + || GET_CODE (XEXP (operands[1], 0)) == PRE_INC + || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC))) + { + /* If the low-address word is used in the address, we must load + it last. Otherwise, load it first. Note that we cannot have + auto-increment in that case since the address register is + known to be dead. */ + if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, + operands[1], 0)) + return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\"; + else + return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\"; + } else - return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\"; + { + rtx addreg; + + addreg = find_addr_reg (XEXP (operands[1], 0)); + if (refers_to_regno_p (REGNO (operands[0]), + REGNO (operands[0]) + 1, + operands[1], 0)) + { + output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg); + output_asm_insn (\"{lx|lwzx} %L0,%1\", operands); + output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg); + return \"{lx|lwzx} %0,%1\"; + } + else + { + output_asm_insn (\"{lx|lwzx} %0,%1\", operands); + output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg); + output_asm_insn (\"{lx|lwzx} %L0,%1\", operands); + output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg); + return \"\"; + } + } case 2: - return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\"; + if (offsettable_memref_p (operands[0]) + || (GET_CODE (operands[0]) == MEM + && (GET_CODE (XEXP (operands[0], 0)) == LO_SUM + || GET_CODE (XEXP (operands[0], 0)) == PRE_INC + || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))) + return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\"; + else + { + rtx addreg; + + addreg = find_addr_reg (XEXP (operands[0], 0)); + output_asm_insn (\"{stx|stwx} %1,%0\", operands); + output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg); + output_asm_insn (\"{stx|stwx} %L1,%0\", operands); + output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg); + return \"\"; + } case 3: case 4: case 5: @@ -6366,7 +6462,7 @@ } }" [(set_attr "type" "*,load,store,*,*,*,fp,fpload,fpstore") - (set_attr "length" "8,8,8,8,12,16,*,*,*")]) + (set_attr "length" "8,16,16,8,12,16,*,*,*")]) (define_insn "*movdf_softfloat32" [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r") @@ -6575,13 +6671,14 @@ (set (match_dup 3) (match_dup 1))] " { + HOST_WIDE_INT value = INTVAL (operands[1]); operands[2] = gen_rtx_SUBREG (SImode, operands[0], WORDS_BIG_ENDIAN == 0); operands[3] = gen_rtx_SUBREG (SImode, operands[0], WORDS_BIG_ENDIAN != 0); #if HOST_BITS_PER_WIDE_INT == 32 - operands[4] = (INTVAL (operands[1]) & 0x80000000) ? constm1_rtx : const0_rtx; + operands[4] = (value & 0x80000000) ? constm1_rtx : const0_rtx; #else - operands[4] = (HOST_WIDE_INT) INTVAL (operands[1]) >> 32; - operands[1] = INTVAL (operands[1]) & 0xffffffff; + operands[4] = GEN_INT (value >> 32); + operands[1] = GEN_INT ((value & 0x7fffffff) - (value & 0x80000000)); #endif }") @@ -6680,9 +6777,12 @@ [(set (match_dup 0) (match_dup 2)) (set (match_dup 0) - (zero_extend:DI (subreg:SI (match_dup 0) 0)))] + (zero_extend:DI (match_dup 3)))] " -{ operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); }") +{ + operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); + operands[3] = gen_lowpart_common (SImode, operands[0]); +}") (define_split [(set (match_operand:DI 0 "gpc_reg_operand" "") @@ -6718,7 +6818,8 @@ (define_split [(set (match_operand:DI 0 "gpc_reg_operand" "") (match_operand:DI 1 "const_double_operand" ""))] - "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1" + "HOST_BITS_PER_WIDE_INT == 32 && TARGET_POWERPC64 + && num_insns_constant (operands[1], DImode) > 1" [(set (match_dup 0) (match_dup 2)) (set (match_dup 0) @@ -6729,29 +6830,40 @@ (match_dup 3)))] " { - HOST_WIDE_INT low; - HOST_WIDE_INT high; - if (GET_CODE (operands[1]) == CONST_DOUBLE) { - low = CONST_DOUBLE_LOW (operands[1]); - high = CONST_DOUBLE_HIGH (operands[1]); + operands[2] = GEN_INT (CONST_DOUBLE_HIGH (operands[1])); + operands[3] = immed_double_const (CONST_DOUBLE_LOW (operands[1]), + 0, DImode); } else -#if HOST_BITS_PER_WIDE_INT == 32 { - low = INTVAL (operands[1]); - high = (low < 0) ? ~0 : 0; + HOST_WIDE_INT value = INTVAL (operands[1]); + operands[2] = (value & 0x80000000) ? constm1_rtx : const0_rtx; + operands[3] = immed_double_const (value, 0, DImode); } -#else - { - low = INTVAL (operands[1]) & 0xffffffff; - high = (HOST_WIDE_INT) INTVAL (operands[1]) >> 32; - } -#endif +}") - operands[2] = GEN_INT (high); - operands[3] = GEN_INT (low); +(define_split + [(set (match_operand:DI 0 "gpc_reg_operand" "") + (match_operand:DI 1 "const_int_operand" ""))] + "HOST_BITS_PER_WIDE_INT != 32 && TARGET_POWERPC64 + && num_insns_constant (operands[1], DImode) > 1" + [(set (match_dup 0) + (match_dup 2)) + (set (match_dup 0) + (ashift:DI (match_dup 0) + (const_int 32))) + (set (match_dup 0) + (ior:DI (match_dup 0) + (match_dup 3)))] + " +{ +#if HOST_BITS_PER_WIDE_INT != 32 + HOST_WIDE_INT value = INTVAL (operands[1]); + operands[2] = GEN_INT (value >> 32); + operands[3] = GEN_INT ((value & 0x7fffffff) - (value & 0x80000000)); +#endif }") (define_insn "" @@ -6852,7 +6964,7 @@ [(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"))] - "TARGET_STRING && !TARGET_POWER && ! TARGET_POWERPC64 + "TARGET_STRING && ! TARGET_POWER && ! TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))" "* { @@ -7082,7 +7194,7 @@ [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")) (match_operand:SI 2 "gpc_reg_operand" "r")) (clobber (match_scratch:SI 3 "X"))])] - "TARGET_STRING && !TARGET_POWER" + "TARGET_STRING && ! TARGET_POWER" "{stsi|stswi} %2,%1,%O0" [(set_attr "type" "store")]) @@ -7163,7 +7275,7 @@ (clobber (reg:SI 11)) (clobber (reg:SI 12)) (clobber (match_scratch:SI 5 "X"))] - "TARGET_STRING && !TARGET_POWER + "TARGET_STRING && ! TARGET_POWER && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) || INTVAL (operands[2]) == 0) && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12) && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12) @@ -7222,7 +7334,7 @@ (clobber (reg:SI 11)) (clobber (reg:SI 12)) (clobber (match_scratch:SI 5 "X"))] - "TARGET_STRING && !TARGET_POWER + "TARGET_STRING && ! TARGET_POWER && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32 && (REGNO (operands[0]) < 7 || REGNO (operands[0]) > 12) && (REGNO (operands[1]) < 7 || REGNO (operands[1]) > 12) @@ -7275,7 +7387,7 @@ (clobber (reg:SI 11)) (clobber (reg:SI 12)) (clobber (match_scratch:SI 5 "X"))] - "TARGET_STRING && !TARGET_POWER + "TARGET_STRING && ! TARGET_POWER && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16 && (REGNO (operands[0]) < 9 || REGNO (operands[0]) > 12) && (REGNO (operands[1]) < 9 || REGNO (operands[1]) > 12) @@ -7292,7 +7404,7 @@ (use (match_operand 3 "" "")) (clobber (match_scratch:DI 4 "")) (clobber (match_scratch:SI 5 ""))])] - "TARGET_STRING && !TARGET_64BIT" + "TARGET_STRING && ! TARGET_64BIT" "") (define_insn "" @@ -7302,7 +7414,7 @@ (use (match_operand:SI 3 "immediate_operand" "i")) (clobber (match_scratch:DI 4 "=&r")) (clobber (match_scratch:SI 5 "=q"))] - "TARGET_STRING && TARGET_POWER && !TARGET_64BIT + "TARGET_STRING && TARGET_POWER && ! TARGET_64BIT && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8" "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" [(set_attr "type" "load") @@ -7315,7 +7427,7 @@ (use (match_operand:SI 3 "immediate_operand" "i")) (clobber (match_scratch:DI 4 "=&r")) (clobber (match_scratch:SI 5 "X"))] - "TARGET_STRING && !TARGET_POWER && !TARGET_64BIT + "TARGET_STRING && ! TARGET_POWER && ! TARGET_64BIT && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8" "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" [(set_attr "type" "load") @@ -7352,7 +7464,7 @@ (use (match_operand:SI 3 "immediate_operand" "i")) (clobber (match_scratch:SI 4 "=&r")) (clobber (match_scratch:SI 5 "X"))] - "TARGET_STRING && !TARGET_POWER + "TARGET_STRING && ! TARGET_POWER && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4" "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2" [(set_attr "type" "load") @@ -7759,7 +7871,8 @@ rs6000_output_load_toc_table (asm_out_file, 30); return \"\"; }" - [(set_attr "type" "load")]) + [(set_attr "type" "load") + (set_attr "length" "24")]) ;; A function pointer under AIX is a pointer to a data area whose first word ;; contains the actual address of the function, whose second word contains a @@ -8739,7 +8852,7 @@ (define_insn "" [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y") (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "reg_or_u_short_operand" "rI")))] + (match_operand:SI 2 "reg_or_u_short_operand" "rK")))] "" "{cmpl%I2|cmplw%I2} %0,%1,%W2" [(set_attr "type" "compare")]) @@ -8747,7 +8860,7 @@ (define_insn "" [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y") (compare:CCUNS (match_operand:DI 1 "gpc_reg_operand" "r") - (match_operand:DI 2 "reg_or_u_short_operand" "rI")))] + (match_operand:DI 2 "reg_or_u_short_operand" "rK")))] "" "cmpld%I2 %0,%1,%W2" [(set_attr "type" "compare")]) @@ -8837,7 +8950,7 @@ (const_int 0))) (set (match_operand:SI 3 "gpc_reg_operand" "=r") (match_op_dup 1 [(match_dup 2) (const_int 0)]))] - "" + "! TARGET_POWERPC64" "%D1mfcr %3\;{rlinm.|rlwinm.} %3,%3,%J1,1" [(set_attr "type" "delayed_compare") (set_attr "length" "12")]) @@ -8965,7 +9078,7 @@ (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r") (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))) (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))] - "" + "! TARGET_POWERPC64" "@ xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0 {sfi|subfic} %3,%1,0\;{ae|adde} %0,%3,%1 @@ -8997,7 +9110,7 @@ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r") (eq:SI (match_dup 1) (match_dup 2))) (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))] - "" + "! TARGET_POWERPC64" "@ xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0 {sfi|subfic} %3,%1,0\;{ae.|adde.} %0,%3,%1 @@ -9047,7 +9160,7 @@ (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I")) (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r"))) (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))] - "" + "! TARGET_POWERPC64" "@ xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze|addze} %0,%3 {sfi|subfic} %4,%1,0\;{aze|addze} %0,%3 @@ -9065,7 +9178,7 @@ (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r")) (const_int 0))) (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))] - "" + "! TARGET_POWERPC64" "@ xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3 {sfi|subfic} %4,%1,0\;{aze.|addze.} %4,%3 @@ -9086,7 +9199,7 @@ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r") (plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r"))] - "" + "! TARGET_POWERPC64" "@ xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %0,%3 {sfi|subfic} %4,%1,0\;{aze.|addze.} %0,%3 @@ -9100,7 +9213,7 @@ [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r") (neg:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r") (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,J,I"))))] - "" + "! TARGET_POWERPC64" "@ xor %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0 {ai|addic} %0,%1,-1\;{sfe|subfe} %0,%0,%0 @@ -9116,7 +9229,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_POWER && ! TARGET_POWERPC64" "{ai|addic} %2,%1,-1\;{sfe|subfe} %0,%2,%1" [(set_attr "length" "8")]) @@ -9137,7 +9250,7 @@ (const_int 31)) (match_operand:SI 2 "gpc_reg_operand" "r"))) (clobber (match_scratch:SI 3 "=&r"))] - "" + "! TARGET_POWERPC64" "{ai|addic} %3,%1,-1\;{aze|addze} %0,%2" [(set_attr "length" "8")]) @@ -9161,7 +9274,7 @@ (match_operand:SI 2 "gpc_reg_operand" "r")) (const_int 0))) (clobber (match_scratch:SI 3 "=&r"))] - "" + "! TARGET_POWERPC64" "{ai|addic} %3,%1,-1\;{aze.|addze.} %3,%2" [(set_attr "type" "compare") (set_attr "length" "8")]) @@ -9192,7 +9305,7 @@ (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31)) (match_dup 2))) (clobber (match_scratch:SI 3 "=&r"))] - "" + "! TARGET_POWERPC64" "{ai|addic} %3,%1,-1\;{aze.|addze.} %0,%2" [(set_attr "type" "compare") (set_attr "length" "8")]) @@ -9299,11 +9412,32 @@ [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_short_operand" "rI")))] - "" + "! TARGET_POWERPC64" "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0" [(set_attr "length" "12")]) (define_insn "" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (leu:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (match_operand:DI 2 "reg_or_short_operand" "rI")))] + "TARGET_POWERPC64" + "subf%I2c %0,%1,%2\;li %0,0\;adde %0,%0,%0" + [(set_attr "length" "12")]) + +(define_insn "" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (compare:CC + (leu:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (match_operand:DI 2 "reg_or_short_operand" "rI")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (leu:DI (match_dup 1) (match_dup 2)))] + "TARGET_POWERPC64" + "subf%I2c %0,%1,%2\;li %0,0\;adde. %0,%0,%0" + [(set_attr "type" "compare") + (set_attr "length" "12")]) + +(define_insn "" [(set (match_operand:CC 3 "cc_reg_operand" "=x") (compare:CC (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r") @@ -9311,18 +9445,31 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r") (leu:SI (match_dup 1) (match_dup 2)))] - "" + "! TARGET_POWERPC64" "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0" [(set_attr "type" "compare") (set_attr "length" "12")]) (define_insn "" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (compare:CC + (leu:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (match_operand:DI 2 "reg_or_short_operand" "rI")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (leu:DI (match_dup 1) (match_dup 2)))] + "TARGET_POWERPC64" + "subf%I2c %0,%1,%2\;li %0,0\;adde. %0,%0,%0" + [(set_attr "type" "compare") + (set_attr "length" "12")]) + +(define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_short_operand" "rI")) (match_operand:SI 3 "gpc_reg_operand" "r"))) (clobber (match_scratch:SI 4 "=&r"))] - "" + "! TARGET_POWERPC64" "{sf%I2|subf%I2c} %4,%1,%2\;{aze|addze} %0,%3" [(set_attr "length" "8")]) @@ -9334,7 +9481,7 @@ (match_operand:SI 3 "gpc_reg_operand" "r")) (const_int 0))) (clobber (match_scratch:SI 4 "=&r"))] - "" + "! TARGET_POWERPC64" "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %4,%3" [(set_attr "type" "compare") (set_attr "length" "8")]) @@ -9349,7 +9496,7 @@ (set (match_operand:SI 0 "gpc_reg_operand" "=r") (plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (clobber (match_scratch:SI 4 "=&r"))] - "" + "! TARGET_POWERPC64" "{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %0,%3" [(set_attr "type" "compare") (set_attr "length" "8")]) @@ -9358,7 +9505,7 @@ [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (neg:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_short_operand" "rI"))))] - "" + "! TARGET_POWERPC64" "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0" [(set_attr "length" "12")]) @@ -9369,7 +9516,7 @@ (match_operand:SI 2 "reg_or_short_operand" "rI"))) (match_operand:SI 3 "gpc_reg_operand" "r"))) (clobber (match_scratch:SI 4 "=&r"))] - "" + "! TARGET_POWERPC64" "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4" [(set_attr "length" "12")]) @@ -9382,7 +9529,7 @@ (match_operand:SI 3 "gpc_reg_operand" "r")) (const_int 0))) (clobber (match_scratch:SI 4 "=&r"))] - "" + "! TARGET_POWERPC64" "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4" [(set_attr "type" "compare") (set_attr "length" "12")]) @@ -9398,7 +9545,7 @@ (set (match_operand:SI 0 "gpc_reg_operand" "=r") (and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3))) (clobber (match_scratch:SI 4 "=&r"))] - "" + "! TARGET_POWERPC64" "{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4" [(set_attr "type" "compare") (set_attr "length" "12")]) @@ -9474,7 +9621,7 @@ [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))] - "" + "! TARGET_POWERPC64" "@ {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg %0,%0 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg %0,%0" @@ -9488,7 +9635,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (ltu:SI (match_dup 1) (match_dup 2)))] - "" + "! TARGET_POWERPC64" "@ {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg. %0,%0 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0" @@ -9501,7 +9648,7 @@ (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")) (match_operand:SI 3 "reg_or_short_operand" "rI,rI"))) (clobber (match_scratch:SI 4 "=&r,&r"))] - "" + "! TARGET_POWERPC64" "@ {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3" @@ -9515,7 +9662,7 @@ (match_operand:SI 3 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:SI 4 "=&r,&r"))] - "" + "! TARGET_POWERPC64" "@ {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3" @@ -9532,7 +9679,7 @@ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (clobber (match_scratch:SI 4 "=&r,&r"))] - "" + "! TARGET_POWERPC64" "@ {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3" @@ -9543,7 +9690,7 @@ [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (neg:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))))] - "" + "! TARGET_POWERPC64" "@ {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0 {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0" @@ -9619,6 +9766,7 @@ [(set_attr "length" "12")]) ;; This is (and (neg (ge X (const_int 0))) Y). +;; srawi sign-extends, so these patterrns are 64-bit safe. (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (and:SI (neg:SI @@ -9632,6 +9780,18 @@ [(set_attr "length" "8")]) (define_insn "" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (and:DI (neg:DI + (lshiftrt:DI + (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) + (const_int 63))) + (match_operand:DI 2 "gpc_reg_operand" "r"))) + (clobber (match_scratch:DI 3 "=&r"))] + "TARGET_POWERPC64" + "sradi %3,%1,63\;andc %0,%2,%3" + [(set_attr "length" "8")]) + +(define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x") (compare:CC (and:SI (neg:SI @@ -9647,6 +9807,21 @@ (set_attr "length" "8")]) (define_insn "" + [(set (match_operand:CC 0 "cc_reg_operand" "=x") + (compare:CC + (and:DI (neg:DI + (lshiftrt:DI + (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) + (const_int 63))) + (match_operand:DI 2 "gpc_reg_operand" "r")) + (const_int 0))) + (clobber (match_scratch:DI 3 "=&r"))] + "TARGET_POWERPC64" + "sradi %3,%1,63\;andc. %3,%2,%3" + [(set_attr "type" "compare") + (set_attr "length" "8")]) + +(define_insn "" [(set (match_operand:CC 4 "cc_reg_operand" "=x") (compare:CC (and:SI (neg:SI @@ -9666,16 +9841,45 @@ (set_attr "length" "8")]) (define_insn "" + [(set (match_operand:CC 4 "cc_reg_operand" "=x") + (compare:CC + (and:DI (neg:DI + (lshiftrt:DI + (not:DI (match_operand:DI 1 "gpc_reg_operand" "r")) + (const_int 63))) + (match_operand:DI 2 "gpc_reg_operand" "r")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (and:DI (neg:DI (lshiftrt:SI (not:DI (match_dup 1)) + (const_int 63))) + (match_dup 2))) + (clobber (match_scratch:SI 3 "=&r"))] + "TARGET_POWERPC64" + "sradi %3,%1,63\;andc. %0,%2,%3" + [(set_attr "type" "compare") + (set_attr "length" "8")]) + +(define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))] - "" + "! TARGET_POWERPC64" "@ {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0 {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0" [(set_attr "length" "12")]) (define_insn "" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + (geu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_neg_short_operand" "r,P")))] + "TARGET_POWERPC64" + "@ + subfc %0,%2,%1\;li %0,0\;adde %0,%0,%0 + addic %0,%1,%n2\;li %0,0\;adde %0,%0,%0" + [(set_attr "length" "12")]) + +(define_insn "" [(set (match_operand:CC 3 "cc_reg_operand" "=x,x") (compare:CC (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") @@ -9683,7 +9887,7 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (geu:SI (match_dup 1) (match_dup 2)))] - "" + "! TARGET_POWERPC64" "@ {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0 {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0" @@ -9691,12 +9895,27 @@ (set_attr "length" "12")]) (define_insn "" + [(set (match_operand:CC 3 "cc_reg_operand" "=x,x") + (compare:CC + (geu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_neg_short_operand" "r,P")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + (geu:DI (match_dup 1) (match_dup 2)))] + "TARGET_POWERPC64" + "@ + subfc %0,%2,%1\;li %0,0\;adde. %0,%0,%0 + addic %0,%1,%n2\;li %0,0\;adde. %0,%0,%0" + [(set_attr "type" "compare") + (set_attr "length" "12")]) + +(define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "reg_or_neg_short_operand" "r,P")) (match_operand:SI 3 "gpc_reg_operand" "r,r"))) (clobber (match_scratch:SI 4 "=&r,&r"))] - "" + "! TARGET_POWERPC64" "@ {sf|subfc} %4,%2,%1\;{aze|addze} %0,%3 {ai|addic} %4,%1,%n2\;{aze|addze} %0,%3" @@ -9710,7 +9929,7 @@ (match_operand:SI 3 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:SI 4 "=&r,&r"))] - "" + "! TARGET_POWERPC64" "@ {sf|subfc} %4,%2,%1\;{aze.|addze.} %4,%3 {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3" @@ -9727,7 +9946,7 @@ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (clobber (match_scratch:SI 4 "=&r,&r"))] - "" + "! TARGET_POWERPC64" "@ {sf|subfc} %4,%2,%1\;{aze.|addze.} %0,%3 {ai|addic} %4,%1,%n2\;{aze.|addze.} %0,%3" @@ -9738,7 +9957,7 @@ [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (neg:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "reg_or_short_operand" "r,I"))))] - "" + "! TARGET_POWERPC64" "@ {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0 {sfi|subfic} %0,%1,-1\;{a%I2|add%I2c} %0,%0,%2\;{sfe|subfe} %0,%0,%0" @@ -9751,7 +9970,7 @@ (match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))) (match_operand:SI 3 "gpc_reg_operand" "r,r"))) (clobber (match_scratch:SI 4 "=&r,&r"))] - "" + "! TARGET_POWERPC64" "@ {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc %0,%3,%4" @@ -9766,7 +9985,7 @@ (match_operand:SI 3 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:SI 4 "=&r,&r"))] - "" + "! TARGET_POWERPC64" "@ {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4" @@ -9784,7 +10003,7 @@ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3))) (clobber (match_scratch:SI 4 "=&r,&r"))] - "" + "! TARGET_POWERPC64" "@ {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4 {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %0,%3,%4" @@ -9795,11 +10014,19 @@ [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") (const_int 0)))] - "" + "! TARGET_POWERPC64" "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri|srwi} %0,%0,31" [(set_attr "length" "12")]) (define_insn "" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (const_int 0)))] + "TARGET_POWERPC64" + "subfic %0,%1,0\;addme %0,%0\;srdi %0,%0,63" + [(set_attr "length" "12")]) + +(define_insn "" [(set (match_operand:CC 2 "cc_reg_operand" "=x") (compare:CC (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") @@ -9807,12 +10034,25 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r") (gt:SI (match_dup 1) (const_int 0)))] - "" + "! TARGET_POWERPC64" "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri.|srwi.} %0,%0,31" [(set_attr "type" "delayed_compare") (set_attr "length" "12")]) (define_insn "" + [(set (match_operand:CC 2 "cc_reg_operand" "=x") + (compare:CC + (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (const_int 0)) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (gt:DI (match_dup 1) (const_int 0)))] + "TARGET_POWERPC64" + "subfic %0,%1,0\;addme %0,%0\;srdi. %0,%0,63" + [(set_attr "type" "delayed_compare") + (set_attr "length" "12")]) + +(define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_short_operand" "r")))] @@ -9839,11 +10079,21 @@ (const_int 0)) (match_operand:SI 2 "gpc_reg_operand" "r"))) (clobber (match_scratch:SI 3 "=&r"))] - "" + "! TARGET_POWERPC64" "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze|addze} %0,%2" [(set_attr "length" "12")]) (define_insn "" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (const_int 0)) + (match_operand:DI 2 "gpc_reg_operand" "r"))) + (clobber (match_scratch:DI 3 "=&r"))] + "TARGET_POWERPC64" + "addc %3,%1,%1\;subfe %3,%1,%3\;addze %0,%2" + [(set_attr "length" "12")]) + +(define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x") (compare:CC (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") @@ -9851,12 +10101,25 @@ (match_operand:SI 2 "gpc_reg_operand" "r")) (const_int 0))) (clobber (match_scratch:SI 3 "=&r"))] - "" + "! TARGET_POWERPC64" "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %3,%2" [(set_attr "type" "compare") (set_attr "length" "12")]) (define_insn "" + [(set (match_operand:CC 0 "cc_reg_operand" "=x") + (compare:CC + (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (const_int 0)) + (match_operand:DI 2 "gpc_reg_operand" "r")) + (const_int 0))) + (clobber (match_scratch:DI 3 "=&r"))] + "TARGET_POWERPC64" + "addc %3,%1,%1\;subfe %3,%1,%3\;addze. %3,%2" + [(set_attr "type" "compare") + (set_attr "length" "12")]) + +(define_insn "" [(set (match_operand:CC 4 "cc_reg_operand" "=x") (compare:CC (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") @@ -9866,12 +10129,27 @@ (set (match_operand:SI 0 "gpc_reg_operand" "=r") (plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2))) (clobber (match_scratch:SI 3 "=&r"))] - "" + "! TARGET_POWERPC64" "{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %0,%2" [(set_attr "type" "compare") (set_attr "length" "12")]) (define_insn "" + [(set (match_operand:CC 4 "cc_reg_operand" "=x") + (compare:CC + (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (const_int 0)) + (match_operand:DI 2 "gpc_reg_operand" "r")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2))) + (clobber (match_scratch:DI 3 "=&r"))] + "TARGET_POWERPC64" + "addc %3,%1,%1\;subfe %3,%1,%3\;addze. %0,%2" + [(set_attr "type" "compare") + (set_attr "length" "12")]) + +(define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_short_operand" "r")) @@ -9913,11 +10191,19 @@ [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") (const_int 0))))] - "" + "! TARGET_POWERPC64" "{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{srai|srawi} %0,%0,31" [(set_attr "length" "12")]) (define_insn "" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (neg:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (const_int 0))))] + "TARGET_POWERPC64" + "subfic %0,%1,0\;addme %0,%0\;sradi} %0,%0,63" + [(set_attr "length" "12")]) + +(define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_short_operand" "r"))))] @@ -9929,11 +10215,19 @@ [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_short_operand" "rI")))] - "" + "! TARGET_POWERPC64" "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg %0,%0" [(set_attr "length" "12")]) (define_insn "" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (match_operand:DI 2 "reg_or_short_operand" "rI")))] + "TARGET_POWERPC64" + "subf%I2c %0,%1,%2\;subfe %0,%0,%0\;neg %0,%0" + [(set_attr "length" "12")]) + +(define_insn "" [(set (match_operand:CC 3 "cc_reg_operand" "=x") (compare:CC (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r") @@ -9941,24 +10235,49 @@ (const_int 0))) (set (match_operand:SI 0 "gpc_reg_operand" "=r") (gtu:SI (match_dup 1) (match_dup 2)))] - "" + "! TARGET_POWERPC64" "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0" [(set_attr "type" "compare") (set_attr "length" "12")]) (define_insn "" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (compare:CC + (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (match_operand:DI 2 "reg_or_short_operand" "rI")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "=r") + (gtu:DI (match_dup 1) (match_dup 2)))] + "TARGET_POWERPC64" + "subf%I2c %0,%1,%2\;subfe %0,%0,%0\;neg. %0,%0" + [(set_attr "type" "compare") + (set_attr "length" "12")]) + +(define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") (match_operand:SI 2 "reg_or_short_operand" "I,rI")) (match_operand:SI 3 "reg_or_short_operand" "r,rI"))) (clobber (match_scratch:SI 4 "=&r,&r"))] - "" + "! TARGET_POWERPC64" "@ {ai|addic} %4,%1,%k2\;{aze|addze} %0,%3 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf%I3|subf%I3c} %0,%4,%3" [(set_attr "length" "8,12")]) (define_insn "" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_short_operand" "I,rI")) + (match_operand:DI 3 "reg_or_short_operand" "r,rI"))) + (clobber (match_scratch:DI 4 "=&r,&r"))] + "TARGET_POWERPC64" + "@ + addic %4,%1,%k2\;addze %0,%3 + subf%I2c %4,%1,%2\;subfe %4,%4,%4\;subf%I3c %0,%4,%3" + [(set_attr "length" "8,12")]) + +(define_insn "" [(set (match_operand:CC 0 "cc_reg_operand" "=x,x") (compare:CC (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") @@ -9966,7 +10285,7 @@ (match_operand:SI 3 "gpc_reg_operand" "r,r")) (const_int 0))) (clobber (match_scratch:SI 4 "=&r,&r"))] - "" + "! TARGET_POWERPC64" "@ {ai|addic} %4,%1,%k2\;{aze.|addze.} %4,%3 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3" @@ -9974,6 +10293,21 @@ (set_attr "length" "8,12")]) (define_insn "" + [(set (match_operand:CC 0 "cc_reg_operand" "=x,x") + (compare:CC + (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_short_operand" "I,r")) + (match_operand:DI 3 "gpc_reg_operand" "r,r")) + (const_int 0))) + (clobber (match_scratch:DI 4 "=&r,&r"))] + "TARGET_POWERPC64" + "@ + addic %4,%1,%k2\;addze. %4,%3 + subf%I2c %4,%1,%2\;subfe %4,%4,%4\;subfc. %4,%4,%3" + [(set_attr "type" "compare") + (set_attr "length" "8,12")]) + +(define_insn "" [(set (match_operand:CC 5 "cc_reg_operand" "=x,x") (compare:CC (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") @@ -9983,7 +10317,7 @@ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (clobber (match_scratch:SI 4 "=&r,&r"))] - "" + "! TARGET_POWERPC64" "@ {ai|addic} %4,%1,%k2\;{aze.|addze.} %0,%3 {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %0,%4,%3" @@ -9991,12 +10325,37 @@ (set_attr "length" "8,12")]) (define_insn "" + [(set (match_operand:CC 5 "cc_reg_operand" "=x,x") + (compare:CC + (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") + (match_operand:DI 2 "reg_or_short_operand" "I,r")) + (match_operand:DI 3 "gpc_reg_operand" "r,r")) + (const_int 0))) + (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + (plus:DI (gtu:DI (match_dup 1) (match_dup 2)) (match_dup 3))) + (clobber (match_scratch:DI 4 "=&r,&r"))] + "TARGET_POWERPC64" + "@ + addic %4,%1,%k2\;addze. %0,%3 + subf%I2c %4,%1,%2\;subfe %4,%4,%4\;subfc. %0,%4,%3" + [(set_attr "type" "compare") + (set_attr "length" "8,12")]) + +(define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (neg:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_short_operand" "rI"))))] - "" + "! TARGET_POWERPC64" "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0" [(set_attr "length" "8")]) + +(define_insn "" + [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + (neg:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r") + (match_operand:DI 2 "reg_or_short_operand" "rI"))))] + "TARGET_POWERPC64" + "subf%I2c %0,%1,%2\;subfe %0,%0,%0" + [(set_attr "length" "8")]) ;; Define both directions of branch and return. If we need a reload ;; register, we'd rather use CR0 since it is much easier to copy a @@ -10080,17 +10439,29 @@ "{br|blr}" [(set_attr "type" "jmpreg")]) -(define_insn "indirect_jump" - [(set (pc) (match_operand:SI 0 "register_operand" "c,l"))] +(define_expand "indirect_jump" + [(set (pc) (match_operand 0 "register_operand" ""))] "" + " +{ + if (TARGET_32BIT) + emit_jump_insn (gen_indirect_jumpsi (operands[0])); + else + emit_jump_insn (gen_indirect_jumpdi (operands[0])); + DONE; +}") + +(define_insn "indirect_jumpsi" + [(set (pc) (match_operand:SI 0 "register_operand" "c,l"))] + "TARGET_32BIT" "@ bctr {br|blr}" [(set_attr "type" "jmpreg")]) -(define_insn "" +(define_insn "indirect_jumpdi" [(set (pc) (match_operand:DI 0 "register_operand" "c,l"))] - "TARGET_POWERPC64" + "TARGET_64BIT" "@ bctr {br|blr}" @@ -10116,7 +10487,7 @@ (match_dup 2))) (parallel [(set (pc) (match_dup 3)) (use (label_ref (match_operand 1 "" "")))])] - "" + "TARGET_32BIT" " { operands[0] = force_reg (SImode, operands[0]); operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (VOIDmode, operands[1])); @@ -10129,7 +10500,7 @@ (match_dup 2))) (parallel [(set (pc) (match_dup 3)) (use (label_ref (match_operand 1 "" "")))])] - "" + "TARGET_64BIT" " { operands[0] = force_reg (DImode, operands[0]); operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (VOIDmode, operands[1])); @@ -10140,7 +10511,7 @@ [(set (pc) (match_operand:SI 0 "register_operand" "c,l")) (use (label_ref (match_operand 1 "" "")))] - "" + "TARGET_32BIT" "@ bctr {br|blr}" @@ -10150,7 +10521,7 @@ [(set (pc) (match_operand:DI 0 "register_operand" "c,l")) (use (label_ref (match_operand 1 "" "")))] - "TARGET_POWERPC64" + "TARGET_64BIT" "@ bctr {br|blr}" @@ -10165,6 +10536,19 @@ ;; so loop.c knows what to generate. (define_expand "decrement_and_branch_on_count" + [(use (match_operand 0 "register_operand" "")) + (use (label_ref (match_operand 1 "" "")))] + "" + " +{ + if (TARGET_POWERPC64) + emit_jump_insn (gen_ctrdi (operands[0], operands[1])); + else + emit_jump_insn (gen_ctrsi (operands[0], operands[1])); + DONE; +}") + +(define_expand "ctrsi" [(parallel [(set (pc) (if_then_else (ne (match_operand:SI 0 "register_operand" "") (const_int 1)) (label_ref (match_operand 1 "" "")) @@ -10174,16 +10558,29 @@ (const_int -1))) (clobber (match_scratch:CC 2 "")) (clobber (match_scratch:SI 3 ""))])] - "" + "! TARGET_POWERPC64" + "") + +(define_expand "ctrdi" + [(parallel [(set (pc) (if_then_else (ne (match_operand:DI 0 "register_operand" "") + (const_int 1)) + (label_ref (match_operand 1 "" "")) + (pc))) + (set (match_dup 0) + (plus:DI (match_dup 0) + (const_int -1))) + (clobber (match_scratch:CC 2 "")) + (clobber (match_scratch:DI 3 ""))])] + "TARGET_POWERPC64" "") ;; We need to be able to do this for any operand, including MEM, or we ;; will cause reload to blow up since we don't allow output reloads on ;; JUMP_INSNs. -;; In order that the length attribute is calculated correctly, the +;; For the length attribute to be calculated correctly, the ;; label MUST be operand 0. -(define_insn "" +(define_insn "*ctrsi_internal1" [(set (pc) (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r") (const_int 1)) @@ -10194,7 +10591,7 @@ (const_int -1))) (clobber (match_scratch:CC 3 "=X,&x,&x")) (clobber (match_scratch:SI 4 "=X,X,r"))] - "" + "! TARGET_POWERPC64" "* { if (which_alternative != 0) @@ -10207,7 +10604,7 @@ [(set_attr "type" "branch") (set_attr "length" "*,12,16")]) -(define_insn "" +(define_insn "*ctrsi_internal2" [(set (pc) (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r") (const_int 1)) @@ -10218,7 +10615,55 @@ (const_int -1))) (clobber (match_scratch:CC 3 "=X,&x,&x")) (clobber (match_scratch:SI 4 "=X,X,r"))] - "" + "! TARGET_POWERPC64" + "* +{ + if (which_alternative != 0) + return \"#\"; + else if (get_attr_length (insn) == 8) + return \"bdz %l0\"; + else + return \"{bdn|bdnz} %$+8\;b %l0\"; +}" + [(set_attr "type" "branch") + (set_attr "length" "*,12,16")]) + +(define_insn "*ctrdi_internal1" + [(set (pc) + (if_then_else (ne (match_operand:DI 1 "register_operand" "c,*r,*r") + (const_int 1)) + (label_ref (match_operand 0 "" "")) + (pc))) + (set (match_operand:DI 2 "register_operand" "=1,*r,m*q*c*l") + (plus:DI (match_dup 1) + (const_int -1))) + (clobber (match_scratch:CC 3 "=X,&x,&x")) + (clobber (match_scratch:DI 4 "=X,X,r"))] + "TARGET_POWERPC64" + "* +{ + if (which_alternative != 0) + return \"#\"; + else if (get_attr_length (insn) == 8) + return \"{bdn|bdnz} %l0\"; + else + return \"bdz %$+8\;b %l0\"; +}" + [(set_attr "type" "branch") + (set_attr "length" "*,12,16")]) + +(define_insn "*ctrdi_internal2" + [(set (pc) + (if_then_else (ne (match_operand:DI 1 "register_operand" "c,*r,*r") + (const_int 1)) + (pc) + (label_ref (match_operand 0 "" "")))) + (set (match_operand:DI 2 "register_operand" "=1,*r,m*q*c*l") + (plus:DI (match_dup 1) + (const_int -1))) + (clobber (match_scratch:CC 3 "=X,&x,&x")) + (clobber (match_scratch:DI 4 "=X,X,r"))] + "TARGET_POWERPC64" "* { if (which_alternative != 0) @@ -10232,7 +10677,8 @@ (set_attr "length" "*,12,16")]) ;; Similar, but we can use GE since we have a REG_NONNEG. -(define_insn "" + +(define_insn "*ctrsi_internal3" [(set (pc) (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r") (const_int 0)) @@ -10243,7 +10689,7 @@ (const_int -1))) (clobber (match_scratch:CC 3 "=X,&x,&X")) (clobber (match_scratch:SI 4 "=X,X,r"))] - "find_reg_note (insn, REG_NONNEG, 0)" + "! TARGET_POWERPC64 && find_reg_note (insn, REG_NONNEG, 0)" "* { if (which_alternative != 0) @@ -10256,7 +10702,7 @@ [(set_attr "type" "branch") (set_attr "length" "*,12,16")]) -(define_insn "" +(define_insn "*ctrsi_internal4" [(set (pc) (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r") (const_int 0)) @@ -10267,7 +10713,7 @@ (const_int -1))) (clobber (match_scratch:CC 3 "=X,&x,&X")) (clobber (match_scratch:SI 4 "=X,X,r"))] - "find_reg_note (insn, REG_NONNEG, 0)" + "! TARGET_POWERPC64 && find_reg_note (insn, REG_NONNEG, 0)" "* { if (which_alternative != 0) @@ -10280,7 +10726,57 @@ [(set_attr "type" "branch") (set_attr "length" "*,12,16")]) -(define_insn "" +(define_insn "*ctrdi_internal3" + [(set (pc) + (if_then_else (ge (match_operand:DI 1 "register_operand" "c,*r,*r") + (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc))) + (set (match_operand:DI 2 "register_operand" "=1,*r,m*q*c*l") + (plus:DI (match_dup 1) + (const_int -1))) + (clobber (match_scratch:CC 3 "=X,&x,&X")) + (clobber (match_scratch:DI 4 "=X,X,r"))] + "TARGET_POWERPC64 && find_reg_note (insn, REG_NONNEG, 0)" + "* +{ + if (which_alternative != 0) + return \"#\"; + else if (get_attr_length (insn) == 8) + return \"{bdn|bdnz} %l0\"; + else + return \"bdz %$+8\;b %l0\"; +}" + [(set_attr "type" "branch") + (set_attr "length" "*,12,16")]) + +(define_insn "*ctrdi_internal4" + [(set (pc) + (if_then_else (ge (match_operand:DI 1 "register_operand" "c,*r,*r") + (const_int 0)) + (pc) + (label_ref (match_operand 0 "" "")))) + (set (match_operand:DI 2 "register_operand" "=1,*r,m*q*c*l") + (plus:DI (match_dup 1) + (const_int -1))) + (clobber (match_scratch:CC 3 "=X,&x,&X")) + (clobber (match_scratch:DI 4 "=X,X,r"))] + "TARGET_POWERPC64 && find_reg_note (insn, REG_NONNEG, 0)" + "* +{ + if (which_alternative != 0) + return \"#\"; + else if (get_attr_length (insn) == 8) + return \"bdz %l0\"; + else + return \"{bdn|bdnz} %$+8\;b %l0\"; +}" + [(set_attr "type" "branch") + (set_attr "length" "*,12,16")]) + +;; Similar but use EQ + +(define_insn "*ctrsi_internal5" [(set (pc) (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r") (const_int 1)) @@ -10291,7 +10787,7 @@ (const_int -1))) (clobber (match_scratch:CC 3 "=X,&x,&x")) (clobber (match_scratch:SI 4 "=X,X,r"))] - "" + "! TARGET_POWERPC64" "* { if (which_alternative != 0) @@ -10304,7 +10800,7 @@ [(set_attr "type" "branch") (set_attr "length" "*,12,16")]) -(define_insn "" +(define_insn "*ctrsi_internal6" [(set (pc) (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r") (const_int 1)) @@ -10315,7 +10811,55 @@ (const_int -1))) (clobber (match_scratch:CC 3 "=X,&x,&x")) (clobber (match_scratch:SI 4 "=X,X,r"))] - "" + "! TARGET_POWERPC64" + "* +{ + if (which_alternative != 0) + return \"#\"; + else if (get_attr_length (insn) == 8) + return \"{bdn|bdnz} %l0\"; + else + return \"bdz %$+8\;b %l0\"; +}" + [(set_attr "type" "branch") + (set_attr "length" "*,12,16")]) + +(define_insn "*ctrdi_internal5" + [(set (pc) + (if_then_else (eq (match_operand:DI 1 "register_operand" "c,*r,*r") + (const_int 1)) + (label_ref (match_operand 0 "" "")) + (pc))) + (set (match_operand:DI 2 "register_operand" "=1,*r,m*q*c*l") + (plus:DI (match_dup 1) + (const_int -1))) + (clobber (match_scratch:CC 3 "=X,&x,&x")) + (clobber (match_scratch:DI 4 "=X,X,r"))] + "TARGET_POWERPC64" + "* +{ + if (which_alternative != 0) + return \"#\"; + else if (get_attr_length (insn) == 8) + return \"bdz %l0\"; + else + return \"{bdn|bdnz} %$+8\;b %l0\"; +}" + [(set_attr "type" "branch") + (set_attr "length" "*,12,16")]) + +(define_insn "*ctrdi_internal6" + [(set (pc) + (if_then_else (eq (match_operand:DI 1 "register_operand" "c,*r,*r") + (const_int 1)) + (pc) + (label_ref (match_operand 0 "" "")))) + (set (match_operand:DI 2 "register_operand" "=1,*r,m*q*c*l") + (plus:DI (match_dup 1) + (const_int -1))) + (clobber (match_scratch:CC 3 "=X,&x,&x")) + (clobber (match_scratch:DI 4 "=X,X,r"))] + "TARGET_POWERPC64" "* { if (which_alternative != 0) @@ -10328,6 +10872,8 @@ [(set_attr "type" "branch") (set_attr "length" "*,12,16")]) +;; Now the splitters if we could not allocate the CTR register + (define_split [(set (pc) (if_then_else (match_operator 2 "comparison_operator" @@ -10340,7 +10886,7 @@ (const_int -1))) (clobber (match_scratch:CC 3 "")) (clobber (match_scratch:SI 4 ""))] - "reload_completed" + "! TARGET_POWERPC64 && reload_completed" [(parallel [(set (match_dup 3) (compare:CC (plus:SI (match_dup 1) (const_int -1)) @@ -10366,7 +10912,8 @@ (plus:SI (match_dup 1) (const_int -1))) (clobber (match_scratch:CC 3 "")) (clobber (match_scratch:SI 4 ""))] - "reload_completed && ! gpc_reg_operand (operands[0], SImode)" + "! TARGET_POWERPC64 && reload_completed + && ! gpc_reg_operand (operands[0], SImode)" [(parallel [(set (match_dup 3) (compare:CC (plus:SI (match_dup 1) (const_int -1)) @@ -10382,6 +10929,61 @@ " { operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3], const0_rtx); }") +(define_split + [(set (pc) + (if_then_else (match_operator 2 "comparison_operator" + [(match_operand:DI 1 "gpc_reg_operand" "") + (const_int 1)]) + (match_operand 5 "" "") + (match_operand 6 "" ""))) + (set (match_operand:DI 0 "gpc_reg_operand" "") + (plus:DI (match_dup 1) + (const_int -1))) + (clobber (match_scratch:CC 3 "")) + (clobber (match_scratch:DI 4 ""))] + "TARGET_POWERPC64 && reload_completed" + [(parallel [(set (match_dup 3) + (compare:CC (plus:DI (match_dup 1) + (const_int -1)) + (const_int 0))) + (set (match_dup 0) + (plus:DI (match_dup 1) + (const_int -1)))]) + (set (pc) (if_then_else (match_dup 7) + (match_dup 5) + (match_dup 6)))] + " +{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3], + const0_rtx); }") + +(define_split + [(set (pc) + (if_then_else (match_operator 2 "comparison_operator" + [(match_operand:DI 1 "gpc_reg_operand" "") + (const_int 1)]) + (match_operand 5 "" "") + (match_operand 6 "" ""))) + (set (match_operand:DI 0 "general_operand" "") + (plus:DI (match_dup 1) (const_int -1))) + (clobber (match_scratch:CC 3 "")) + (clobber (match_scratch:DI 4 ""))] + "TARGET_POWERPC64 && reload_completed + && ! gpc_reg_operand (operands[0], DImode)" + [(parallel [(set (match_dup 3) + (compare:CC (plus:DI (match_dup 1) + (const_int -1)) + (const_int 0))) + (set (match_dup 4) + (plus:DI (match_dup 1) + (const_int -1)))]) + (set (match_dup 0) + (match_dup 4)) + (set (pc) (if_then_else (match_dup 7) + (match_dup 5) + (match_dup 6)))] + " +{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3], + const0_rtx); }") (define_insn "trap" [(trap_if (const_int 1) (const_int 0))] |