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