diff options
Diffstat (limited to 'gcc/config/rs6000/rs6000.md')
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 204 |
1 files changed, 117 insertions, 87 deletions
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 59c0193a0ea..3b062ce7cde 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -1,6 +1,6 @@ ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler ;; Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, -;; 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. +;; 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ;; This file is part of GCC. @@ -2404,61 +2404,6 @@ }" [(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" "") @@ -5245,16 +5190,18 @@ (define_expand "floatdisf2" [(set (match_operand:SF 0 "gpc_reg_operand" "") (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))] - "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_FPRS" + "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS" " { + rtx val = operands[1]; if (!flag_unsafe_math_optimizations) { rtx label = gen_label_rtx (); - emit_insn (gen_floatdisf2_internal2 (operands[1], label)); + val = gen_reg_rtx (DImode); + emit_insn (gen_floatdisf2_internal2 (val, operands[1], label)); emit_label (label); } - emit_insn (gen_floatdisf2_internal1 (operands[0], operands[1])); + emit_insn (gen_floatdisf2_internal1 (operands[0], val)); DONE; }") @@ -5279,30 +5226,31 @@ ;; 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)) + [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "") + (const_int 53))) + (parallel [(set (match_operand:DI 0 "" "") (and:DI (match_dup 1) + (const_int 2047))) + (clobber (scratch:CC))]) + (set (match_dup 3) (plus:DI (match_dup 3) + (const_int 1))) + (set (match_dup 0) (plus:DI (match_dup 0) + (const_int 2047))) + (set (match_dup 4) (compare:CCUNS (match_dup 3) + (const_int 3))) + (set (match_dup 0) (ior:DI (match_dup 0) + (match_dup 1))) + (parallel [(set (match_dup 0) (and:DI (match_dup 0) + (const_int -2048))) + (clobber (scratch:CC))]) + (set (pc) (if_then_else (geu (match_dup 4) (const_int 0)) + (label_ref (match_operand:DI 2 "" "")) (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_64BIT && TARGET_HARD_FLOAT && TARGET_FPRS" + (set (match_dup 0) (match_dup 1))] + "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); + operands[4] = gen_reg_rtx (CCUNSmode); }") ;; Define the DImode operations that can be done in a small number @@ -8311,14 +8259,36 @@ DONE; }) -(define_insn "trunctfdf2" +(define_expand "trunctfdf2" + [(set (match_operand:DF 0 "gpc_reg_operand" "") + (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))] + "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" + "") + +(define_insn_and_split "trunctfdf2_internal1" + [(set (match_operand:DF 0 "gpc_reg_operand" "=f,?f") + (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "0,f")))] + "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) && !TARGET_XL_COMPAT + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" + "@ + # + fmr %0,%1" + "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])" + [(const_int 0)] +{ + emit_note (NOTE_INSN_DELETED); + DONE; +} + [(set_attr "type" "fp")]) + +(define_insn "trunctfdf2_internal2" [(set (match_operand:DF 0 "gpc_reg_operand" "=f") (float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "f")))] - "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) + "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" "fadd %0,%1,%L1" - [(set_attr "type" "fp") - (set_attr "length" "4")]) + [(set_attr "type" "fp")]) (define_insn_and_split "trunctfsf2" [(set (match_operand:SF 0 "gpc_reg_operand" "=f") @@ -10081,11 +10051,10 @@ (define_insn "load_toc_v4_PIC_1b" [(set (match_operand:SI 0 "register_operand" "=l") - (match_operand:SI 1 "immediate_operand" "s")) - (use (unspec [(match_dup 1) (match_operand 2 "immediate_operand" "s")] + (unspec:SI [(match_operand:SI 1 "immediate_operand" "s")] UNSPEC_TOCPTR))] "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2" - "bcl 20,31,%1+4\\n%1:\\n\\t.long %2-%1" + "bcl 20,31,$+8\\n\\t.long %1-$" [(set_attr "type" "branch") (set_attr "length" "8")]) @@ -11349,11 +11318,72 @@ [(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 || DEFAULT_ABI == ABI_DARWIN) + "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) && !TARGET_XL_COMPAT && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2" [(set_attr "type" "fpcompare") (set_attr "length" "12")]) + +(define_insn_and_split "*cmptf_internal2" + [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") + (compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "f") + (match_operand:TF 2 "gpc_reg_operand" "f"))) + (clobber (match_scratch:DF 3 "=f")) + (clobber (match_scratch:DF 4 "=f")) + (clobber (match_scratch:DF 5 "=f")) + (clobber (match_scratch:DF 6 "=f")) + (clobber (match_scratch:DF 7 "=f")) + (clobber (match_scratch:DF 8 "=f")) + (clobber (match_scratch:DF 9 "=f")) + (clobber (match_scratch:DF 10 "=f"))] + "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) && TARGET_XL_COMPAT + && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" + "#" + "&& reload_completed" + [(set (match_dup 3) (match_dup 13)) + (set (match_dup 4) (match_dup 14)) + (set (match_dup 9) (abs:DF (match_dup 5))) + (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3))) + (set (pc) (if_then_else (ne (match_dup 0) (const_int 0)) + (label_ref (match_dup 11)) + (pc))) + (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7))) + (set (pc) (label_ref (match_dup 12))) + (match_dup 11) + (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7))) + (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8))) + (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9))) + (set (match_dup 0) (compare:CCFP (match_dup 7) (match_dup 4))) + (match_dup 12)] +{ + REAL_VALUE_TYPE rv; + const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0; + const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode); + + operands[5] = simplify_gen_subreg (DFmode, operands[1], TFmode, hi_word); + operands[6] = simplify_gen_subreg (DFmode, operands[1], TFmode, lo_word); + operands[7] = simplify_gen_subreg (DFmode, operands[2], TFmode, hi_word); + operands[8] = simplify_gen_subreg (DFmode, operands[2], TFmode, lo_word); + operands[11] = gen_label_rtx (); + operands[12] = gen_label_rtx (); + real_inf (&rv); + operands[13] = force_const_mem (DFmode, + CONST_DOUBLE_FROM_REAL_VALUE (rv, DFmode)); + operands[14] = force_const_mem (DFmode, + CONST_DOUBLE_FROM_REAL_VALUE (dconst0, + DFmode)); + if (TARGET_TOC) + { + operands[13] = gen_rtx_MEM (DFmode, + create_TOC_reference (XEXP (operands[13], 0))); + operands[14] = gen_rtx_MEM (DFmode, + create_TOC_reference (XEXP (operands[14], 0))); + set_mem_alias_set (operands[13], get_TOC_alias_set ()); + set_mem_alias_set (operands[14], get_TOC_alias_set ()); + RTX_UNCHANGING_P (operands[13]) = 1; + RTX_UNCHANGING_P (operands[14]) = 1; + } +}) ;; Now we have the scc insns. We can do some combinations because of the ;; way the machine works. |