[gcc r14-9480] gcc: xtensa: reorder movsi_internal patterns for better code generation during LRA

2024-03-14 Thread Max Filippov via Gcc-cvs
https://gcc.gnu.org/g:bc5a9dab55d13f888a3cdd150c8cf5c2244f35e0

commit r14-9480-gbc5a9dab55d13f888a3cdd150c8cf5c2244f35e0
Author: Max Filippov 
Date:   Thu Mar 14 04:20:36 2024 -0700

gcc: xtensa: reorder movsi_internal patterns for better code generation 
during LRA

After switching to LRA xtensa backend generates the following code for
saving/loading registers:

movi a9, 0x190
add  a9, a9, sp
s32i.n   a3, a9, 0

instead of the shorter and more efficient

s32i a3, a9, 0x190

E.g. the following code can be used to reproduce it:

int f1(int a, int b, int c, int d, int e, int f, int *p);
int f2(int a, int b, int c, int d, int e, int f, int *p);
int f3(int a, int b, int c, int d, int e, int f, int *p);

int foo(int a, int b, int c, int d, int e, int f)
{
int g[100];
return
f1(a, b, c, d, e, f, g) +
f2(a, b, c, d, e, f, g) +
f3(a, b, c, d, e, f, g);
}

This happens in the LRA pass because s32i.n and l32i.n are listed before
the s32i and l32i in the movsi_internal pattern and alternative
consideration loop stops early.

gcc/

* config/xtensa/xtensa.md (movsi_internal): Move l32i and s32i
patterns ahead of the l32i.n and s32i.n.

Diff:
---
 gcc/config/xtensa/xtensa.md | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 1a2249b059a..5cdf4dffe70 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -1270,13 +1270,15 @@
 })
 
 (define_insn "movsi_internal"
-  [(set (match_operand:SI 0 "nonimmed_operand" 
"=D,D,D,D,R,R,a,q,a,a,W,a,a,U,*a,*A")
-   (match_operand:SI 1 "move_operand" 
"M,D,d,R,D,d,r,r,I,Y,i,T,U,r,*A,*r"))]
+  [(set (match_operand:SI 0 "nonimmed_operand" 
"=D,D,D,a,U,D,R,R,a,q,a,a,W,a,*a,*A")
+   (match_operand:SI 1 "move_operand" 
"M,D,d,U,r,R,D,d,r,r,I,Y,i,T,*A,*r"))]
   "xtensa_valid_move (SImode, operands)"
   "@
movi.n\t%0, %x1
mov.n\t%0, %1
mov.n\t%0, %1
+   %v1l32i\t%0, %1
+   %v0s32i\t%1, %0
%v1l32i.n\t%0, %1
%v0s32i.n\t%1, %0
%v0s32i.n\t%1, %0
@@ -1286,13 +1288,11 @@
movi\t%0, %1
const16\t%0, %t1\;const16\t%0, %b1
%v1l32r\t%0, %1
-   %v1l32i\t%0, %1
-   %v0s32i\t%1, %0
rsr\t%0, ACCLO
wsr\t%1, ACCLO"
-  [(set_attr "type"
"move,move,move,load,store,store,move,move,move,move,move,load,load,store,rsr,wsr")
+  [(set_attr "type"
"move,move,move,load,store,load,store,store,move,move,move,move,move,load,rsr,wsr")
(set_attr "mode""SI")
-   (set_attr "length"  "2,2,2,2,2,2,3,3,3,3,6,3,3,3,3,3")])
+   (set_attr "length"  "2,2,2,3,3,2,2,2,3,3,3,3,6,3,3,3")])
 
 (define_split
   [(set (match_operand:SHI 0 "register_operand")


[gcc r14-9638] xtensa: Add supplementary split pattern for "*addsubx"

2024-03-22 Thread Max Filippov via Gcc-cvs
https://gcc.gnu.org/g:7a01cc711f33530436712a5bfd18f8457a68ea1f

commit r14-9638-g7a01cc711f33530436712a5bfd18f8457a68ea1f
Author: Takayuki 'January June' Suwa 
Date:   Fri Mar 22 08:36:30 2024 +0900

xtensa: Add supplementary split pattern for "*addsubx"

int test(int a) {
   return a * 4 + 3;
}

In the example above, since Xtensa has instructions to add register value
scaled by 2, 4 or 8 (and corresponding define_insns), we would expect them
to be used but not, because it is transformed before reaching the RTL
generation pass as below:

int test(int a) {
   return (a + 7500) * 4;
}

Fortunately, the RTL combination pass tries a splitting pattern that matches
the first example, so it is easy to solve by defining that pattern.

gcc/ChangeLog:

* config/xtensa/xtensa.md: Add new split pattern described above.

Diff:
---
 gcc/config/xtensa/xtensa.md | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 5cdf4dffe70..fbe40ec671a 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -194,6 +194,20 @@
(set_attr "mode""SI")
(set_attr "length"  "3")])
 
+(define_split
+  [(set (match_operand:SI 0 "register_operand")
+   (plus:SI (ashift:SI (match_operand:SI 1 "register_operand")
+   (match_operand:SI 3 "addsubx_operand"))
+(match_operand:SI 2 "const_int_operand")))]
+  "TARGET_ADDX && can_create_pseudo_p ()"
+  [(set (match_dup 0)
+   (plus:SI (ashift:SI (match_dup 1)
+   (match_dup 3))
+(match_dup 2)))]
+{
+  operands[2] = force_reg (SImode, operands[2]);
+})
+
 (define_expand "adddi3"
   [(set (match_operand:DI 0 "register_operand")
(plus:DI (match_operand:DI 1 "register_operand")


[gcc r14-9655] libgcc: arm: fix build for FDPIC target

2024-03-25 Thread Max Filippov via Gcc-cvs
https://gcc.gnu.org/g:c2e68ff9edd5da7a55ba6574b4ce49ce6495b18d

commit r14-9655-gc2e68ff9edd5da7a55ba6574b4ce49ce6495b18d
Author: Max Filippov 
Date:   Fri Mar 22 13:03:46 2024 -0700

libgcc: arm: fix build for FDPIC target

libgcc/
* unwind-arm-common.inc (__gnu_personality_sigframe_fdpic): Cast
last argument of _Unwind_VRS_Set to void *.

Diff:
---
 libgcc/unwind-arm-common.inc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libgcc/unwind-arm-common.inc b/libgcc/unwind-arm-common.inc
index 5453f38186b..576f7e93e8a 100644
--- a/libgcc/unwind-arm-common.inc
+++ b/libgcc/unwind-arm-common.inc
@@ -248,7 +248,7 @@ __gnu_personality_sigframe_fdpic (_Unwind_State state,
  + ARM_SIGCONTEXT_R0;
 /* Restore regs saved on stack by the kernel.  */
 for (i = 0; i < 16; i++)
-   _Unwind_VRS_Set (context, _UVRSC_CORE, i, _UVRSD_UINT32, sp + 4 * i);
+   _Unwind_VRS_Set (context, _UVRSC_CORE, i, _UVRSD_UINT32, (void *)(sp + 
4 * i));
 
 return _URC_CONTINUE_UNWIND;
 }


[gcc r15-2385] gcc: xtensa: disable late-combine by default

2024-07-29 Thread Max Filippov via Gcc-cvs
https://gcc.gnu.org/g:9d5d6e61500411ea9043258e300d5b0f57e5c391

commit r15-2385-g9d5d6e61500411ea9043258e300d5b0f57e5c391
Author: Max Filippov 
Date:   Fri Jul 19 17:27:03 2024 -0700

gcc: xtensa: disable late-combine by default

gcc/
* config/xtensa/xtensa.cc (xtensa_option_override_after_change):
New function.
(TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE): Define as
xtensa_option_override_after_change.
(xtensa_option_override): Call
xtensa_option_override_after_change.

Diff:
---
 gcc/config/xtensa/xtensa.cc | 13 +
 1 file changed, 13 insertions(+)

diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index d49d224466ad..10d964b51a96 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -114,6 +114,7 @@ struct GTY(()) machine_function
 };
 
 static void xtensa_option_override (void);
+static void xtensa_option_override_after_change (void);
 static enum internal_test map_test_to_internal_test (enum rtx_code);
 static rtx gen_int_relational (enum rtx_code, rtx, rtx);
 static rtx gen_float_relational (enum rtx_code, rtx, rtx);
@@ -303,6 +304,9 @@ static rtx xtensa_delegitimize_address (rtx);
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE xtensa_option_override
 
+#undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
+#define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE 
xtensa_option_override_after_change
+
 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA xtensa_output_addr_const_extra
 
@@ -2988,6 +2992,15 @@ xtensa_option_override (void)
  the define_insn_and_splits are fixed.  */
   if (!OPTION_SET_P (flag_late_combine_instructions))
 flag_late_combine_instructions = 0;
+
+  xtensa_option_override_after_change ();
+}
+
+static void
+xtensa_option_override_after_change (void)
+{
+  if (!OPTION_SET_P (flag_late_combine_instructions))
+flag_late_combine_instructions = 0;
 }
 
 /* Implement TARGET_HARD_REGNO_NREGS.  */


[gcc r15-2391] xtensa: Make use of std::swap where appropriate

2024-07-29 Thread Max Filippov via Gcc-cvs
https://gcc.gnu.org/g:56c4979dd8be40681f2724861fc41ae6135e1e78

commit r15-2391-g56c4979dd8be40681f2724861fc41ae6135e1e78
Author: Takayuki 'January June' Suwa 
Date:   Sun Jul 14 20:03:13 2024 +0900

xtensa: Make use of std::swap where appropriate

No functional changes.

gcc/ChangeLog:

* config/xtensa/xtensa.cc
(gen_int_relational, gen_float_relational): Replace tempvar-based
value-swapping codes with std::swap.
* config/xtensa/xtensa.md (movdi_internal, movdf_internal):
Ditto.

Diff:
---
 gcc/config/xtensa/xtensa.cc | 12 ++--
 gcc/config/xtensa/xtensa.md | 10 --
 2 files changed, 6 insertions(+), 16 deletions(-)

diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index 10d964b51a96..772150c7fa22 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -794,11 +794,7 @@ gen_int_relational (enum rtx_code test_code, /* relational 
test (EQ, etc) */
 
 }
   else if (p_info->reverse_regs)
-{
-  rtx temp = cmp0;
-  cmp0 = cmp1;
-  cmp1 = temp;
-}
+std::swap (cmp0, cmp1);
 
   return gen_rtx_fmt_ee (invert ? reverse_condition (p_info->test_code)
: p_info->test_code,
@@ -842,11 +838,7 @@ gen_float_relational (enum rtx_code test_code, /* 
relational test (EQ, etc) */
 }
 
   if (reverse_regs)
-{
-  rtx temp = cmp0;
-  cmp0 = cmp1;
-  cmp1 = temp;
-}
+std::swap (cmp0, cmp1);
 
   brtmp = gen_rtx_REG (CCmode, FPCC_REGNUM);
   emit_insn (gen_fn (brtmp, cmp0, cmp1));
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 8709ef6d7a7d..0fcbb0b7bc37 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -1215,9 +1215,8 @@
   xtensa_split_operand_pair (operands, SImode);
   if (reg_overlap_mentioned_p (operands[0], operands[3]))
 {
-  rtx tmp;
-  tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
-  tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
+  std::swap (operands[0], operands[1]);
+  std::swap (operands[2], operands[3]);
 }
 })
 
@@ -1562,9 +1561,8 @@
   xtensa_split_operand_pair (operands, SFmode);
   if (reg_overlap_mentioned_p (operands[0], operands[3]))
 {
-  rtx tmp;
-  tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
-  tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
+  std::swap (operands[0], operands[1]);
+  std::swap (operands[2], operands[3]);
 }
 })


[gcc r15-2392] xtensa: Make use of scaled [U]FLOAT/TRUNC.S instructions

2024-07-29 Thread Max Filippov via Gcc-cvs
https://gcc.gnu.org/g:f9c7775f58798a051b57356ad321b758a2ee837d

commit r15-2392-gf9c7775f58798a051b57356ad321b758a2ee837d
Author: Takayuki 'January June' Suwa 
Date:   Sun Jul 14 20:04:15 2024 +0900

xtensa: Make use of scaled [U]FLOAT/TRUNC.S instructions

[U]FLOAT.S machine instruction in Xtensa ISA, which converts an integer to
a hardware single-precision FP register, has the ability to divide the
result by power of two (0 to 15th).

Similarly, [U]TRUNC.S instruction, which truncates single-precision FP to
integer, can multiply the source value by power of two in advance, but
neither of these currently uses this function (always specified with 0th
power of two, i.e. a scaling factor of 1).

This patch unleashes the scaling ability of the above instructions.

 /* example */
 float test0(int a) {
   return a / 2.f;
 }
 float test1(unsigned int a) {
   return a / 32768.f;
 }
 int test2(float a) {
   return a * 2;
 }
 unsigned int test3(float a) {
   return a * 32768;
 }

 ;; before
 test0:
movi.n  a9, 0x3f
float.s f0, a2, 0
sllia9, a9, 24
wfr f1, a9
mul.s   f0, f0, f1
rfr a2, f0
ret.n
 test1:
movi.n  a9, 7
ufloat.sf0, a2, 0
sllia9, a9, 27
wfr f1, a9
mul.s   f0, f0, f1
rfr a2, f0
ret.n
 test2:
wfr f1, a2
add.s   f0, f1, f1
trunc.s a2, f0, 0
ret.n
 test3:
movi.n  a9, 0x47
sllia9, a9, 24
wfr f1, a2
wfr f2, a9
mul.s   f0, f1, f2
utrunc.sa2, f0, 0
ret.n

 ;; after
 test0:
float.s f0, a2, 1
rfr a2, f0
ret.n
 test1:
ufloat.sf0, a2, 15
rfr a2, f0
ret.n
 test2:
wfr f0, a2
trunc.s a2, f0, 1
ret.n
 test3:
wfr f0, a2
utrunc.sa2, f0, 15
ret.n

gcc/ChangeLog:

* config/xtensa/predicates.md
(fix_scaling_operand, float_scaling_operand): New predicates.
* config/xtensa/xtensa.md
(any_fix/m_fix/s_fix, any_float/m_float/s_float):
New code iterators and their attributes.
(fix_truncsfsi2): Change from "fix_truncsfsi2".
(*fix_truncsfsi2_2x, *fix_truncsfsi2_scaled):
New insn definitions.
(floatsisf2): Change from "floatsisf2".
(*floatsisf2_scaled): New insn definition.

Diff:
---
 gcc/config/xtensa/predicates.md | 20 ++
 gcc/config/xtensa/xtensa.md | 58 -
 2 files changed, 66 insertions(+), 12 deletions(-)

diff --git a/gcc/config/xtensa/predicates.md b/gcc/config/xtensa/predicates.md
index 19b9f4cd7efe..e676fa4fb95c 100644
--- a/gcc/config/xtensa/predicates.md
+++ b/gcc/config/xtensa/predicates.md
@@ -159,6 +159,26 @@
   return real_equal (CONST_DOUBLE_REAL_VALUE (op), &dconst1);
 })
 
+(define_predicate "fix_scaling_operand"
+  (match_code "const_double")
+{
+  REAL_VALUE_TYPE r = *CONST_DOUBLE_REAL_VALUE (op);
+  int exp = REAL_EXP (&r) - 1;
+
+  SET_REAL_EXP (&r, 1);
+  return real_equal (&r, &dconst1) && IN_RANGE (exp, 2, 15);
+})
+
+(define_predicate "float_scaling_operand"
+  (match_code "const_double")
+{
+  REAL_VALUE_TYPE r = *CONST_DOUBLE_REAL_VALUE (op);
+  int exp = REAL_EXP (&r) - 1;
+
+  SET_REAL_EXP (&r, 1);
+  return real_equal (&r, &dconst1) && IN_RANGE (-exp, 1, 15);
+})
+
 (define_predicate "fpmem_offset_operand"
   (and (match_code "const_int")
(match_test "xtensa_mem_offset (INTVAL (op), SFmode)")))
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 0fcbb0b7bc37..376d0f755446 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -91,6 +91,18 @@
 ;; the same template.
 (define_mode_iterator SHI [SI HI])
 
+;; This iterator and attribute allow signed/unsigned FP truncations to be
+;; generated from one template.
+(define_code_iterator any_fix [fix unsigned_fix])
+(define_code_attr m_fix [(fix "trunc") (unsigned_fix "utrunc")])
+(define_code_attr s_fix [(fix "") (unsigned_fix "uns")])
+
+;; This iterator and attribute allow signed/unsigned FP conversions to be
+;; generated from one template.
+(define_code_iterator any_float [float unsigned_float])
+(define_code_attr m_float [(float "float") (unsigned_float "ufloat")])
+(define_code_attr s_float [(float "") (unsigned_float "uns")])
+
 
 ;; Attributes.
 
@@ -1132,38 +1144,60 @@
 
 ;; Conversions.
 
-(define_insn "fix_truncsfsi2"
+(define_insn "fix_truncsfsi

[gcc r15-2396] xtensa: Fix the regression introduce by r15-959-gbe9b3f4375e7

2024-07-29 Thread Max Filippov via Gcc-cvs
https://gcc.gnu.org/g:8ebb1d79ea16f37214c33d853061d3c9cf5e7f46

commit r15-2396-g8ebb1d79ea16f37214c33d853061d3c9cf5e7f46
Author: Takayuki 'January June' Suwa 
Date:   Sat Jul 20 05:35:33 2024 +0900

xtensa: Fix the regression introduce by r15-959-gbe9b3f4375e7

It is not wrong but also not optimal to specify that sibcalls require
register A0 in RTX generation pass, by misleading DFA into thinking it
is being used in function body.
It would be better to specify it in pro_and_epilogue as with 'return'
insn in order to avoid incorrect removing load that restores A0 in
subsequent passes, but since it is not possible to modify each sibcall
there, as a workaround we will preface it with a 'use' as before.

This patch effectively reverts commit r15-959-gbe9b3f4375e7

gcc/ChangeLog:

* config/xtensa/xtensa-protos.h (xtensa_expand_call):
Remove the third argument.
* config/xtensa/xtensa.cc (xtensa_expand_call):
Remove the third argument and the code that uses it.
* config/xtensa/xtensa.md (call, call_value, sibcall, 
sibcall_value):
Remove each Boolean constant specified in the third argument of
xtensa_expand_call.
(sibcall_epilogue): Add emitting '(use A0_REG)' after calling
xtensa_expand_epilogue.

Diff:
---
 gcc/config/xtensa/xtensa-protos.h |  2 +-
 gcc/config/xtensa/xtensa.cc   | 10 +-
 gcc/config/xtensa/xtensa.md   |  9 +
 3 files changed, 7 insertions(+), 14 deletions(-)

diff --git a/gcc/config/xtensa/xtensa-protos.h 
b/gcc/config/xtensa/xtensa-protos.h
index 8f645e87de96..3646ceaa0938 100644
--- a/gcc/config/xtensa/xtensa-protos.h
+++ b/gcc/config/xtensa/xtensa-protos.h
@@ -53,7 +53,7 @@ extern void xtensa_expand_atomic (enum rtx_code, rtx, rtx, 
rtx, bool);
 extern void xtensa_emit_loop_end (rtx_insn *, rtx *);
 extern char *xtensa_emit_branch (bool, rtx *);
 extern char *xtensa_emit_movcc (bool, bool, bool, rtx *);
-extern void xtensa_expand_call (int, rtx *, bool);
+extern void xtensa_expand_call (int, rtx *);
 extern char *xtensa_emit_call (int, rtx *);
 extern char *xtensa_emit_sibcall (int, rtx *);
 extern bool xtensa_tls_referenced_p (rtx);
diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index 772150c7fa22..1ccd42bcda89 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -2297,7 +2297,7 @@ xtensa_emit_movcc (bool inverted, bool isfp, bool isbool, 
rtx *operands)
 
 
 void
-xtensa_expand_call (int callop, rtx *operands, bool sibcall_p)
+xtensa_expand_call (int callop, rtx *operands)
 {
   rtx call;
   rtx_insn *call_insn;
@@ -2339,14 +2339,6 @@ xtensa_expand_call (int callop, rtx *operands, bool 
sibcall_p)
   CALL_INSN_FUNCTION_USAGE (call_insn) =
gen_rtx_EXPR_LIST (Pmode, clob, CALL_INSN_FUNCTION_USAGE (call_insn));
 }
-  else if (sibcall_p)
-{
-  /* Sibling call requires a return address to the caller, similar to
-"return" insn.  */
-  rtx use = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, A0_REG));
-  CALL_INSN_FUNCTION_USAGE (call_insn) =
-   gen_rtx_EXPR_LIST (Pmode, use, CALL_INSN_FUNCTION_USAGE (call_insn));
-}
 }
 
 
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 376d0f755446..a3b99dc381de 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -2597,7 +2597,7 @@
 (match_operand 1 "" ""))]
   ""
 {
-  xtensa_expand_call (0, operands, false);
+  xtensa_expand_call (0, operands);
   DONE;
 })
 
@@ -2618,7 +2618,7 @@
  (match_operand 2 "" "")))]
   ""
 {
-  xtensa_expand_call (1, operands, false);
+  xtensa_expand_call (1, operands);
   DONE;
 })
 
@@ -2639,7 +2639,7 @@
 (match_operand 1 "" ""))]
   "!TARGET_WINDOWED_ABI"
 {
-  xtensa_expand_call (0, operands, true);
+  xtensa_expand_call (0, operands);
   DONE;
 })
 
@@ -2660,7 +2660,7 @@
  (match_operand 2 "" "")))]
   "!TARGET_WINDOWED_ABI"
 {
-  xtensa_expand_call (1, operands, true);
+  xtensa_expand_call (1, operands);
   DONE;
 })
 
@@ -2777,6 +2777,7 @@
   "!TARGET_WINDOWED_ABI"
 {
   xtensa_expand_epilogue ();
+  emit_use (gen_rtx_REG (SImode, A0_REG));
   DONE;
 })


[gcc r15-2397] xtensa: Fix suboptimal loading of pooled constant value into hardware single-precision FP register

2024-07-29 Thread Max Filippov via Gcc-cvs
https://gcc.gnu.org/g:fb7b82964f54192d0723a45c0657d2eb7c5ac97c

commit r15-2397-gfb7b82964f54192d0723a45c0657d2eb7c5ac97c
Author: Takayuki 'January June' Suwa 
Date:   Tue Jul 23 16:03:12 2024 +0900

xtensa: Fix suboptimal loading of pooled constant value into hardware 
single-precision FP register

We would like to implement the following to store a single-precision FP
constant in a hardware FP register:

- Load the bit-exact integer image of the pooled single-precision FP
  constant into an address (integer) register
- Then, assign from that address register to a hardware single-precision
  FP register

.literal_position
.literal.LC1, 0x3f80
...
l32ra9, .LC1
wfr f0, a9

However, it was emitted as follows:

- Load the address of the FP constant entry in litpool into an address
  register
- Then, dereference the address via that address register into a hardware
  single-precision FP register

.literal_position
.literal.LC1, 0x3f80
.literal.LC2, .LC1
...
l32ra9, .LC2
lsi f0, a9, 0

It is obviously inefficient to read the pool twice.

gcc/ChangeLog:

* config/xtensa/xtensa.md (movsf_internal):
Reorder alternative that corresponds to L32R machine instruction,
and prefix alternatives that correspond to LSI/SSI instructions
with the constraint character '^' so that they are disparaged by
reload/LRA.

Diff:
---
 gcc/config/xtensa/xtensa.md | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index a3b99dc381de..f19e1fd16b54 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -1453,8 +1453,8 @@
 })
 
 (define_insn "movsf_internal"
-  [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,D,R,a,f,a,a,W,a,a,U")
-   (match_operand:SF 1 "move_operand" "f,U,f,d,R,d,r,r,f,Y,iF,T,U,r"))]
+  [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,^U,D,a,D,R,a,f,a,a,W,a,U")
+   (match_operand:SF 1 "move_operand" "f,^U,f,d,T,R,d,r,r,f,Y,iF,U,r"))]
   "((register_operand (operands[0], SFmode)
  || register_operand (operands[1], SFmode))
 && !(FP_REG_P (xt_true_regnum (operands[0]))
@@ -1464,6 +1464,7 @@
%v1lsi\t%0, %1
%v0ssi\t%1, %0
mov.n\t%0, %1
+   %v1l32r\t%0, %1
%v1l32i.n\t%0, %1
%v0s32i.n\t%1, %0
mov\t%0, %1
@@ -1471,12 +1472,11 @@
rfr\t%0, %1
movi\t%0, %y1
const16\t%0, %t1\;const16\t%0, %b1
-   %v1l32r\t%0, %1
%v1l32i\t%0, %1
%v0s32i\t%1, %0"
-  [(set_attr "type"
"farith,fload,fstore,move,load,store,move,farith,farith,move,move,load,load,store")
+  [(set_attr "type"
"farith,fload,fstore,move,load,load,store,move,farith,farith,move,move,load,store")
(set_attr "mode""SF")
-   (set_attr "length"  "3,3,3,2,2,2,3,3,3,3,6,3,3,3")])
+   (set_attr "length"  "3,3,3,2,3,2,2,3,3,3,3,6,3,3")])
 
 (define_insn "*lsiu"
   [(set (match_operand:SF 0 "register_operand" "=f")


[gcc r15-2398] xtensa: Add missing speed cost for TYPE_FARITH in TARGET_INSN_COST

2024-07-29 Thread Max Filippov via Gcc-cvs
https://gcc.gnu.org/g:c1d35de0d94d43b9976aff44001dadd4dd42b7ae

commit r15-2398-gc1d35de0d94d43b9976aff44001dadd4dd42b7ae
Author: Takayuki 'January June' Suwa 
Date:   Wed Jul 24 06:07:06 2024 +0900

xtensa: Add missing speed cost for TYPE_FARITH in TARGET_INSN_COST

According to the implemented pipeline model, this cost can be assumed to be
1 clock cycle.

gcc/ChangeLog:

* config/xtensa/xtensa.cc (xtensa_insn_cost):
Add a case statement for TYPE_FARITH.

Diff:
---
 gcc/config/xtensa/xtensa.cc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index 1ccd42bcda89..43b1332d42b3 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -4723,6 +4723,7 @@ xtensa_insn_cost (rtx_insn *insn, bool speed)
case TYPE_ARITH:
case TYPE_MULTI:
case TYPE_NOP:
+   case TYPE_FARITH:
case TYPE_FSTORE:
  return COSTS_N_INSNS (n);


[gcc r15-935] xtensa: Use REG_P(), MEM_P(), etc. instead of comparing GET_CODE()

2024-05-30 Thread Max Filippov via Gcc-cvs
https://gcc.gnu.org/g:1e091097b1b42fed562a6d80a6e08603d1c648a2

commit r15-935-g1e091097b1b42fed562a6d80a6e08603d1c648a2
Author: Takayuki 'January June' Suwa 
Date:   Thu May 30 22:32:24 2024 +0900

xtensa: Use REG_P(), MEM_P(), etc. instead of comparing GET_CODE()

Instead of comparing directly, this patch replaces as much as possible with
macros that determine RTX code such as REG_P(), SUBREG_P() or MEM_P(), etc.

gcc/ChangeLog:

* config/xtensa/xtensa.cc (xtensa_valid_move, 
constantpool_address_p,
xtensa_tls_symbol_p, gen_int_relational, xtensa_emit_move_sequence,
xtensa_copy_incoming_a7, xtensa_expand_block_move,
xtensa_expand_nonlocal_goto, xtensa_emit_call,
xtensa_legitimate_address_p, xtensa_legitimize_address,
xtensa_tls_referenced_p, print_operand, print_operand_address,
xtensa_output_literal):
Replace RTX code comparisons with their predicate macros such as
REG_P().
* config/xtensa/xtensa.h (CONSTANT_ADDRESS_P,
LEGITIMATE_PIC_OPERAND_P): Ditto.
* config/xtensa/xtensa.md (reload_literal, indirect_jump):
Ditto.

Diff:
---
 gcc/config/xtensa/xtensa.cc | 90 ++---
 gcc/config/xtensa/xtensa.h  | 10 ++---
 gcc/config/xtensa/xtensa.md |  4 +-
 3 files changed, 51 insertions(+), 53 deletions(-)

diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index 9beac932467..75973cfbac0 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -551,18 +551,18 @@ xtensa_valid_move (machine_mode mode, rtx *operands)
 int
 smalloffset_mem_p (rtx op)
 {
-  if (GET_CODE (op) == MEM)
+  if (MEM_P (op))
 {
   rtx addr = XEXP (op, 0);
-  if (GET_CODE (addr) == REG)
+  if (REG_P (addr))
return BASE_REG_P (addr, 0);
   if (GET_CODE (addr) == PLUS)
{
  rtx offset = XEXP (addr, 0);
  HOST_WIDE_INT val;
- if (GET_CODE (offset) != CONST_INT)
+ if (! CONST_INT_P (offset))
offset = XEXP (addr, 1);
- if (GET_CODE (offset) != CONST_INT)
+ if (! CONST_INT_P (offset))
return FALSE;
 
  val = INTVAL (offset);
@@ -596,7 +596,7 @@ constantpool_address_p (const_rtx addr)
   sym = XEXP (addr, 0);
 }
 
-  if ((GET_CODE (sym) == SYMBOL_REF)
+  if (SYMBOL_REF_P (sym)
   && CONSTANT_POOL_ADDRESS_P (sym))
 return true;
   return false;
@@ -606,9 +606,9 @@ constantpool_address_p (const_rtx addr)
 int
 constantpool_mem_p (rtx op)
 {
-  if (GET_CODE (op) == SUBREG)
+  if (SUBREG_P (op))
 op = SUBREG_REG (op);
-  if (GET_CODE (op) == MEM)
+  if (MEM_P (op))
 return constantpool_address_p (XEXP (op, 0));
   return FALSE;
 }
@@ -622,7 +622,7 @@ xtensa_tls_symbol_p (rtx x)
   if (! targetm.have_tls)
 return false;
 
-  return GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x) != 0;
+  return SYMBOL_REF_P (x) && SYMBOL_REF_TLS_MODEL (x) != 0;
 }
 
 
@@ -749,7 +749,7 @@ gen_int_relational (enum rtx_code test_code, /* relational 
test (EQ, etc) */
 mode = GET_MODE (cmp1);
 
   /* Make sure we can handle any constants given to us.  */
-  if (GET_CODE (cmp1) == CONST_INT)
+  if (CONST_INT_P (cmp1))
 {
   HOST_WIDE_INT value = INTVAL (cmp1);
   unsigned HOST_WIDE_INT uvalue = (unsigned HOST_WIDE_INT)value;
@@ -768,7 +768,7 @@ gen_int_relational (enum rtx_code test_code, /* relational 
test (EQ, etc) */
  cmp1 = force_reg (mode, cmp1);
}
 }
-  else if ((GET_CODE (cmp1) != REG) && (GET_CODE (cmp1) != SUBREG))
+  else if (! REG_P (cmp1) && ! SUBREG_P (cmp1))
 {
   cmp1 = force_reg (mode, cmp1);
 }
@@ -780,7 +780,7 @@ gen_int_relational (enum rtx_code test_code, /* relational 
test (EQ, etc) */
 
   /* Comparison to constants, may involve adding 1 to change a LT into LE.
  Comparison between two registers, may involve switching operands.  */
-  if (GET_CODE (cmp1) == CONST_INT)
+  if (CONST_INT_P (cmp1))
 {
   if (p_info->const_add != 0)
cmp1 = GEN_INT (INTVAL (cmp1) + p_info->const_add);
@@ -1271,7 +1271,7 @@ xtensa_emit_move_sequence (rtx *operands, machine_mode 
mode)
   rtx src = operands[1];
 
   if (CONSTANT_P (src)
-  && (GET_CODE (src) != CONST_INT || ! xtensa_simm12b (INTVAL (src
+  && (! CONST_INT_P (src) || ! xtensa_simm12b (INTVAL (src
 {
   rtx dst = operands[0];
 
@@ -1368,12 +1368,12 @@ xtensa_copy_incoming_a7 (rtx opnd)
   /* The operand using a7 may come in a later instruction, so just return
  the original operand if it doesn't use a7.  */
   reg = opnd;
-  if (GET_CODE (reg) == SUBREG)
+  if (SUBREG_P (reg))
 {
   gcc_assert (SUBREG_BYTE (reg) == 0);
   reg = SUBREG_REG (reg);
 }
-  if (GET_CODE (reg) != REG
+  if (! REG_P (reg)
   || REGNO (reg) > A7_REG
   || REGNO (reg) + hard_regno_nregs (A7_REG, mode) <= A7_REG)
   

[gcc r15-936] xtensa: Use epilogue_completed rather than cfun->machine->epilogue_done

2024-05-30 Thread Max Filippov via Gcc-cvs
https://gcc.gnu.org/g:1b58f46ba2079b327580ffa1720c0b40ab3db74d

commit r15-936-g1b58f46ba2079b327580ffa1720c0b40ab3db74d
Author: Takayuki 'January June' Suwa 
Date:   Thu May 30 22:32:24 2024 +0900

xtensa: Use epilogue_completed rather than cfun->machine->epilogue_done

In commit ad89d820bf, an "epilogue_done" member was added to the
machine_function structure, but it is sufficient to use the existing
"epilogue_completed" global variable.

gcc/ChangeLog:

* config/xtensa/xtensa-protos.h
(xtensa_use_return_instruction_p): Remove.
* config/xtensa/xtensa.cc
(machine_function): Remove "epilogue_done" field.
(xtensa_expand_epilogue): Remove "cfun->machine->epilogue_done" 
usage.
(xtensa_use_return_instruction_p): Remove.
* config/xtensa/xtensa.md ("return"):
Replace calling "xtensa_use_return_instruction_p()" with inline 
code.

Diff:
---
 gcc/config/xtensa/xtensa-protos.h |  1 -
 gcc/config/xtensa/xtensa.cc   | 14 --
 gcc/config/xtensa/xtensa.md   |  5 -
 3 files changed, 4 insertions(+), 16 deletions(-)

diff --git a/gcc/config/xtensa/xtensa-protos.h 
b/gcc/config/xtensa/xtensa-protos.h
index 508d5b28aa2..b87b3e8ac48 100644
--- a/gcc/config/xtensa/xtensa-protos.h
+++ b/gcc/config/xtensa/xtensa-protos.h
@@ -76,7 +76,6 @@ extern rtx xtensa_return_addr (int, rtx);
 extern void xtensa_setup_frame_addresses (void);
 extern int xtensa_debugger_regno (int);
 extern long compute_frame_size (poly_int64);
-extern bool xtensa_use_return_instruction_p (void);
 extern void xtensa_expand_prologue (void);
 extern void xtensa_expand_epilogue (bool);
 extern void xtensa_adjust_reg_alloc_order (void);
diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index 75973cfbac0..84268db5c9d 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -104,7 +104,6 @@ struct GTY(()) machine_function
  compute_frame_size.  */
   int callee_save_size;
   bool frame_laid_out;
-  bool epilogue_done;
   bool inhibit_logues_a1_adjusts;
   rtx last_logues_a9_content;
   HARD_REG_SET eliminated_callee_saved;
@@ -3747,25 +3746,12 @@ xtensa_expand_epilogue (bool sibcall_p)
  stack_pointer_rtx,
  EH_RETURN_STACKADJ_RTX));
 }
-  cfun->machine->epilogue_done = true;
   if (sibcall_p)
 emit_use (gen_rtx_REG (SImode, A0_REG));
   else
 emit_jump_insn (gen_return ());
 }
 
-bool
-xtensa_use_return_instruction_p (void)
-{
-  if (!reload_completed)
-return false;
-  if (TARGET_WINDOWED_ABI)
-return true;
-  if (compute_frame_size (get_frame_size ()) == 0)
-return true;
-  return cfun->machine->epilogue_done;
-}
-
 void
 xtensa_set_return_address (rtx address, rtx scratch)
 {
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 1b82a12d879..6061a86ee13 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -2735,7 +2735,10 @@
 (define_insn "return"
   [(return)
(use (reg:SI A0_REG))]
-  "xtensa_use_return_instruction_p ()"
+  "reload_completed
+   && (TARGET_WINDOWED_ABI
+   || compute_frame_size (get_frame_size ()) == 0
+   || epilogue_completed)"
 {
   return TARGET_WINDOWED_ABI ?
   (TARGET_DENSITY ? "retw.n" : "retw") :


[gcc r15-958] xtensa: Simplify several MD templates

2024-05-31 Thread Max Filippov via Gcc-cvs
https://gcc.gnu.org/g:68cda24d3ac12292a599ff8f9b58fdbc95baba4e

commit r15-958-g68cda24d3ac12292a599ff8f9b58fdbc95baba4e
Author: Takayuki 'January June' Suwa 
Date:   Fri May 31 19:23:13 2024 +0900

xtensa: Simplify several MD templates

No functional changes.

gcc/ChangeLog:

* config/xtensa/predicates.md
(subreg_HQI_lowpart_operator, xtensa_sminmax_operator):
New operator predicates.
* config/xtensa/xtensa-protos.h (xtensa_match_CLAMPS_imms_p):
Remove.
* config/xtensa/xtensa.cc (xtensa_match_CLAMPS_imms_p): Ditto.
* config/xtensa/xtensa.md
(*addsubx, *extzvsi-1bit_ashlsi3, *extzvsi-1bit_addsubx):
Revise the output statements by conditional ternary operator rather
than switch-case clause in order to avoid using gcc_unreachable().
(xtensa_clamps): Reduce to a single pattern definition using the
predicate added above.
(Some split patterns to assist *masktrue_const_bitcmpl): Ditto.

Diff:
---
 gcc/config/xtensa/predicates.md   |  23 
 gcc/config/xtensa/xtensa-protos.h |   1 -
 gcc/config/xtensa/xtensa.cc   |  10 
 gcc/config/xtensa/xtensa.md   | 109 +++---
 4 files changed, 43 insertions(+), 100 deletions(-)

diff --git a/gcc/config/xtensa/predicates.md b/gcc/config/xtensa/predicates.md
index a296c7ecc99..19b9f4cd7ef 100644
--- a/gcc/config/xtensa/predicates.md
+++ b/gcc/config/xtensa/predicates.md
@@ -200,6 +200,29 @@
 (define_predicate "xtensa_bit_join_operator"
   (match_code "plus,ior"))
 
+(define_predicate "subreg_HQI_lowpart_operator"
+  (match_code "subreg")
+{
+  int ofs = SUBREG_BYTE (op), pos = 0;
+  switch (GET_MODE (op))
+{
+case QImode:
+  if (BYTES_BIG_ENDIAN)
+   pos = 3;
+  break;
+case HImode:
+  if (BYTES_BIG_ENDIAN)
+   pos = 2;
+  break;
+default:
+  return false;
+}
+  return ofs == pos;
+})
+
+(define_predicate "xtensa_sminmax_operator"
+  (match_code "smin,smax"))
+
 (define_predicate "tls_symbol_operand"
   (and (match_code "symbol_ref")
(match_test "SYMBOL_REF_TLS_MODEL (op) != 0")))
diff --git a/gcc/config/xtensa/xtensa-protos.h 
b/gcc/config/xtensa/xtensa-protos.h
index b87b3e8ac48..834f15e0e48 100644
--- a/gcc/config/xtensa/xtensa-protos.h
+++ b/gcc/config/xtensa/xtensa-protos.h
@@ -60,7 +60,6 @@ extern bool xtensa_tls_referenced_p (rtx);
 extern enum rtx_code xtensa_shlrd_which_direction (rtx, rtx);
 extern bool xtensa_split1_finished_p (void);
 extern void xtensa_split_DI_reg_imm (rtx *);
-extern bool xtensa_match_CLAMPS_imms_p (rtx, rtx);
 
 #ifdef TREE_CODE
 extern void init_cumulative_args (CUMULATIVE_ARGS *, int);
diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index 84268db5c9d..301448c65e2 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -2666,16 +2666,6 @@ xtensa_emit_add_imm (rtx dst, rtx src, HOST_WIDE_INT 
imm, rtx scratch,
 }
 
 
-/* Return true if the constants used in the application of smin() following
-   smax() meet the specifications of the CLAMPS machine instruction.  */
-bool
-xtensa_match_CLAMPS_imms_p (rtx cst_max, rtx cst_min)
-{
-  return IN_RANGE (exact_log2 (-INTVAL (cst_max)), 7, 22)
-&& (INTVAL (cst_max) + INTVAL (cst_min)) == -1;
-}
-
-
 /* Implement TARGET_CANNOT_FORCE_CONST_MEM.  */
 
 static bool
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 6061a86ee13..03e816b8a12 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -180,15 +180,8 @@
   "TARGET_ADDX"
 {
   operands[3] = GEN_INT (1 << INTVAL (operands[3]));
-  switch (GET_CODE (operands[4]))
-{
-case PLUS:
-  return "addx%3\t%0, %1, %2";
-case MINUS:
-  return "subx%3\t%0, %1, %2";
-default:
-  gcc_unreachable ();
-}
+  return GET_CODE (operands[4]) == PLUS
+ ? "addx%3\t%0, %1, %2" : "subx%3\t%0, %1, %2";
 }
   [(set_attr "type""arith")
(set_attr "mode""SI")
@@ -535,34 +528,23 @@
 
 ;; Signed clamp.
 
-(define_insn_and_split "*xtensa_clamps"
-  [(set (match_operand:SI 0 "register_operand" "=a")
-   (smax:SI (smin:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "const_int_operand" "i"))
-(match_operand:SI 3 "const_int_operand" "i")))]
-  "TARGET_MINMAX && TARGET_CLAMPS
-   && xtensa_match_CLAMPS_imms_p (operands[3], operands[2])"
-  "#"
-  "&& 1"
-  [(set (match_dup 0)
-   (smin:SI (smax:SI (match_dup 1)
- (match_dup 3))
-(match_dup 2)))]
-  ""
-  [(set_attr "type""arith")
-   (set_attr "mode""SI")
-   (set_attr "length"  "3")])
-
 (define_insn "*xtensa_clamps"
   [(set (match_operand:SI 0 "register_operand" "=a")
-   (smin:SI (smax:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "const

[gcc r15-959] xtensa: Prepend "(use A0_REG)" to sibling call CALL_INSN_FUNCTION_USAGE instead of emitting it as in

2024-05-31 Thread Max Filippov via Gcc-cvs
https://gcc.gnu.org/g:be9b3f4375e74b6f10dd15fc563c93f803e91db5

commit r15-959-gbe9b3f4375e74b6f10dd15fc563c93f803e91db5
Author: Takayuki 'January June' Suwa 
Date:   Fri May 31 19:24:48 2024 +0900

xtensa: Prepend "(use A0_REG)" to sibling call CALL_INSN_FUNCTION_USAGE 
instead of emitting it as insn at the end of epilogue

No functional changes.

gcc/ChangeLog:

* config/xtensa/xtensa-protos.h (xtensa_expand_call):
Add the third argument as boolean.
(xtensa_expand_epilogue): Remove the first argument.
* config/xtensa/xtensa.cc (xtensa_expand_call):
Add the third argument "sibcall_p", and modify in order to prepend
"(use A0_REG)" to CALL_INSN_FUNCTION_USAGE if the argument is true.
(xtensa_expand_epilogue): Remove the first argument "sibcall_p" and
its conditional clause.
* config/xtensa/xtensa.md (call, call_value, sibcall, 
sibcall_value):
Append a boolean value to the argument of xtensa_expand_call()
indicating whether it is sibling call or not.
(epilogue): Remove the boolean argument from 
xtensa_expand_epilogue(),
and then append emitting "(return)".
(sibcall_epilogue): Remove the boolean argument from
xtensa_expand_epilogue().

Diff:
---
 gcc/config/xtensa/xtensa-protos.h |  4 ++--
 gcc/config/xtensa/xtensa.cc   | 16 ++--
 gcc/config/xtensa/xtensa.md   | 13 +++--
 3 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/gcc/config/xtensa/xtensa-protos.h 
b/gcc/config/xtensa/xtensa-protos.h
index 834f15e0e48..77553b0453f 100644
--- a/gcc/config/xtensa/xtensa-protos.h
+++ b/gcc/config/xtensa/xtensa-protos.h
@@ -53,7 +53,7 @@ extern void xtensa_expand_atomic (enum rtx_code, rtx, rtx, 
rtx, bool);
 extern void xtensa_emit_loop_end (rtx_insn *, rtx *);
 extern char *xtensa_emit_branch (bool, rtx *);
 extern char *xtensa_emit_movcc (bool, bool, bool, rtx *);
-extern void xtensa_expand_call (int, rtx *);
+extern void xtensa_expand_call (int, rtx *, bool);
 extern char *xtensa_emit_call (int, rtx *);
 extern char *xtensa_emit_sibcall (int, rtx *);
 extern bool xtensa_tls_referenced_p (rtx);
@@ -76,7 +76,7 @@ extern void xtensa_setup_frame_addresses (void);
 extern int xtensa_debugger_regno (int);
 extern long compute_frame_size (poly_int64);
 extern void xtensa_expand_prologue (void);
-extern void xtensa_expand_epilogue (bool);
+extern void xtensa_expand_epilogue (void);
 extern void xtensa_adjust_reg_alloc_order (void);
 extern enum reg_class xtensa_regno_to_class (int regno);
 extern HOST_WIDE_INT xtensa_initial_elimination_offset (int from, int to);
diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index 301448c65e2..45dc1be3ff5 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -2239,7 +2239,7 @@ xtensa_emit_movcc (bool inverted, bool isfp, bool isbool, 
rtx *operands)
 
 
 void
-xtensa_expand_call (int callop, rtx *operands)
+xtensa_expand_call (int callop, rtx *operands, bool sibcall_p)
 {
   rtx call;
   rtx_insn *call_insn;
@@ -2281,6 +2281,14 @@ xtensa_expand_call (int callop, rtx *operands)
   CALL_INSN_FUNCTION_USAGE (call_insn) =
gen_rtx_EXPR_LIST (Pmode, clob, CALL_INSN_FUNCTION_USAGE (call_insn));
 }
+  else if (sibcall_p)
+{
+  /* Sibling call requires a return address to the caller, similar to
+"return" insn.  */
+  rtx use = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, A0_REG));
+  CALL_INSN_FUNCTION_USAGE (call_insn) =
+   gen_rtx_EXPR_LIST (Pmode, use, CALL_INSN_FUNCTION_USAGE (call_insn));
+}
 }
 
 
@@ -3671,7 +3679,7 @@ xtensa_expand_prologue (void)
 }
 
 void
-xtensa_expand_epilogue (bool sibcall_p)
+xtensa_expand_epilogue (void)
 {
   if (!TARGET_WINDOWED_ABI)
 {
@@ -3736,10 +3744,6 @@ xtensa_expand_epilogue (bool sibcall_p)
  stack_pointer_rtx,
  EH_RETURN_STACKADJ_RTX));
 }
-  if (sibcall_p)
-emit_use (gen_rtx_REG (SImode, A0_REG));
-  else
-emit_jump_insn (gen_return ());
 }
 
 void
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 03e816b8a12..ef826b63e44 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -2553,7 +2553,7 @@
 (match_operand 1 "" ""))]
   ""
 {
-  xtensa_expand_call (0, operands);
+  xtensa_expand_call (0, operands, false);
   DONE;
 })
 
@@ -2574,7 +2574,7 @@
  (match_operand 2 "" "")))]
   ""
 {
-  xtensa_expand_call (1, operands);
+  xtensa_expand_call (1, operands, false);
   DONE;
 })
 
@@ -2595,7 +2595,7 @@
 (match_operand 1 "" ""))]
   "!TARGET_WINDOWED_ABI"
 {
-  xtensa_expand_call (0, operands);
+  xtensa_expand_call (0, operands, true);
   DONE;
 })
 
@@ -2616,7 +2616,7 @@
  (match_operand 2 "" "")))]
   "!TARGET_WINDOWED_ABI"
 {
-  xtensa_expand_call (1, o

[gcc r15-1433] xtensa: constantsynth: Reforge to fix some non-fatal issues

2024-06-19 Thread Max Filippov via Gcc-cvs
https://gcc.gnu.org/g:23141088e8fb50bf916ac0b2e364b1eef9f3569d

commit r15-1433-g23141088e8fb50bf916ac0b2e364b1eef9f3569d
Author: Takayuki 'January June' Suwa 
Date:   Wed Jun 19 11:55:57 2024 +0900

xtensa: constantsynth: Reforge to fix some non-fatal issues

The previous constant synthesis logic had some issues that were non-fatal
but worth considering:

- It didn't work with DFmode literals, because those were cast to SImode
   rather SFmode when splitting into two natural-width words by
   split_double().

- It didn't work with large literals when TARGET_AUTO_LITPOOLS was enabled,
   because those were relaxed MOVI immediates rather references to literal
   pool entries,

- It didn't take into account that when literals with the same RTL
   representation are pooled multiple times within a function, those entries
   are shared (especially important when optimizing for size).

This patch addresses the above issues by making appropriate tweaks to the
constant synthesis logic.

gcc/ChangeLog:

* config/xtensa/xtensa-protos.h (xtensa_constantsynth):
Change the second argument from HOST_WIDE_INT to rtx.
* config/xtensa/xtensa.cc (#include):
Add "context.h" and "pass_manager.h".
(machine_function): Add a new hash_map field "litpool_usage".
(xtensa_constantsynth): Make "src" (the second operand) accept
RTX literal instead of its value, and treat both bare and pooled
SI/SFmode literals equally by bit-exact canonicalization into
CONST_INT RTX internally.  And then, make avoid synthesis if
such multiple identical canonicalized literals are found in same
function when optimizing for size.  Finally, for literals where
synthesis is not possible or has been avoided, re-emit "move"
RTXes with canonicalized ones to increase the chances of sharing
literal pool entries.
* config/xtensa/xtensa.md (split patterns for constant synthesis):
Change to simply invoke xtensa_constantsynth() as mentioned above,
and add new patterns for when TARGET_AUTO_LITPOOLS is enabled.

Diff:
---
 gcc/config/xtensa/xtensa-protos.h |  2 +-
 gcc/config/xtensa/xtensa.cc   | 75 +++
 gcc/config/xtensa/xtensa.md   | 56 +
 3 files changed, 103 insertions(+), 30 deletions(-)

diff --git a/gcc/config/xtensa/xtensa-protos.h 
b/gcc/config/xtensa/xtensa-protos.h
index 77553b0453f1..8f645e87de96 100644
--- a/gcc/config/xtensa/xtensa-protos.h
+++ b/gcc/config/xtensa/xtensa-protos.h
@@ -44,7 +44,7 @@ extern int xtensa_expand_scc (rtx *, machine_mode);
 extern int xtensa_expand_block_move (rtx *);
 extern int xtensa_expand_block_set (rtx *);
 extern void xtensa_split_operand_pair (rtx *, machine_mode);
-extern int xtensa_constantsynth (rtx, HOST_WIDE_INT);
+extern int xtensa_constantsynth (rtx, rtx);
 extern int xtensa_emit_move_sequence (rtx *, machine_mode);
 extern rtx xtensa_copy_incoming_a7 (rtx);
 extern void xtensa_expand_nonlocal_goto (rtx *);
diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index 45dc1be3ff52..bc127997ac6c 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -58,6 +58,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "insn-attr.h"
 #include "tree-pass.h"
 #include "print-rtl.h"
+#include "context.h"
+#include "pass_manager.h"
 #include 
 
 /* This file should be included last.  */
@@ -107,6 +109,7 @@ struct GTY(()) machine_function
   bool inhibit_logues_a1_adjusts;
   rtx last_logues_a9_content;
   HARD_REG_SET eliminated_callee_saved;
+  hash_map *litpool_usage;
 };
 
 static void xtensa_option_override (void);
@@ -1104,7 +1107,7 @@ xtensa_split_operand_pair (rtx operands[4], machine_mode 
mode)
 }
 
 
-/* Try to emit insns to load srcval (that cannot fit into signed 12-bit)
+/* Try to emit insns to load src (either naked or pooled SI/SF constant)
into dst with synthesizing a such constant value from a sequence of
load-immediate / arithmetic ones, instead of a L32R instruction
(plus a constant in litpool).  */
@@ -1190,11 +1193,67 @@ xtensa_constantsynth_rtx_ADDSUBX (rtx reg, 
HOST_WIDE_INT imm)
 }
 
 int
-xtensa_constantsynth (rtx dst, HOST_WIDE_INT srcval)
+xtensa_constantsynth (rtx dst, rtx src)
 {
+  HOST_WIDE_INT srcval;
+  static opt_pass *pass_rtl_split2;
+  int *pv;
+
+  /* Derefer if src is litpool entry, and get integer constant value.  */
+  src = avoid_constant_pool_reference (src);
+  if (CONST_INT_P (src))
+srcval = INTVAL (src);
+  else if (CONST_DOUBLE_P (src) && GET_MODE (src) == SFmode)
+{
+  long l;
+
+  REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (src), l);
+  srcval = (int32_t)l, src = GEN_INT (srcval);
+}
+  else
+return 0;
+
+  /* Force dst

[gcc r15-1453] xtensa: Eliminate double MEMW insertions for volatile memory

2024-06-19 Thread Max Filippov via Gcc-cvs
https://gcc.gnu.org/g:0982552bc4eeffb5520deba10dedecfb2390a8de

commit r15-1453-g0982552bc4eeffb5520deba10dedecfb2390a8de
Author: Takayuki 'January June' Suwa 
Date:   Wed Jun 19 13:59:54 2024 +0900

xtensa: Eliminate double MEMW insertions for volatile memory

This patch makes avoid inserting a MEMW instruction before a load/store
nstruction with volatile memory reference if there is already a MEMW
immediately before it.

gcc/ChangeLog:

* config/xtensa/xtensa.cc (print_operand):
When outputting MEMW before the instruction, check if the previous
instruction is already that.

Diff:
---
 gcc/config/xtensa/xtensa.cc | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index bc127997ac6c..e2549de5df05 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -3078,7 +3078,17 @@ print_operand (FILE *file, rtx x, int letter)
  /* For a volatile memory reference, emit a MEMW before the
 load or store.  */
  if (MEM_VOLATILE_P (x) && TARGET_SERIALIZE_VOLATILE)
-   fprintf (file, "memw\n\t");
+   {
+ rtx_insn *prev_insn
+   = prev_nonnote_nondebug_insn (current_output_insn);
+ rtx pat, src;
+
+ if (! (prev_insn && NONJUMP_INSN_P (prev_insn)
+&& GET_CODE (pat = PATTERN (prev_insn)) == SET
+&& GET_CODE (src = SET_SRC (pat)) == UNSPEC
+&& XINT (src, 1) == UNSPEC_MEMW))
+   fprintf (file, "memw\n\t");
+   }
}
   else
output_operand_lossage ("invalid %%v value");


[gcc r15-4706] xtensa: Define TARGET_DIFFERENT_ADDR_DISPLACEMENT_P target hook

2024-10-27 Thread Max Filippov via Gcc-cvs
https://gcc.gnu.org/g:211459e12147e9ed42c0a0947b1b95b551e03ef3

commit r15-4706-g211459e12147e9ed42c0a0947b1b95b551e03ef3
Author: Takayuki 'January June' Suwa 
Date:   Wed Oct 23 11:31:15 2024 +0900

xtensa: Define TARGET_DIFFERENT_ADDR_DISPLACEMENT_P target hook

In commit bc5a9dab55d13f888a3cdd150c8cf5c2244f35e0 ("gcc: xtensa: reorder
movsi_internal patterns for better code generation during LRA"),  the
instruction order in "movsi_internal" MD definition was changed to make LRA
use load/store instructions with larger memory address displacements, but as
a side effect, it now uses the larger displacements (ie., the larger
instructions) even outside of reload operations.

The underlying problem is that LRA assumes by default that there is only one
maximal legitimate displacement for the same address structure, meaning that
it has no choice but to use the first load/store instruction it finds.

To fix this, define TARGET_DIFFERENT_ADDR_DISPLACEMENT_P hook to always
return true.

gcc/ChangeLog:

* config/xtensa/xtensa.cc (TARGET_DIFFERENT_ADDR_DISPLACEMENT_P):
Add new target hook to always return true.
* config/xtensa/xtensa.md (movsi_internal):
Revert the previous changes.

Diff:
---
 gcc/config/xtensa/xtensa.cc |  3 +++
 gcc/config/xtensa/xtensa.md | 12 ++--
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index 43b1332d42b3..d2793822641c 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -363,6 +363,9 @@ static rtx xtensa_delegitimize_address (rtx);
 #undef TARGET_MAX_ANCHOR_OFFSET
 #define TARGET_MAX_ANCHOR_OFFSET 1020
 
+#undef TARGET_DIFFERENT_ADDR_DISPLACEMENT_P
+#define TARGET_DIFFERENT_ADDR_DISPLACEMENT_P hook_bool_void_true
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index f19e1fd16b54..2c08c7d6bf10 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -1279,15 +1279,13 @@
 })
 
 (define_insn "movsi_internal"
-  [(set (match_operand:SI 0 "nonimmed_operand" 
"=D,D,D,a,U,D,R,R,a,q,a,a,W,a,*a,*A")
-   (match_operand:SI 1 "move_operand" 
"M,D,d,U,r,R,D,d,r,r,I,Y,i,T,*A,*r"))]
+  [(set (match_operand:SI 0 "nonimmed_operand" 
"=D,D,D,D,R,R,a,q,a,a,W,a,a,U,*a,*A")
+   (match_operand:SI 1 "move_operand" 
"M,D,d,R,D,d,r,r,I,Y,i,T,U,r,*A,*r"))]
   "xtensa_valid_move (SImode, operands)"
   "@
movi.n\t%0, %x1
mov.n\t%0, %1
mov.n\t%0, %1
-   %v1l32i\t%0, %1
-   %v0s32i\t%1, %0
%v1l32i.n\t%0, %1
%v0s32i.n\t%1, %0
%v0s32i.n\t%1, %0
@@ -1297,11 +1295,13 @@
movi\t%0, %1
const16\t%0, %t1\;const16\t%0, %b1
%v1l32r\t%0, %1
+   %v1l32i\t%0, %1
+   %v0s32i\t%1, %0
rsr\t%0, ACCLO
wsr\t%1, ACCLO"
-  [(set_attr "type"
"move,move,move,load,store,load,store,store,move,move,move,move,move,load,rsr,wsr")
+  [(set_attr "type"
"move,move,move,load,store,store,move,move,move,move,move,load,load,store,rsr,wsr")
(set_attr "mode""SI")
-   (set_attr "length"  "2,2,2,3,3,2,2,2,3,3,3,3,6,3,3,3")])
+   (set_attr "length"  "2,2,2,2,2,2,3,3,3,3,6,3,3,3,3,3")])
 
 (define_split
   [(set (match_operand:SHI 0 "register_operand")


[gcc r15-5074] xtensa: Fix the issue in "*extzvsi-1bit_addsubx"

2024-11-10 Thread Max Filippov via Gcc-cvs
https://gcc.gnu.org/g:b433140a6cb40acedb2e6cb43c4e5a388e33f805

commit r15-5074-gb433140a6cb40acedb2e6cb43c4e5a388e33f805
Author: Takayuki 'January June' Suwa 
Date:   Sun Nov 10 15:39:22 2024 +0900

xtensa: Fix the issue in "*extzvsi-1bit_addsubx"

The second source register of insn "*extzvsi-1bit_addsubx" cannot be the
same as the destination register, because that register will be overwritten
with an intermediate value after insn splitting.

 /* example #1 */
 int test1(int b, int a) {
   return ((a & 1024) ? 4 : 0) + b;
 }

 ;; result #1 (incorrect)
 test1:
extui   a2, a3, 10, 1   ;; overwrites A2 before used
addx4   a2, a2, a2
ret.n

This patch fixes that.

 ;; result #1 (correct)
 test1:
extui   a3, a3, 10, 1   ;; uses A3 and then overwrites
addx4   a2, a3, a2
ret.n

However, it should be noted that the first source register can be the same
as the destination without any problems.

 /* example #2 */
 int test2(int a, int b) {
   return ((a & 1024) ? 4 : 0) + b;
 }

 ;; result (correct)
 test2:
extui   a2, a2, 10, 1   ;; uses A2 and then overwrites
addx4   a2, a2, a3
ret.n

gcc/ChangeLog:

* config/xtensa/xtensa.md (*extzvsi-1bit_addsubx):
Add '&' to the destination register constraint to indicate that
it is 'earlyclobber', append '0' to the first source register
constraint to indicate that it can be the same as the destination
register, and change the split condition from 1 to reload_completed
so that the insn will be split only after RA in order to obtain
allocated registers that satisfy the above constraints.

Diff:
---
 gcc/config/xtensa/xtensa.md | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 2c08c7d6bf10..cecd319685c0 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -1109,17 +1109,17 @@
  (const_int 6)))])
 
 (define_insn_and_split "*extzvsi-1bit_addsubx"
-  [(set (match_operand:SI 0 "register_operand" "=a")
+  [(set (match_operand:SI 0 "register_operand" "=&a")
(match_operator:SI 5 "addsub_operator"
[(and:SI (match_operator:SI 6 "logical_shift_operator"
-   [(match_operand:SI 1 "register_operand" "r")
+   [(match_operand:SI 1 "register_operand" "r0")
 (match_operand:SI 3 "const_int_operand" "i")])
 (match_operand:SI 4 "const_int_operand" "i"))
 (match_operand:SI 2 "register_operand" "r")]))]
   "TARGET_ADDX
&& IN_RANGE (exact_log2 (INTVAL (operands[4])), 1, 3)"
   "#"
-  "&& 1"
+  "&& reload_completed"
   [(set (match_dup 0)
(zero_extract:SI (match_dup 1)
 (const_int 1)


[gcc r16-529] xtensa: Fix up unwanted spills of SFmode hard registers holding function arguments/returns

2025-05-11 Thread Max Filippov via Gcc-cvs
https://gcc.gnu.org/g:6d73d75a7c04caf3457297400372f87765b9a653

commit r16-529-g6d73d75a7c04caf3457297400372f87765b9a653
Author: Takayuki 'January June' Suwa 
Date:   Sun May 11 04:51:11 2025 +0900

xtensa: Fix up unwanted spills of SFmode hard registers holding function 
arguments/returns

Until now (presumably after transition to LRA), hard registers storing
function arguments or return values ​​were spilling undesirably when
TARGET_HARD_FLOAT is enabled.

 /* example */
 float test0(float a, float b) {
   return a + b;
 }
 extern float foo(void);
 float test1(void) {
   return foo() * 3.14f;
 }

 ;; before
 test0:
entry   sp, 48
wfr f0, a2
wfr f1, a3
add.s   f0, f0, f1
s32i.n  a2, sp, 0   ;; unwanted spilling-out
s32i.n  a3, sp, 4   ;;
rfr a2, f0
retw.n
.literal .LC1, 1078523331
 test1:
entry   sp, 48
call8   foo
l32ra8, .LC1
wfr f0, a10
wfr f1, a8
mul.s   f0, f0, f1
s32i.n  a10, sp, 0  ;; unwanted spilling-out
rfr a2, f0
retw.n

Ultimately, that is because the costs of moving between integer and
floating-point hard registers are undefined and the default (large value)
is used.  This patch fixes this.

 ;; after
 test0:
entry   sp, 32
wfr f1, a2
wfr f0, a3
add.s   f0, f1, f0
rfr a2, f0
retw.n
.literal .LC1, 1078523331
 test1:
entry   sp, 32
call8   foo
l32ra8, .LC1
wfr f1, a10
wfr f0, a8
mul.s   f0, f1, f0
rfr a2, f0
retw.n

gcc/ChangeLog:

* config/xtensa/xtensa.cc (xtensa_register_move_cost):
Add appropriate move costs between AR_REGS and FP_REGS.

Diff:
---
 gcc/config/xtensa/xtensa.cc | 28 +++-
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index 53db06ec6f2c..621fb0aeb461 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -4430,17 +4430,27 @@ static int
 xtensa_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
   reg_class_t from, reg_class_t to)
 {
-  if (from == to && from != BR_REGS && to != BR_REGS)
+  /* If both are equal (except for BR_REGS) or belong to AR_REGS,
+ the cost is 2 (the default value).  */
+  if ((from == to && from != BR_REGS && to != BR_REGS)
+  || (reg_class_subset_p (from, AR_REGS)
+ && reg_class_subset_p (to, AR_REGS)))
 return 2;
-  else if (reg_class_subset_p (from, AR_REGS)
-  && reg_class_subset_p (to, AR_REGS))
-return 2;
-  else if (reg_class_subset_p (from, AR_REGS) && to == ACC_REG)
-return 3;
-  else if (from == ACC_REG && reg_class_subset_p (to, AR_REGS))
+
+  /* The cost between AR_REGS and FR_REGS must be <= 8 (2x the default
+ MEMORY_MOVE_COST) to avoid unwanted spills, and > 4 (2x the above
+ case) to avoid excessive register-to-register moves.  */
+  if ((reg_class_subset_p (from, AR_REGS) && to == FP_REGS)
+  || (from == FP_REGS && reg_class_subset_p (to, AR_REGS)))
+return 5;
+
+  if ((reg_class_subset_p (from, AR_REGS) && to == ACC_REG)
+  || (from == ACC_REG && reg_class_subset_p (to, AR_REGS)))
 return 3;
-  else
-return 10;
+
+  /* Otherwise, spills to stack (because greater than 2x the default
+ MEMORY_MOVE_COST).  */
+  return 10;
 }
 
 /* Compute a (partial) cost for rtx X.  Return true if the complete


[gcc r16-530] testsuite: xtensa: add support for effective_target_sync_*

2025-05-11 Thread Max Filippov via Gcc-cvs
https://gcc.gnu.org/g:aa0d25683bb5c7f2256d9e897fe471f0de84ea9b

commit r16-530-gaa0d25683bb5c7f2256d9e897fe471f0de84ea9b
Author: Max Filippov 
Date:   Sun Apr 27 18:05:20 2025 -0700

testsuite: xtensa: add support for effective_target_sync_*

Add new function check_effective_target_xtensa_atomic and use it in the
check_effective_target_sync_int_long and
check_effective_target_sync_char_short.

gcc/testsuite/ChangeLog:

* lib/target-supports.exp
(check_effective_target_xtensa_atomic): New function.
(check_effective_target_sync_int_long)
(check_effective_target_sync_char_short): Add test for xtensa.

Diff:
---
 gcc/testsuite/lib/target-supports.exp | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/lib/target-supports.exp 
b/gcc/testsuite/lib/target-supports.exp
index 287e51bbfc66..24d0b3d08e34 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -10145,6 +10145,7 @@ proc check_effective_target_sync_int_long { } {
 || ([istarget arc*-*-*] && [check_effective_target_arc_atomic])
 || [check_effective_target_mips_llsc]
 || [istarget nvptx*-*-*]
+|| ([istarget xtensa*-*-*] && 
[check_effective_target_xtensa_atomic])
 }}]
 }
 
@@ -10182,7 +10183,9 @@ proc check_effective_target_sync_char_short { } {
 || ([istarget riscv*-*-*]
 && ([check_effective_target_riscv_zalrsc]
 || [check_effective_target_riscv_zabha]))
-|| [check_effective_target_mips_llsc] }}]
+|| [check_effective_target_mips_llsc]
+|| ([istarget xtensa*-*-*] && 
[check_effective_target_xtensa_atomic])
+}}]
 }
 
 # Return 1 if thread_fence does not rely on __sync_synchronize
@@ -14407,3 +14410,12 @@ proc 
check_effective_target_speculation_barrier_defined { } {
}
}]
 }
+
+# Return 1 if this is a compiler supporting Xtensa atomic operations
+proc check_effective_target_xtensa_atomic { } {
+return [check_no_compiler_messages xtensa_atomic assembly {
+   #if __XCHAL_HAVE_S32C1I != 1 && __XCHAL_HAVE_EXCLUSIVE != 1
+   #error FOO
+   #endif
+}]
+}


[gcc r16-1031] xtensa: Implement TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS

2025-05-31 Thread Max Filippov via Gcc-cvs
https://gcc.gnu.org/g:9050005673b68f5267a4c8262363b547555337a0

commit r16-1031-g9050005673b68f5267a4c8262363b547555337a0
Author: Takayuki 'January June' Suwa 
Date:   Tue May 27 15:57:26 2025 +0900

xtensa: Implement TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS

Implement TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS in order to avoid using
ALL_REGS rclass as is done on other targets, instead of overestimating
between integer and FP register move costs.

gcc/ChangeLog:

* config/xtensa/xtensa.cc
(xtensa_ira_change_pseudo_allocno_class):
New prototype and function.
(TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS): Define macro.
(xtensa_register_move_cost):
Change between integer and FP register move cost to a value
based on actual behavior, i.e. 2, the default and the same as
the move cost between integer registers.

Diff:
---
 gcc/config/xtensa/xtensa.cc | 27 +++
 1 file changed, 23 insertions(+), 4 deletions(-)

diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index e03dee3f4c4a..d1856f76c053 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -197,6 +197,8 @@ static void xtensa_output_mi_thunk (FILE *file, tree thunk 
ATTRIBUTE_UNUSED,
tree function);
 
 static rtx xtensa_delegitimize_address (rtx);
+static reg_class_t xtensa_ira_change_pseudo_allocno_class (int, reg_class_t,
+  reg_class_t);
 
 
 
@@ -366,6 +368,9 @@ static rtx xtensa_delegitimize_address (rtx);
 #undef TARGET_DIFFERENT_ADDR_DISPLACEMENT_P
 #define TARGET_DIFFERENT_ADDR_DISPLACEMENT_P hook_bool_void_true
 
+#undef TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS
+#define TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS 
xtensa_ira_change_pseudo_allocno_class
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 
@@ -4432,12 +4437,10 @@ xtensa_register_move_cost (machine_mode mode 
ATTRIBUTE_UNUSED,
  && reg_class_subset_p (to, AR_REGS)))
 return 2;
 
-  /* The cost between AR_REGS and FR_REGS must be <= 8 (2x the default
- MEMORY_MOVE_COST) to avoid unwanted spills, and > 4 (2x the above
- case) to avoid excessive register-to-register moves.  */
+  /* The cost between AR_REGS and FR_REGS is 2 (the default value).  */
   if ((reg_class_subset_p (from, AR_REGS) && to == FP_REGS)
   || (from == FP_REGS && reg_class_subset_p (to, AR_REGS)))
-return 5;
+return 2;
 
   if ((reg_class_subset_p (from, AR_REGS) && to == ACC_REG)
   || (from == ACC_REG && reg_class_subset_p (to, AR_REGS)))
@@ -5433,4 +5436,20 @@ xtensa_delegitimize_address (rtx op)
   return op;
 }
 
+/* Implement TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS, in order to tell
+   the register allocator to avoid using ALL_REGS rclass.  */
+
+static reg_class_t
+xtensa_ira_change_pseudo_allocno_class (int regno, reg_class_t allocno_class,
+   reg_class_t best_class)
+{
+  if (allocno_class != ALL_REGS)
+return allocno_class;
+
+  if (best_class != ALL_REGS)
+return best_class;
+
+  return FLOAT_MODE_P (PSEUDO_REGNO_MODE (regno)) ? FP_REGS : AR_REGS;
+}
+
 #include "gt-xtensa.h"


[gcc r16-1032] xtensa: Remove an unnecessary constraint modifier from movsf_internal insn pattern

2025-05-31 Thread Max Filippov via Gcc-cvs
https://gcc.gnu.org/g:2e5130f6870bdb016f58f42f2ff99a2226e93af6

commit r16-1032-g2e5130f6870bdb016f58f42f2ff99a2226e93af6
Author: Takayuki 'January June' Suwa 
Date:   Tue May 27 15:58:35 2025 +0900

xtensa: Remove an unnecessary constraint modifier from movsf_internal insn 
pattern

In this case, there is no need to consider reloading when memory is the
destination.  On the other hand, when memory is the source, reloading
read from constant pool becomes double indirection and should obviously
be avoided.

gcc/ChangeLog:

* config/xtensa/xtensa.md (movsf_internal):
Remove destination side constraint modifier '^' in the third
alternative.

Diff:
---
 gcc/config/xtensa/xtensa.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 88f011cd0ef6..c7ac456ae5f3 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -1453,7 +1453,7 @@
 })
 
 (define_insn "movsf_internal"
-  [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,^U,D,a,D,R,a,f,a,a,W,a,U")
+  [(set (match_operand:SF 0 "nonimmed_operand" "=f,f,U,D,a,D,R,a,f,a,a,W,a,U")
(match_operand:SF 1 "move_operand" "f,^U,f,d,T,R,d,r,r,f,Y,iF,U,r"))]
   "((register_operand (operands[0], SFmode)
  || register_operand (operands[1], SFmode))


[gcc r16-1033] xtensa: Remove include of reload.h

2025-05-31 Thread Max Filippov via Gcc-cvs
https://gcc.gnu.org/g:2e1f0142708e29bf0f19ef76c9dded913081a0ef

commit r16-1033-g2e1f0142708e29bf0f19ef76c9dded913081a0ef
Author: Takayuki 'January June' Suwa 
Date:   Tue May 27 15:59:21 2025 +0900

xtensa: Remove include of reload.h

As one of the last steps in removing old reload.

gcc/ChangeLog:

* config/xtensa/xtensa.cc: Remove include of reload.h.

Diff:
---
 gcc/config/xtensa/xtensa.cc | 1 -
 1 file changed, 1 deletion(-)

diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index d1856f76c053..a9d67a56cd6a 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -48,7 +48,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "alias.h"
 #include "explow.h"
 #include "expr.h"
-#include "reload.h"
 #include "langhooks.h"
 #include "gimplify.h"
 #include "builtins.h"


[gcc r16-1280] xtensa: Implement l(ceil|floor)sfsi2 insn patterns and their scaled variants

2025-06-08 Thread Max Filippov via Gcc-cvs
https://gcc.gnu.org/g:5f3b5b0616fe883e86e95d9476371cf87059ca7f

commit r16-1280-g5f3b5b0616fe883e86e95d9476371cf87059ca7f
Author: Takayuki 'January June' Suwa 
Date:   Sun Jun 8 14:05:05 2025 +0900

xtensa: Implement l(ceil|floor)sfsi2 insn patterns and their scaled variants

By using the previously unused CEIL|FLOOR.S floating-point coprocessor
instructions.  In addition, two instruction operand format codes are added
to output the scale value as assembler source.

 /* example */
 int test0(float a) {
   return __builtin_lceilf(a);
 }
 int test1(float a) {
   return __builtin_lceilf(a * 2);
 }
 int test2(float a) {
   return __builtin_lfloorf(a);
 }
 int test3(float a) {
   return __builtin_lfloorf(a * 32768);
 }

 ;; result
 test0:
entry   sp, 32
wfr f0, a2
ceil.s  a2, f0, 0
retw.n
 test1:
entry   sp, 32
wfr f0, a2
ceil.s  a2, f0, 1
retw.n
 test2:
entry   sp, 32
wfr f0, a2
floor.s a2, f0, 0
retw.n
 test3:
entry   sp, 32
wfr f0, a2
floor.s a2, f0, 15
retw.n

However, because the rounding-half behavior (e.g., the rule that determines
whether 1.5 should be rounded to 1 or 2) of the two is inconsistent;
the lroundsfsi2 pattern is explicitly specified that rounding to nearest
integer and away from zero, but the other hand, the ROUND.S instruction is
not specified that by the ISA and is implementation-dependent.

Therefore lroundsfsi2 cannot be implemented by ROUND.S.

gcc/ChangeLog:

* config/xtensa/xtensa.cc (printx, print_operand):
Add two instruction operand format codes 'U' and 'V',
whose represent scale factors of 0 to 15th positive/negative
power of two.
* config/xtensa/xtensa.md (c_enum "unspec"):
Add UNSPEC_CEIL and UNSPEC_FLOOR.
(int_iterator ANY_ROUND, int_attr m_round):
New integer iterator and its attribute.
(fix_truncsfsi2, *fix_truncsfsi2_2x,
*fix_truncsfsi2_scaled, floatsisf2,
*floatsisf2_scaled):
Use output templates with the operand formats added above,
instead of individual output statements.
(lsfsi2, *lsfsi2_2x, *lsfsi2_scaled):
New insn patterns.

Diff:
---
 gcc/config/xtensa/xtensa.cc | 16 +++
 gcc/config/xtensa/xtensa.md | 50 ++---
 2 files changed, 54 insertions(+), 12 deletions(-)

diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index a9d67a56cd6a..90b5ff93042f 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -3047,6 +3047,8 @@ xtensa_modes_tieable_p (machine_mode mode1, machine_mode 
mode2)
'K'  CONST_INT, print number of bits in mask for EXTUI
'R'  CONST_INT, print (X & 0x1f)
'L'  CONST_INT, print ((32 - X) & 0x1f)
+   'U', CONST_DOUBLE:SF, print (REAL_EXP (rval) - 1)
+   'V', CONST_DOUBLE:SF, print (1 - REAL_EXP (rval))
'D'  REG, print second register of double-word register operand
'N'  MEM, print address of next word following a memory operand
'v'  MEM, if memory reference is volatile, output a MEMW before it
@@ -3143,6 +3145,20 @@ print_operand (FILE *file, rtx x, int letter)
output_operand_lossage ("invalid %%R value");
   break;
 
+case 'U':
+  if (CONST_DOUBLE_P (x) && GET_MODE (x) == SFmode)
+   fprintf (file, "%d", REAL_EXP (CONST_DOUBLE_REAL_VALUE (x)) - 1);
+  else
+   output_operand_lossage ("invalid %%U value");
+  break;
+
+case 'V':
+  if (CONST_DOUBLE_P (x) && GET_MODE (x) == SFmode)
+   fprintf (file, "%d", 1 - REAL_EXP (CONST_DOUBLE_REAL_VALUE (x)));
+  else
+   output_operand_lossage ("invalid %%V value");
+  break;
+
 case 'x':
   if (CONST_INT_P (x))
printx (file, INTVAL (x));
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index c7ac456ae5f3..56e222dddfd2 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -41,6 +41,8 @@
   UNSPEC_LSETUP_START
   UNSPEC_LSETUP_END
   UNSPEC_FRAME_BLOCKAGE
+  UNSPEC_CEIL
+  UNSPEC_FLOOR
 ])
 
 (define_c_enum "unspecv" [
@@ -103,6 +105,11 @@
 (define_code_attr m_float [(float "float") (unsigned_float "ufloat")])
 (define_code_attr s_float [(float "") (unsigned_float "uns")])
 
+;; This iterator and attribute allow FP-to-integer rounding of two types
+;; to be generated from one template.
+(define_int_iterator ANY_ROUND [UNSPEC_CEIL UNSPEC_FLOOR])
+(define_int_attr m_round [(UNSPEC_CEIL "ceil") (UNSPEC_FLOOR "floor")])
+
 
 ;; Attributes.
 
@@ -1168,12 +1175,7 @@
(any_fix:SI (mult:S