gcc/
        * config/xtensa/xtensa.cc (xtensa_zero_call_used_regs): Handle
        double precision FPU registers by emitting gen_movdf_concat.
        * config/xtensa/xtensa.md (UNSPEC_CONCAT): New unspec constant.
        (movdf_concat): New pattern.
---
 gcc/config/xtensa/xtensa.cc |  4 ++++
 gcc/config/xtensa/xtensa.md | 11 +++++++++++
 2 files changed, 15 insertions(+)

diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index 0343c35bd194..a0a61a3a14a0 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -5670,6 +5670,10 @@ xtensa_zero_call_used_regs (HARD_REG_SET selected_regs)
                                           rtvec_alloc (0),
                                           UNKNOWN_LOCATION));
        }
+      else if (TARGET_FLOAT64 && FP_REG_P (regno))
+       emit_insn (gen_movdf_concat (gen_rtx_REG (DFmode, regno),
+                                    gen_rtx_REG (SImode, zeroed_regno),
+                                    gen_rtx_REG (SImode, zeroed_regno)));
       else if (TARGET_FLOAT32 && FP_REG_P (regno))
        emit_move_insn (gen_rtx_REG (SFmode, regno),
                        gen_rtx_REG (SFmode, zeroed_regno));
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 458ffb0aea09..95797109205b 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -44,6 +44,7 @@
   UNSPEC_CEIL
   UNSPEC_FLOOR
   UNSPEC_ROUND
+  UNSPEC_CONCAT
 ])
 
 (define_c_enum "unspecv" [
@@ -1630,6 +1631,16 @@
 }
   [(set_attr "mode" "DF")])
 
+(define_insn "movdf_concat"
+  [(set (match_operand:DF 0 "register_operand" "=f")
+       (unspec:DF [(match_operand:SI 1 "register_operand" "r")
+                   (match_operand:SI 2 "register_operand" "r")] 
UNSPEC_CONCAT))]
+  "TARGET_FLOAT64"
+  "wfrd\t%0, %1, %2"
+  [(set_attr "type"    "farith")
+   (set_attr "mode"    "DF")
+   (set_attr "length"  "3")])
+
 ;; Block moves
 
 (define_expand "cpymemsi"
-- 
2.47.3

Reply via email to