X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fconfig%2Frs6000%2Frs6000.md;h=b9fa39c386df77750ab9bb0c654a0d85569ee2d4;hb=965e7256d9c6beb266cd5ca44e3eecaa8a297f0a;hp=edbccc64613aa69bbd9fcc49de8be318d386db5f;hpb=d6c7292e957cd78a1d5c5c952474ed1c56a5f2da;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index edbccc64613..b9fa39c386d 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. @@ -50,7 +50,8 @@ (UNSPEC_TLSGOTTPREL 28) (UNSPEC_TLSTLS 29) (UNSPEC_FIX_TRUNC_TF 30) ; fadd, rounding towards zero - (UNSPEC_MV_CR_EQ 31) ; move_from_CR_eq_bit + (UNSPEC_MV_CR_GT 31) ; move_from_CR_eq_bit + (UNSPEC_STFIWX 32) ]) ;; @@ -101,6 +102,9 @@ (include "8540.md") (include "power4.md") (include "power5.md") + +(include "predicates.md") + (include "darwin.md") @@ -2411,60 +2415,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" - [(set (match_dup 0) - (and:SI (rotate:SI (match_dup 1) (match_dup 4)) - (match_dup 5))) - (parallel [(set (match_dup 3) - (compare:CC (rotate:SI (match_dup 0) (match_dup 6)) - (const_int 0))) - (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" "") @@ -4461,24 +4411,25 @@ (define_expand "extendsfdf2" [(set (match_operand:DF 0 "gpc_reg_operand" "") - (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "")))] + (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))] "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)" "") (define_insn_and_split "*extendsfdf2_fpr" - [(set (match_operand:DF 0 "gpc_reg_operand" "=f,?f") - (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "0,f")))] + [(set (match_operand:DF 0 "gpc_reg_operand" "=f,?f,f") + (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m")))] "TARGET_HARD_FLOAT && TARGET_FPRS" "@ # - fmr %0,%1" + fmr %0,%1 + lfs%U1%X1 %0,%1" "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])" [(const_int 0)] { emit_note (NOTE_INSN_DELETED); DONE; } - [(set_attr "type" "fp")]) + [(set_attr "type" "fp,fp,fpload")]) (define_expand "truncdfsf2" [(set (match_operand:SF 0 "gpc_reg_operand" "") @@ -4759,11 +4710,47 @@ "fsqrt %0,%1" [(set_attr "type" "dsqrt")]) +(define_expand "copysignsf3" + [(set (match_dup 3) + (abs:SF (match_operand:SF 1 "gpc_reg_operand" ""))) + (set (match_dup 4) + (neg:SF (abs:SF (match_dup 1)))) + (set (match_operand:SF 0 "gpc_reg_operand" "") + (if_then_else:SF (ge (match_operand:SF 2 "gpc_reg_operand" "") + (match_dup 5)) + (match_dup 3) + (match_dup 4)))] + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS + && !HONOR_NANS (SFmode) && !HONOR_SIGNED_ZEROS (SFmode)" + { + operands[3] = gen_reg_rtx (SFmode); + operands[4] = gen_reg_rtx (SFmode); + operands[5] = CONST0_RTX (SFmode); + }) + +(define_expand "copysigndf3" + [(set (match_dup 3) + (abs:DF (match_operand:DF 1 "gpc_reg_operand" ""))) + (set (match_dup 4) + (neg:DF (abs:DF (match_dup 1)))) + (set (match_operand:DF 0 "gpc_reg_operand" "") + (if_then_else:DF (ge (match_operand:DF 2 "gpc_reg_operand" "") + (match_dup 5)) + (match_dup 3) + (match_dup 4)))] + "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS + && !HONOR_NANS (DFmode) && !HONOR_SIGNED_ZEROS (DFmode)" + { + operands[3] = gen_reg_rtx (DFmode); + operands[4] = gen_reg_rtx (DFmode); + operands[5] = CONST0_RTX (DFmode); + }) + ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a ;; fsel instruction and some auxiliary computations. Then we just have a ;; single DEFINE_INSN for fsel and the define_splits to make them if made by ;; combine. -(define_expand "maxsf3" +(define_expand "smaxsf3" [(set (match_operand:SF 0 "gpc_reg_operand" "") (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "") (match_operand:SF 2 "gpc_reg_operand" "")) @@ -4772,7 +4759,7 @@ "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math" "{ rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); DONE;}") -(define_expand "minsf3" +(define_expand "sminsf3" [(set (match_operand:SF 0 "gpc_reg_operand" "") (if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "") (match_operand:SF 2 "gpc_reg_operand" "")) @@ -5037,7 +5024,7 @@ ;; The conditional move instructions allow us to perform max and min ;; operations even when -(define_expand "maxdf3" +(define_expand "smaxdf3" [(set (match_operand:DF 0 "gpc_reg_operand" "") (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "") (match_operand:DF 2 "gpc_reg_operand" "")) @@ -5046,7 +5033,7 @@ "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math" "{ rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); DONE;}") -(define_expand "mindf3" +(define_expand "smindf3" [(set (match_operand:DF 0 "gpc_reg_operand" "") (if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "") (match_operand:DF 2 "gpc_reg_operand" "")) @@ -5286,7 +5273,7 @@ }") (define_expand "fix_truncdfsi2" - [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "") + [(parallel [(set (match_operand:SI 0 "reg_or_mem_operand" "") (fix:SI (match_operand:DF 1 "gpc_reg_operand" ""))) (clobber (match_dup 2)) (clobber (match_dup 3))])] @@ -5300,28 +5287,29 @@ DONE; } operands[2] = gen_reg_rtx (DImode); + if (TARGET_PPC_GFXOPT) + { + rtx orig_dest = operands[0]; + if (GET_CODE (orig_dest) != MEM) + operands[0] = assign_stack_temp (SImode, GET_MODE_SIZE (SImode), 0); + emit_insn (gen_fix_truncdfsi2_internal_gfxopt (operands[0], operands[1], + operands[2])); + if (operands[0] != orig_dest) + emit_move_insn (orig_dest, operands[0]); + DONE; + } operands[3] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0); }") -(define_insn "*fix_truncdfsi2_internal" +(define_insn_and_split "*fix_truncdfsi2_internal" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))) (clobber (match_operand:DI 2 "gpc_reg_operand" "=f")) (clobber (match_operand:DI 3 "memory_operand" "=o"))] "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS" "#" - [(set_attr "length" "16")]) - -(define_split - [(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" "")) - (clobber (match_operand:DI 3 "offsettable_mem_operand" ""))] - "(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" "")) - (clobber (match_operand:DI 3 "offsettable_mem_operand" ""))] + "&& 1" + [(pc)] " { rtx lowword; @@ -5335,20 +5323,47 @@ emit_move_insn (operands[3], operands[2]); emit_move_insn (operands[0], gen_rtx_MEM (SImode, lowword)); DONE; -}") +}" + [(set_attr "length" "16")]) + +(define_insn_and_split "fix_truncdfsi2_internal_gfxopt" + [(set (match_operand:SI 0 "memory_operand" "=Z") + (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))) + (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))] + "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS + && TARGET_PPC_GFXOPT" + "#" + "&& 1" + [(pc)] + " +{ + emit_insn (gen_fctiwz (operands[2], operands[1])); + emit_insn (gen_stfiwx (operands[0], operands[2])); + DONE; +}" + [(set_attr "length" "16")]) ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ)) ; rather than (set (subreg:SI (reg)) (fix:SI ...)) ; because the first makes it clear that operand 0 is not live ; before the instruction. (define_insn "fctiwz" - [(set (match_operand:DI 0 "gpc_reg_operand" "=*f") + [(set (match_operand:DI 0 "gpc_reg_operand" "=f") (unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))] UNSPEC_FCTIWZ))] "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS" "{fcirz|fctiwz} %0,%1" [(set_attr "type" "fp")]) +; An UNSPEC is used so we don't have to support SImode in FP registers. +(define_insn "stfiwx" + [(set (match_operand:SI 0 "memory_operand" "=Z") + (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "f")] + UNSPEC_STFIWX))] + "TARGET_PPC_GFXOPT" + "stfiwx %1,%y0" + [(set_attr "type" "fpstore")]) + (define_expand "floatsisf2" [(set (match_operand:SF 0 "gpc_reg_operand" "") (float:SF (match_operand:SI 1 "gpc_reg_operand" "")))] @@ -7763,7 +7778,7 @@ (set_attr "length" "4")]) (define_insn "*movsi_internal1" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,r,r,r,r,r,*q,*c*l,*h,*h") + [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,r,*q,*c*l,*h,*h") (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,R,*h,r,r,r,0"))] "gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode)" @@ -8288,10 +8303,10 @@ ; It's important to list the o->f and f->o moves before f->f because ; otherwise reload, given m->f, will try to pick f->f and reload it, -; which doesn't make progress. Likewise r->o<> must be before r->r. +; which doesn't make progress. Likewise r->Y must be before r->r. (define_insn_and_split "*movtf_internal" - [(set (match_operand:TF 0 "nonimmediate_operand" "=o,f,f,r,o<>,r") - (match_operand:TF 1 "input_operand" "f,o,f,mGHF,r,r"))] + [(set (match_operand:TF 0 "nonimmediate_operand" "=o,f,f,r,Y,r") + (match_operand:TF 1 "input_operand" "f,o,f,YGHF,r,r"))] "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128 && (gpc_reg_operand (operands[0], TFmode) @@ -8315,7 +8330,7 @@ (define_insn_and_split "*extenddftf2_internal" [(set (match_operand:TF 0 "nonimmediate_operand" "=o,f,&f,r") (float_extend:TF (match_operand:DF 1 "input_operand" "fr,mf,mf,rmGHF"))) - (use (match_operand:DF 2 "input_operand" "rf,m,f,n"))] + (use (match_operand:DF 2 "zero_reg_mem_operand" "rf,m,f,n"))] "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" "#" @@ -8343,14 +8358,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") @@ -8496,7 +8533,7 @@ ; List r->r after r->"o<>", otherwise reload will try to reload a ; non-offsettable address by using r->r which won't make progress. (define_insn "*movdi_internal32" - [(set (match_operand:DI 0 "nonimmediate_operand" "=o<>,r,r,f,f,m,r") + [(set (match_operand:DI 0 "nonimmediate_operand" "=o<>,r,r,*f,*f,m,r") (match_operand:DI 1 "input_operand" "r,r,m,f,m,f,IJKnGHF"))] "! TARGET_POWERPC64 && (gpc_reg_operand (operands[0], DImode) @@ -8540,34 +8577,8 @@ [(pc)] { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) -(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) @@ -8692,9 +8703,9 @@ ;; giving the SCRATCH mq. (define_insn "*movti_power" - [(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")) - (clobber (match_scratch:SI 2 "=q,q#X,X,X,X"))] + [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r,r") + (match_operand:TI 1 "input_operand" "r,r,r,Q,m,n")) + (clobber (match_scratch:SI 2 "=q,q#X,X,X,X,X"))] "TARGET_POWER && ! TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))" "* @@ -8718,14 +8729,15 @@ return \"{lsi|lswi} %0,%P1,16\"; /* ... fall through ... */ case 4: + case 5: return \"#\"; } }" - [(set_attr "type" "store,store,*,load,load")]) + [(set_attr "type" "store,store,*,load,load,*")]) (define_insn "*movti_string" - [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,o<>,????r,????r,????r") - (match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))] + [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,o<>,????r,????r,????r,r") + (match_operand:TI 1 "input_operand" "r,r,r,Q,m,n"))] "! TARGET_POWER && ! TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))" "* @@ -8748,10 +8760,11 @@ return \"{lsi|lswi} %0,%P1,16\"; /* ... fall through ... */ case 4: + case 5: return \"#\"; } }" - [(set_attr "type" "store,store,*,load,load")]) + [(set_attr "type" "store,store,*,load,load,*")]) (define_insn "*movti_ppc64" [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o<>,r") @@ -8762,6 +8775,32 @@ [(set_attr "type" "*,load,store")]) (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_split [(set (match_operand:TI 0 "nonimmediate_operand" "") (match_operand:TI 1 "input_operand" ""))] "reload_completed @@ -11119,8 +11158,7 @@ "" " { - if (! rs6000_compare_fp_p - && (! TARGET_POWER || rs6000_compare_op1 == const0_rtx)) + if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx) FAIL; rs6000_emit_sCOND (GE, operands[0]); @@ -11133,8 +11171,7 @@ "" " { - if (! rs6000_compare_fp_p - && (! TARGET_POWER || rs6000_compare_op1 == const0_rtx)) + if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx) FAIL; rs6000_emit_sCOND (GT, operands[0]); @@ -11147,8 +11184,7 @@ "" " { - if (! rs6000_compare_fp_p - && (! TARGET_POWER || rs6000_compare_op1 == const0_rtx)) + if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx) FAIL; rs6000_emit_sCOND (LE, operands[0]); @@ -11161,8 +11197,7 @@ "" " { - if (! rs6000_compare_fp_p - && (! TARGET_POWER || rs6000_compare_op1 == const0_rtx)) + if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx) FAIL; rs6000_emit_sCOND (LT, operands[0]); @@ -11191,12 +11226,12 @@ (define_expand "sunordered" [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] - "" + "! (TARGET_HARD_FLOAT && TARGET_E500 && !TARGET_FPRS)" "{ rs6000_emit_sCOND (UNORDERED, operands[0]); DONE; }") (define_expand "sordered" [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] - "" + "! (TARGET_HARD_FLOAT && TARGET_E500 && !TARGET_FPRS)" "{ rs6000_emit_sCOND (ORDERED, operands[0]); DONE; }") (define_expand "suneq" @@ -11357,11 +11392,70 @@ [(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_const_mem (DFmode, + create_TOC_reference (XEXP (operands[13], 0))); + operands[14] = gen_const_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 ()); + } +}) ;; Now we have the scc insns. We can do some combinations because of the ;; way the machine works. @@ -11385,11 +11479,11 @@ (set_attr "length" "8")]) ;; Same as above, but get the GT bit. -(define_insn "move_from_CR_eq_bit" +(define_insn "move_from_CR_gt_bit" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_EQ))] + (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))] "TARGET_E500" - "mfcr %0\;{rlinm|rlwinm} %0,%0,%D1,1" + "mfcr %0\;{rlinm|rlwinm} %0,%0,%D1,31,31" [(set_attr "type" "mfcr") (set_attr "length" "8")]) @@ -12582,25 +12676,25 @@ "") (define_insn_and_split "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") + [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r") (plus:SI (ltu: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 "reg_or_short_operand" "rI,rI")))] "TARGET_32BIT" "#" - "TARGET_32BIT" + "&& !reg_overlap_mentioned_p (operands[0], operands[3])" [(set (match_dup 0) (neg:SI (ltu:SI (match_dup 1) (match_dup 2)))) (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 0)))] "") (define_insn_and_split "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") + [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r") (plus:DI (ltu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r") (match_operand:DI 2 "reg_or_neg_short_operand" "r,P")) (match_operand:DI 3 "reg_or_short_operand" "rI,rI")))] "TARGET_64BIT" "#" - "TARGET_64BIT" + "&& !reg_overlap_mentioned_p (operands[0], operands[3])" [(set (match_dup 0) (neg:DI (ltu:DI (match_dup 1) (match_dup 2)))) (set (match_dup 0) (minus:DI (match_dup 3) (match_dup 0)))] "") @@ -13540,25 +13634,25 @@ "") (define_insn_and_split "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + [(set (match_operand:SI 0 "gpc_reg_operand" "=&r") (plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r") (match_operand:SI 2 "reg_or_short_operand" "rI")) (match_operand:SI 3 "reg_or_short_operand" "rI")))] "TARGET_32BIT" "#" - "TARGET_32BIT" + "&& !reg_overlap_mentioned_p (operands[0], operands[3])" [(set (match_dup 0) (neg:SI (gtu:SI (match_dup 1) (match_dup 2)))) (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 0)))] "") (define_insn_and_split "" - [(set (match_operand:DI 0 "gpc_reg_operand" "=r") + [(set (match_operand:DI 0 "gpc_reg_operand" "=&r") (plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r") (match_operand:DI 2 "reg_or_short_operand" "rI")) (match_operand:DI 3 "reg_or_short_operand" "rI")))] "TARGET_64BIT" "#" - "TARGET_64BIT" + "&& !reg_overlap_mentioned_p (operands[0], operands[3])" [(set (match_dup 0) (neg:DI (gtu:DI (match_dup 1) (match_dup 2)))) (set (match_dup 0) (minus:DI (match_dup 3) (match_dup 0)))] "") @@ -13864,8 +13958,10 @@ { int positive_1, positive_2; - positive_1 = branch_positive_comparison_operator (operands[1], CCEQmode); - positive_2 = branch_positive_comparison_operator (operands[3], CCEQmode); + positive_1 = branch_positive_comparison_operator (operands[1], + GET_MODE (operands[1])); + positive_2 = branch_positive_comparison_operator (operands[3], + GET_MODE (operands[3])); if (! positive_1) operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),