rs6000.md: (floatdisf2): Rename to floatdisf2_internal1.
* config/rs6000/rs6000.md: (floatdisf2): Rename to floatdisf2_internal1. (floatdisf2): New define_expand. (floatdisf2_internal2): Likewise. From-SVN: r57288
This commit is contained in:
parent
c402b6bfbd
commit
678b77333a
@ -1,3 +1,10 @@
|
||||
2002-09-19 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* config/rs6000/rs6000.md: (floatdisf2): Rename to
|
||||
floatdisf2_internal1.
|
||||
(floatdisf2): New define_expand.
|
||||
(floatdisf2_internal2): Likewise.
|
||||
|
||||
2002-09-18 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* real.c (sticky_rshift_significand): Collect sticky as
|
||||
|
@ -5890,13 +5890,30 @@
|
||||
"fctidz %0,%1"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
;; This only is safe if rounding mode set appropriately.
|
||||
(define_insn_and_split "floatdisf2"
|
||||
(define_expand "floatdisf2"
|
||||
[(set (match_operand:SF 0 "gpc_reg_operand" "")
|
||||
(float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
|
||||
"TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
|
||||
"
|
||||
{
|
||||
if (!flag_unsafe_math_optimizations)
|
||||
{
|
||||
rtx label = gen_label_rtx ();
|
||||
emit_insn (gen_floatdisf2_internal2 (operands[1], label));
|
||||
emit_label (label);
|
||||
}
|
||||
emit_insn (gen_floatdisf2_internal1 (operands[0], operands[1]));
|
||||
DONE;
|
||||
}")
|
||||
|
||||
;; This is not IEEE compliant if rounding mode is "round to nearest".
|
||||
;; If the DI->DF conversion is inexact, then it's possible to suffer
|
||||
;; from double rounding.
|
||||
(define_insn_and_split "floatdisf2_internal1"
|
||||
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
|
||||
(float:SF (match_operand:DI 1 "gpc_reg_operand" "*f")))
|
||||
(clobber (match_scratch:DF 2 "=f"))]
|
||||
"TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS
|
||||
&& flag_unsafe_math_optimizations"
|
||||
"TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(set (match_dup 2)
|
||||
@ -5904,6 +5921,33 @@
|
||||
(set (match_dup 0)
|
||||
(float_truncate:SF (match_dup 2)))]
|
||||
"")
|
||||
|
||||
;; Twiddles bits to avoid double rounding.
|
||||
;; Bits that might be trucated when converting to DFmode are replaced
|
||||
;; by a bit that won't be lost at that stage, but is below the SFmode
|
||||
;; rounding position.
|
||||
(define_expand "floatdisf2_internal2"
|
||||
[(set (match_dup 2) (and:DI (match_operand:DI 0 "" "") (const_int 2047)))
|
||||
(set (match_dup 4) (compare:CC (match_dup 2) (const_int 0)))
|
||||
(set (match_dup 3) (ashiftrt:DI (match_dup 0) (const_int 53)))
|
||||
(set (match_dup 3) (plus:DI (match_dup 3) (const_int 1)))
|
||||
(set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
|
||||
(label_ref (match_operand:DI 1 "" ""))
|
||||
(pc)))
|
||||
(set (match_dup 5) (compare:CCUNS (match_dup 3) (const_int 2)))
|
||||
(set (pc) (if_then_else (ltu (match_dup 5) (const_int 0))
|
||||
(label_ref (match_dup 1))
|
||||
(pc)))
|
||||
(set (match_dup 0) (xor:DI (match_dup 0) (match_dup 2)))
|
||||
(set (match_dup 0) (ior:DI (match_dup 0) (const_int 2048)))]
|
||||
"TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
|
||||
"
|
||||
{
|
||||
operands[2] = gen_reg_rtx (DImode);
|
||||
operands[3] = gen_reg_rtx (DImode);
|
||||
operands[4] = gen_reg_rtx (CCmode);
|
||||
operands[5] = gen_reg_rtx (CCUNSmode);
|
||||
}")
|
||||
|
||||
;; Define the DImode operations that can be done in a small number
|
||||
;; of instructions. The & constraints are to prevent the register
|
||||
|
Loading…
Reference in New Issue
Block a user