Hi Max,

On 2026/10/12 22:44, Max Filippov wrote:
Suwa-san,

could you please take a look?

Max Filippov (3):
   gcc: xtensa: add DFPU support
   gcc: xtensa: zero DF FPU registers
   gcc: xtensa: add conversion tests

  gcc/config/xtensa/constraints.md              |   2 +-
  gcc/config/xtensa/xtensa-protos.h             |   2 +-
  gcc/config/xtensa/xtensa.cc                   | 169 +++++---
  gcc/config/xtensa/xtensa.h                    |  26 +-
  gcc/config/xtensa/xtensa.md                   | 365 ++++++++++--------
  .../xtensa/constsynthV2_O2_costs0.c           |   3 +-
  gcc/testsuite/gcc.target/xtensa/double-conv.c |  44 +++
  .../gcc.target/xtensa/elim_callee_saved.c     |   3 +-
  gcc/testsuite/gcc.target/xtensa/float-conv.c  |  31 ++
  9 files changed, 425 insertions(+), 220 deletions(-)
  create mode 100644 gcc/testsuite/gcc.target/xtensa/double-conv.c
  create mode 100644 gcc/testsuite/gcc.target/xtensa/float-conv.c


Oh, what a ton of changes!

I tried it out a little, but here is what I noticed at a glance:

-- TARGET_FLOAT32/64 @ xtensa.h
Is it possible to configure XCHAL_HAVE_DFP without configuring XCHAL_HAVE_FP?
If so, providing patterns that emulate SFmode operations using DFmode ones 
might be advantageous compared to falling back to the SFmode softmath library.

-- TARGET_HARD_FLOAT_CONST @ xtensa.h
Is CONST.D available when TARGET_FLOAT32_*s are true and TARGET_FLOAT64_*s are 
false?
Similarly, is CONST.S available when TARGET_FLOAT32_*s are false and 
TARGET_FLOAT64_*s are true?

-- movdf_internal @ xtensa.md
It would be advantageous to have an alternative to assigning the constant 0.0 
to an address register pair:
        "movi a3, 0; movi a2, 0"
is faster and smaller than
        "const.d f0, 0" followed by "rfrd a3, f0; rfr a2, f0"

-- movdf_internal @ xtensa.md
The instructions corresponding to "df-load-a-from-T\t%0, %1" consist of two 
pairs, each comprising an L32R instruction (3 bytes) and a literal pool entry (4 bytes).

-- xtensa_class_max_nregs() @ xtensa.cc
Addressed the issue where DFmode register number allocation for the FP_REGS 
register class skipped every other register.

=====
mailto:[email protected]

---
 gcc/config/xtensa/constraints.md |  2 +-
 gcc/config/xtensa/xtensa.cc      | 15 +++++++++++++++
 gcc/config/xtensa/xtensa.md      | 10 +++++++---
 3 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/gcc/config/xtensa/constraints.md b/gcc/config/xtensa/constraints.md
index e0b3dfa1713..0344bed6e3b 100644
--- a/gcc/config/xtensa/constraints.md
+++ b/gcc/config/xtensa/constraints.md
@@ -133,7 +133,7 @@
       (match_test "rval->cl == rvc_zero && rval->sign == 0")))
(define_constraint "Gc"
- "A single Floating-point constant for use with CONST.S instructions."
+ "A single Floating-point constant for use with CONST.[SD] instructions."
  (and (match_code "const_double")
       (match_test "TARGET_HARD_FLOAT_CONST && xtensa_fp_const (rval) >= 0")))
diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index a0a61a3a14a..d7420fffec2 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -180,6 +180,7 @@ static bool xtensa_member_type_forces_blk (const_tree,
static void xtensa_conditional_register_usage (void);
 static unsigned int xtensa_hard_regno_nregs (unsigned int, machine_mode);
+static unsigned char xtensa_class_max_nregs (reg_class_t, machine_mode);
 static bool xtensa_hard_regno_mode_ok (unsigned int, machine_mode);
 static bool xtensa_modes_tieable_p (machine_mode, machine_mode);
 static HOST_WIDE_INT xtensa_constant_alignment (const_tree, HOST_WIDE_INT);
@@ -339,6 +340,10 @@ static tree xtensa_handle_force_l32_attribute (tree *, 
tree, tree, int, bool *);
#undef TARGET_HARD_REGNO_NREGS
 #define TARGET_HARD_REGNO_NREGS xtensa_hard_regno_nregs
+
+#undef TARGET_CLASS_MAX_NREGS
+#define TARGET_CLASS_MAX_NREGS xtensa_class_max_nregs
+
 #undef TARGET_HARD_REGNO_MODE_OK
 #define TARGET_HARD_REGNO_MODE_OK xtensa_hard_regno_mode_ok
@@ -3114,6 +3119,16 @@ xtensa_hard_regno_nregs (unsigned int regno, machine_mode mode)
   return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
 }
+/* Implement TARGET_CLASS_MAX_NREGS. */
+
+static unsigned char
+xtensa_class_max_nregs (reg_class_t rclass, machine_mode mode)
+{
+  if (rclass == FP_REGS)
+    return CEIL (GET_MODE_SIZE (mode), UNITS_PER_FPREG);
+  return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
+}
+
 /* Implement TARGET_HARD_REGNO_MODE_OK.  */
static bool
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 95797109205..09adf915299 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -1608,6 +1608,8 @@
   "register_operand (operands[0], DFmode)
    || register_operand (operands[1], DFmode)"
   {@ [cons: =0, 1; attrs: type, length]
+     [D, Gz; move  , 4] movi.n\t%T0, 0\;movi.n\t%B0, 0
+     [a, Gz; move  , 6] movi\t%T0, 0\;movi\t%B0, 0
      [f, Gc; farith, 3] const.d\t%0, %G1
      [f,  r; farith, 3] wfrd\t%0, %T1, %B1
      [a,  f; farith, 6] rfrd\t%T0, %1\;rfr\t%B0, %1
@@ -1616,7 +1618,7 @@
      [U,  f; fstore, 3] %v0sdi\t%1, %0
      [a,  r; move  , 6] df-move-a-from-r\t%0, %1
      [a,  Y; load  , 6] df-load-a-from-Y\t%0, %1
-     [a,  T; load  , 6] df-load-a-from-T\t%0, %1
+     [a,  T; load  ,14] df-load-a-from-T\t%0, %1
      [a,  U; load  , 6] df-load-a-from-U\t%0, %1
      [U,  r; store , 6] df-store-r-to-U\t%0, %1
   }
@@ -1624,8 +1626,10 @@
   [(set (match_dup 0) (match_dup 2))
    (set (match_dup 1) (match_dup 3))]
 {
-  if ((register_operand (operands[0], DFmode) && REGNO_REG_CLASS (REGNO 
(operands[0])) == FP_REGS)
-      || (register_operand (operands[1], DFmode) && REGNO_REG_CLASS (REGNO 
(operands[1])) == FP_REGS))
+  if ((register_operand (operands[0], DFmode)
+       && (FP_REG_P (REGNO (operands[0])) || CONSTANT_P (operands[1])))
+      || (register_operand (operands[1], DFmode)
+         && FP_REG_P (REGNO (operands[1]))))
     FAIL;
   xtensa_split_operand_pair (operands, SFmode);
 }
--
2.39.5

Reply via email to