diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-01-24 20:10:04 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-01-24 20:10:04 +0000 |
commit | a4110d9a66b1bfab2679b8b4774839bcfb1b3cba (patch) | |
tree | a9f7967b844ec94122754eade0945e4f551bf9f1 /gcc/config | |
parent | 8581412d5881e717bf3351f305d6b2e99dd64f96 (diff) | |
download | gcc-a4110d9a66b1bfab2679b8b4774839bcfb1b3cba.tar.gz |
* rtl.def: Add unordered fp comparisions.
* tree.def: Likewise.
* tree.h: Add ISO C 9x unordered fp comparision builtins.
* builtins.c (expand_tree_builtin): New function.
* c-typeck.c (build_function_call): Use it.
(build_binary_op): Support unordered compares.
* c-common.c (c_common_nodes_and_builtins): Add unordered compares.
* combine.c (known_cond): Handle reverse_condition returning UNKNOWN.
(reversible_comparison_p): Allow UNORDERED/ORDERED to be reversed.
* cse.c (fold_rtx): Check FLOAT_MODE_P before reversing.
(record_jump_equiv): Handle reverse_condition returning UNKNOWN.
* jump.c (reverse_condition): Don't abort for UNLE etc, but
return UNKNOWN.
(swap_condition): Handle unordered compares.
(thread_jumps): Check can_reverse before reversing.
* loop.c (get_condition): Likewise. Allow UNORERED/ORDERED to be
reversed for FP.
* optabs.c (can_compare_p): New argument CODE. Verify branch or
setcc is present before acking for cmp_optab. Update all callers.
(prepare_float_lib_cmp, init_optabs): Handle UNORDERED.
* expmed.c (do_cmp_and_jump): Update for can_compare_p.
* expr.c (expand_expr): Likewise. Support unordered compares.
(do_jump, do_store_flag): Likewise.
* expr.h (enum libfunc_index): Add unordered compares.
* Makefile.in (FPBIT_FUNCS): Add _unord_sf.
(DPBIT_FUNCS): Add _unord_df.
* config/fp-bit.c (_unord_f2): New.
* fp-test.c (main): Try unordered compare builtins.
* alpha-protos.h (alpha_fp_comparison_operator): Declare.
* alpha.c (alpha_comparison_operator): Check mode properly.
(alpha_swapped_comparison_operator): Likewise.
(signed_comparison_operator): Likewise.
(alpha_fp_comparison_operator): New.
(alpha_emit_conditional_branch): Handle unordered compares.
* alpha.h (PREDICATE_CODES): Update.
* alpha.md (fp compares): Use alpha_fp_comparison_operator.
(bunordered, bordered): New.
* cp/call.c (build_over_call): Use expand_tree_builtin.
* cp/typeck.c (build_function_call_real): Likewise.
(build_binary_op_nodefault): Handle unordered compares.
* gcc.c-torture/execute/ieee/fp-cmp-4.c: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@31591 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/alpha/alpha-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/alpha/alpha.c | 43 | ||||
-rw-r--r-- | gcc/config/alpha/alpha.h | 1 | ||||
-rw-r--r-- | gcc/config/alpha/alpha.md | 38 | ||||
-rw-r--r-- | gcc/config/fp-bit.c | 24 |
5 files changed, 83 insertions, 24 deletions
diff --git a/gcc/config/alpha/alpha-protos.h b/gcc/config/alpha/alpha-protos.h index c29063e9fd2..693fa245bcc 100644 --- a/gcc/config/alpha/alpha-protos.h +++ b/gcc/config/alpha/alpha-protos.h @@ -58,6 +58,7 @@ extern int call_operand PARAMS ((rtx, enum machine_mode)); extern int alpha_comparison_operator PARAMS ((rtx, enum machine_mode)); extern int alpha_swapped_comparison_operator PARAMS ((rtx, enum machine_mode)); extern int signed_comparison_operator PARAMS ((rtx, enum machine_mode)); +extern int alpha_fp_comparison_operator PARAMS ((rtx, enum machine_mode)); extern int divmod_operator PARAMS ((rtx, enum machine_mode)); extern int aligned_memory_operand PARAMS ((rtx, enum machine_mode)); extern int unaligned_memory_operand PARAMS ((rtx, enum machine_mode)); diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index ca9e0ecaf35..cbc16883d6f 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -706,7 +706,7 @@ alpha_comparison_operator (op, mode) { enum rtx_code code = GET_CODE (op); - if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<') + if (mode != GET_MODE (op) && mode != VOIDmode) return 0; return (code == EQ || code == LE || code == LT @@ -722,7 +722,8 @@ alpha_swapped_comparison_operator (op, mode) { enum rtx_code code = GET_CODE (op); - if (mode != GET_MODE (op) || GET_RTX_CLASS (code) != '<') + if ((mode != GET_MODE (op) && mode != VOIDmode) + || GET_RTX_CLASS (code) != '<') return 0; code = swap_condition (code); @@ -737,16 +738,30 @@ signed_comparison_operator (op, mode) register rtx op; enum machine_mode mode ATTRIBUTE_UNUSED; { - switch (GET_CODE (op)) - { - case EQ: case NE: case LE: case LT: case GE: case GT: - return 1; + enum rtx_code code = GET_CODE (op); - default: - break; - } + if (mode != GET_MODE (op) && mode != VOIDmode) + return 0; - return 0; + return (code == EQ || code == NE + || code == LE || code == LT + || code == GE || code == GT); +} + +/* Return 1 if OP is a valid Alpha floating point comparison operator. + Here we know which comparisons are valid in which insn. */ + +int +alpha_fp_comparison_operator (op, mode) + register rtx op; + enum machine_mode mode; +{ + enum rtx_code code = GET_CODE (op); + + if (mode != GET_MODE (op) && mode != VOIDmode) + return 0; + + return (code == EQ || code == LE || code == LT || code == UNORDERED); } /* Return 1 if this is a divide or modulus operator. */ @@ -1484,13 +1499,15 @@ alpha_emit_conditional_branch (code) switch (code) { case EQ: case LE: case LT: case LEU: case LTU: + case UNORDERED: /* We have these compares: */ cmp_code = code, branch_code = NE; break; case NE: - /* This must be reversed. */ - cmp_code = EQ, branch_code = EQ; + case ORDERED: + /* These must be reversed. */ + cmp_code = reverse_condition (code), branch_code = EQ; break; case GE: case GT: case GEU: case GTU: @@ -3383,6 +3400,8 @@ print_operand (file, x, code) fprintf (file, "ule"); else if (c == LTU) fprintf (file, "ult"); + else if (c == UNORDERED) + fprintf (file, "un"); else fprintf (file, "%s", GET_RTX_NAME (c)); } diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h index b146a5a4c24..ad45596f0bb 100644 --- a/gcc/config/alpha/alpha.h +++ b/gcc/config/alpha/alpha.h @@ -2311,6 +2311,7 @@ do { \ {"alpha_comparison_operator", {EQ, LE, LT, LEU, LTU}}, \ {"alpha_swapped_comparison_operator", {EQ, GE, GT, GEU, GTU}}, \ {"signed_comparison_operator", {EQ, NE, LE, LT, GE, GT}}, \ + {"alpha_fp_comparison_operator", {EQ, LE, LT, UNORDERED}}, \ {"divmod_operator", {DIV, MOD, UDIV, UMOD}}, \ {"fp0_operand", {CONST_DOUBLE}}, \ {"current_file_function_operand", {SYMBOL_REF}}, \ diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md index 5f0e2219bbd..2325483d02d 100644 --- a/gcc/config/alpha/alpha.md +++ b/gcc/config/alpha/alpha.md @@ -2752,12 +2752,12 @@ "") ;; The following are the corresponding floating-point insns. Recall -;; we need to have variants that expand the arguments from SF mode +;; we need to have variants that expand the arguments from SFmode ;; to DFmode. -(define_insn "" +(define_insn "*cmpdf_tp" [(set (match_operand:DF 0 "register_operand" "=&f") - (match_operator:DF 1 "alpha_comparison_operator" + (match_operator:DF 1 "alpha_fp_comparison_operator" [(match_operand:DF 2 "reg_or_fp0_operand" "fG") (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))] "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU" @@ -2765,9 +2765,9 @@ [(set_attr "type" "fadd") (set_attr "trap" "yes")]) -(define_insn "" +(define_insn "*cmpdf_no_tp" [(set (match_operand:DF 0 "register_operand" "=f") - (match_operator:DF 1 "alpha_comparison_operator" + (match_operator:DF 1 "alpha_fp_comparison_operator" [(match_operand:DF 2 "reg_or_fp0_operand" "fG") (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))] "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU" @@ -2777,7 +2777,7 @@ (define_insn "" [(set (match_operand:DF 0 "register_operand" "=&f") - (match_operator:DF 1 "alpha_comparison_operator" + (match_operator:DF 1 "alpha_fp_comparison_operator" [(float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG")) (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))] @@ -2788,7 +2788,7 @@ (define_insn "" [(set (match_operand:DF 0 "register_operand" "=f") - (match_operator:DF 1 "alpha_comparison_operator" + (match_operator:DF 1 "alpha_fp_comparison_operator" [(float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG")) (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))] @@ -2799,7 +2799,7 @@ (define_insn "" [(set (match_operand:DF 0 "register_operand" "=&f") - (match_operator:DF 1 "alpha_comparison_operator" + (match_operator:DF 1 "alpha_fp_comparison_operator" [(match_operand:DF 2 "reg_or_fp0_operand" "fG") (float_extend:DF (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))] @@ -2810,7 +2810,7 @@ (define_insn "" [(set (match_operand:DF 0 "register_operand" "=f") - (match_operator:DF 1 "alpha_comparison_operator" + (match_operator:DF 1 "alpha_fp_comparison_operator" [(match_operand:DF 2 "reg_or_fp0_operand" "fG") (float_extend:DF (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))] @@ -2821,7 +2821,7 @@ (define_insn "" [(set (match_operand:DF 0 "register_operand" "=&f") - (match_operator:DF 1 "alpha_comparison_operator" + (match_operator:DF 1 "alpha_fp_comparison_operator" [(float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG")) (float_extend:DF @@ -2833,7 +2833,7 @@ (define_insn "" [(set (match_operand:DF 0 "register_operand" "=f") - (match_operator:DF 1 "alpha_comparison_operator" + (match_operator:DF 1 "alpha_fp_comparison_operator" [(float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG")) (float_extend:DF @@ -3126,6 +3126,22 @@ "" "{ operands[1] = alpha_emit_conditional_branch (GEU); }") +(define_expand "bunordered" + [(set (pc) + (if_then_else (match_dup 1) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "{ operands[1] = alpha_emit_conditional_branch (UNORDERED); }") + +(define_expand "bordered" + [(set (pc) + (if_then_else (match_dup 1) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "{ operands[1] = alpha_emit_conditional_branch (ORDERED); }") + (define_expand "seq" [(set (match_operand:DI 0 "register_operand" "") (match_dup 1))] diff --git a/gcc/config/fp-bit.c b/gcc/config/fp-bit.c index d7bc3de38f4..fc496c0f059 100644 --- a/gcc/config/fp-bit.c +++ b/gcc/config/fp-bit.c @@ -1,7 +1,7 @@ /* This is a software floating point library which can be used instead of the floating point routines in libgcc1.c for targets without hardware floating point. - Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1994-1998, 2000 Free Software Foundation, Inc. This file is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -78,6 +78,8 @@ Boston, MA 02111-1307, USA. */ #define L_lt_df #define L_le_sf #define L_le_df +#define L_unord_sf +#define L_unord_df #define L_si_to_sf #define L_si_to_df #define L_sf_to_si @@ -268,6 +270,7 @@ typedef unsigned int UDItype __attribute__ ((mode (DI))); # define _ge_f2 __gesf2 # define _lt_f2 __ltsf2 # define _le_f2 __lesf2 +# define _unord_f2 __unordsf2 # define si_to_float __floatsisf # define float_to_si __fixsfsi # define float_to_usi __fixunssfsi @@ -285,6 +288,7 @@ typedef unsigned int UDItype __attribute__ ((mode (DI))); # define _ge_f2 __gedf2 # define _lt_f2 __ltdf2 # define _le_f2 __ledf2 +# define _unord_f2 __unorddf2 # define si_to_float __floatsidf # define float_to_si __fixdfsi # define float_to_usi __fixunsdfsi @@ -1370,6 +1374,24 @@ _le_f2 (FLO_type arg_a, FLO_type arg_b) } #endif +#if defined(L_unord_sf) || defined(L_unord_df) +CMPtype +_unord_f2 (FLO_type arg_a, FLO_type arg_b) +{ + fp_number_type a; + fp_number_type b; + FLO_union_type au, bu; + + au.value = arg_a; + bu.value = arg_b; + + unpack_d (&au, &a); + unpack_d (&bu, &b); + + return (isnan (&a) || isnan (&b); +} +#endif + #endif /* ! US_SOFTWARE_GOFAST */ #if defined(L_si_to_sf) || defined(L_si_to_df) |