]> gcc.gnu.org Git - gcc.git/commitdiff
Fix for PR 2498, getf/stf require normalization after a cast.
authorJim Wilson <wilson@redhat.com>
Thu, 12 Apr 2001 20:46:19 +0000 (20:46 +0000)
committerJim Wilson <wilson@gcc.gnu.org>
Thu, 12 Apr 2001 20:46:19 +0000 (13:46 -0700)
* config/ia64/ia64.md (extendsfdf2, extendsftf2, extenddftf2): Simplify
to just emit an fnorm.

From-SVN: r41311

gcc/ChangeLog
gcc/config/ia64/ia64.md

index 3873a00ebe405a866f714d44c96ca1b09d9d9406..30c42db8e1a8a637de3380027ec9a73f2c4d5dbd 100644 (file)
@@ -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,
index 1f99ab6d90817b47fcc8821e7fe72d5f1627b924..6a6f91f29696e932b3c0526bbeaf60765a4602bb 100644 (file)
 
 ;; 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")
This page took 0.082014 seconds and 5 git commands to generate.