aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Wilson <wilson@redhat.com>2001-04-12 20:46:19 +0000
committerJim Wilson <wilson@gcc.gnu.org>2001-04-12 13:46:19 -0700
commit640cea5fb46684f1f837f8096724182f0bb113e7 (patch)
treebd0c776be0e052960864b39d0c9b0d1738de152f
parent20e50c627742a85f445c2f6ad3534175f67ef046 (diff)
downloadgcc-640cea5fb46684f1f837f8096724182f0bb113e7.zip
gcc-640cea5fb46684f1f837f8096724182f0bb113e7.tar.gz
gcc-640cea5fb46684f1f837f8096724182f0bb113e7.tar.bz2
Fix for PR 2498, getf/stf require normalization after a cast.
* config/ia64/ia64.md (extendsfdf2, extendsftf2, extenddftf2): Simplify to just emit an fnorm. From-SVN: r41311
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/ia64/ia64.md90
2 files changed, 30 insertions, 65 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3873a00..30c42db 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2001-04-12 Jim Wilson <wilson@redhat.com>
+
+ * config/ia64/ia64.md (extendsfdf2, extendsftf2, extenddftf2): Simplify
+ to just emit an fnorm.
+
2001-04-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* c-common.h (truthvalue_conversion, type_for_mode,
diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md
index 1f99ab6..6a6f91f 100644
--- a/gcc/config/ia64/ia64.md
+++ b/gcc/config/ia64/ia64.md
@@ -821,80 +821,40 @@
;; Convert between floating point types of different sizes.
+;; At first glance, it would appear that emitting fnorm for an extending
+;; conversion is unnecessary. However, the stf and getf instructions work
+;; correctly only if the input is properly rounded for its type. In
+;; particular, we get the wrong result for getf.d/stfd if the input is a
+;; denorm single. Since we don't know what the next instruction will be, we
+;; have to emit an fnorm.
+
;; ??? Optimization opportunity here. Get rid of the insn altogether
;; when we can. Should probably use a scheme like has been proposed
;; for ia32 in dealing with operands that match unary operators. This
-;; would let combine merge the thing into adjacent insns.
+;; would let combine merge the thing into adjacent insns. See also how the
+;; mips port handles SIGN_EXTEND as operands to integer arithmetic insns via
+;; se_register_operand.
-(define_insn_and_split "extendsfdf2"
- [(set (match_operand:DF 0 "grfr_nonimmediate_operand" "=f,f,f,f,m,*r")
- (float_extend:DF
- (match_operand:SF 1 "grfr_nonimmediate_operand" "0,f,m,*r,f,f")))]
+(define_insn "extendsfdf2"
+ [(set (match_operand:DF 0 "fr_register_operand" "=f")
+ (float_extend:DF (match_operand:SF 1 "fr_register_operand" "f")))]
""
- "@
- mov %0 = %1
- mov %0 = %1
- ldfs %0 = %1%P1
- setf.s %0 = %1
- stfd %0 = %1%P0
- getf.d %0 = %1"
- "reload_completed"
- [(set (match_dup 0) (float_extend:DF (match_dup 1)))]
- "
-{
- if (true_regnum (operands[0]) == true_regnum (operands[1]))
- {
- emit_insn (gen_movdi (pic_offset_table_rtx, pic_offset_table_rtx));
- DONE;
- }
-}"
- [(set_attr "itanium_class" "unknown,fmisc,fld,tofr,stf,frfr")])
+ "fnorm.d %0 = %1"
+ [(set_attr "itanium_class" "fmac")])
-(define_insn_and_split "extendsftf2"
- [(set (match_operand:TF 0 "fr_nonimmediate_operand" "=f,f,f,f,Q")
- (float_extend:TF
- (match_operand:SF 1 "grfr_nonimmediate_operand" "0,f,Q,*r,f")))]
+(define_insn "extendsftf2"
+ [(set (match_operand:TF 0 "fr_register_operand" "=f")
+ (float_extend:TF (match_operand:SF 1 "fr_register_operand" "f")))]
""
- "@
- mov %0 = %1
- mov %0 = %1
- ldfs %0 = %1%P1
- setf.s %0 = %1
- stfe %0 = %1%P0"
- "reload_completed"
- [(set (match_dup 0) (float_extend:TF (match_dup 1)))]
- "
-{
- if (true_regnum (operands[0]) == true_regnum (operands[1]))
- {
- emit_insn (gen_movdi (pic_offset_table_rtx, pic_offset_table_rtx));
- DONE;
- }
-}"
- [(set_attr "itanium_class" "unknown,fmisc,fld,frfr,stf")])
+ "fnorm %0 = %1"
+ [(set_attr "itanium_class" "fmac")])
-(define_insn_and_split "extenddftf2"
- [(set (match_operand:TF 0 "fr_nonimmediate_operand" "=f,f,f,f,Q")
- (float_extend:TF
- (match_operand:DF 1 "grfr_nonimmediate_operand" "0,f,Q,*r,f")))]
+(define_insn "extenddftf2"
+ [(set (match_operand:TF 0 "fr_register_operand" "=f")
+ (float_extend:TF (match_operand:DF 1 "fr_register_operand" "f")))]
""
- "@
- mov %0 = %1
- mov %0 = %1
- ldfd %0 = %1%P1
- setf.d %0 = %1
- stfe %0 = %1%P0"
- "reload_completed"
- [(set (match_dup 0) (float_extend:TF (match_dup 1)))]
- "
-{
- if (true_regnum (operands[0]) == true_regnum (operands[1]))
- {
- emit_insn (gen_movdi (pic_offset_table_rtx, pic_offset_table_rtx));
- DONE;
- }
-}"
- [(set_attr "itanium_class" "unknown,fmisc,fld,frfr,stf")])
+ "fnorm %0 = %1"
+ [(set_attr "itanium_class" "fmac")])
(define_insn "truncdfsf2"
[(set (match_operand:SF 0 "fr_register_operand" "=f")