diff options
author | Jim Wilson <wilson@redhat.com> | 2001-04-12 20:46:19 +0000 |
---|---|---|
committer | Jim Wilson <wilson@gcc.gnu.org> | 2001-04-12 13:46:19 -0700 |
commit | 640cea5fb46684f1f837f8096724182f0bb113e7 (patch) | |
tree | bd0c776be0e052960864b39d0c9b0d1738de152f | |
parent | 20e50c627742a85f445c2f6ad3534175f67ef046 (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/ia64/ia64.md | 90 |
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") |