From 640cea5fb46684f1f837f8096724182f0bb113e7 Mon Sep 17 00:00:00 2001 From: Jim Wilson Date: Thu, 12 Apr 2001 20:46:19 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 5 +++ gcc/config/ia64/ia64.md | 90 ++++++++++++----------------------------- 2 files changed, 30 insertions(+), 65 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3873a00ebe4..30c42db8e1a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2001-04-12 Jim Wilson + + * config/ia64/ia64.md (extendsfdf2, extendsftf2, extenddftf2): Simplify + to just emit an fnorm. + 2001-04-12 Kaveh R. Ghazi * c-common.h (truthvalue_conversion, type_for_mode, diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md index 1f99ab6d908..6a6f91f2969 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") -- 2.30.2