From 6924c00c8710ec95834e21f8d68b10f2d09a8680 Mon Sep 17 00:00:00 2001 From: Takayuki 'January June' Suwa Date: Fri, 10 Oct 2025 06:33:36 +0900 Subject: [PATCH] xtensa: Make all memory constraints special In a previous commit (fb7b82964f54192d0723a45c0657d2eb7c5ac97c), we fixed an issue where loads from literal pool to a hardware floating-point register were double- indirected; that is, the address of the literal pool entry was temporarily loaded from another entry into the address (GP) register, and then loaded from that address into the FP register. However, we discovered that the same issue could occur in rare cases when loading FP constants into address registers. Similarly, this problem can be avoided by prefixing the corresponding alternative constraint with '^' to increase the cost of Reload/LRA, but as a more fundamental and comprehensive solution, this patch defines all memory constraint definitions using define_special_memory_constraint, so that reloads cannot occur for addresses (based on a good suggestion from Jeff Law). gcc/ChangeLog: * config/xtensa/constraints.md (R, U): Change define_memory_constraint to define_special_memory_constraint. * config/xtensa/xtensa.md (movsi_internal, movhi_internal, movqi_internal): Rearrange their alternatives in the order of constant assignment, register- register move, load, store and special. And also consolidate overlapping alternatives. (movsf_internal): Rearrange the alternatives as above, and remove the '^' alternative character which is no longer needed. --- gcc/config/xtensa/constraints.md | 4 ++-- gcc/config/xtensa/xtensa.md | 36 +++++++++++++++----------------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/gcc/config/xtensa/constraints.md b/gcc/config/xtensa/constraints.md index 08fdab1c2e7..7322107eaa3 100644 --- a/gcc/config/xtensa/constraints.md +++ b/gcc/config/xtensa/constraints.md @@ -126,7 +126,7 @@ ;; Memory constraints. -(define_memory_constraint "R" +(define_special_memory_constraint "R" "Memory that can be accessed with a 4-bit unsigned offset from a register." (and (match_code "mem") (match_test "smalloffset_mem_p (op)"))) @@ -136,7 +136,7 @@ (and (match_code "mem") (match_test "!TARGET_CONST16 && constantpool_mem_p (op)"))) -(define_memory_constraint "U" +(define_special_memory_constraint "U" "Memory that is not in a literal pool." (and (match_code "mem") (match_test "! constantpool_mem_p (op)"))) diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md index 950c33f859f..aa64808ea62 100644 --- a/gcc/config/xtensa/xtensa.md +++ b/gcc/config/xtensa/xtensa.md @@ -1263,18 +1263,16 @@ "xtensa_valid_move (SImode, operands)" {@ [cons: =0, 1; attrs: type, length] [ D, M; move , 2] movi.n\t%0, %x1 - [ D, D; move , 2] mov.n\t%0, %1 - [ D, d; move , 2] ^ - [ D, R; load , 2] %v1l32i.n\t%0, %1 - [ R, D; store, 2] %v0s32i.n\t%1, %0 - [ R, d; store, 2] ^ - [ a, r; move , 3] mov\t%0, %1 - [ q, r; move , 3] movsp\t%0, %1 [ a, I; move , 3] movi\t%0, %x1 - [ a, Y; load , 3] movi\t%0, %1 [ W, i; move , 6] const16\t%0, %t1\;const16\t%0, %b1 + [ a, Y; load , 3] movi\t%0, %1 [ a, T; load , 3] %v1l32r\t%0, %1 + [ q, r; move , 3] movsp\t%0, %1 + [ D, Dd; move , 2] mov.n\t%0, %1 + [ a, r; move , 3] mov\t%0, %1 + [ D, R; load , 2] %v1l32i.n\t%0, %1 [ a, U; load , 3] %v1l32i\t%0, %1 + [ R, Dd; store, 2] %v0s32i.n\t%1, %0 [ U, r; store, 3] %v0s32i\t%1, %0 [*a, *A; rsr , 3] rsr\t%0, ACCLO [*A, *r; wsr , 3] wsr\t%1, ACCLO @@ -1310,11 +1308,11 @@ "xtensa_valid_move (HImode, operands)" {@ [cons: =0, 1; attrs: type, length] [ D, M; move , 2] movi.n\t%0, %x1 - [ D, d; move , 2] mov.n\t%0, %1 - [ a, r; move , 3] mov\t%0, %1 [ a, I; move , 3] movi\t%0, %x1 [ a, Y; load , 3] movi\t%0, %1 [ a, T; load , 3] %v1l32r\t%0, %1 + [ D, d; move , 2] mov.n\t%0, %1 + [ a, r; move , 3] mov\t%0, %1 [ a, U; load , 3] %v1l16ui\t%0, %1 [ U, r; store, 3] %v0s16i\t%1, %0 [*a, *A; rsr , 3] rsr\t%0, ACCLO @@ -1339,9 +1337,9 @@ "xtensa_valid_move (QImode, operands)" {@ [cons: =0, 1; attrs: type, length] [ D, M; move , 2] movi.n\t%0, %x1 + [ a, I; move , 3] movi\t%0, %x1 [ D, d; move , 2] mov.n\t%0, %1 [ a, r; move , 3] mov\t%0, %1 - [ a, I; move , 3] movi\t%0, %x1 [ a, U; load , 3] %v1l8ui\t%0, %1 [ U, r; store, 3] %v0s8i\t%1, %0 [*a, *A; rsr , 3] rsr\t%0, ACCLO @@ -1412,20 +1410,20 @@ && !(FP_REG_P (xt_true_regnum (operands[0])) && (constantpool_mem_p (operands[1]) || CONSTANT_P (operands[1]))))" {@ [cons: =0, 1; attrs: type, length] - [f, f; farith, 3] mov.s\t%0, %1 - [f, ^U; fload , 3] %v1lsi\t%0, %1 - [U, f; fstore, 3] %v0ssi\t%1, %0 - [D, d; move , 2] mov.n\t%0, %1 + [W, iF; move , 6] const16\t%0, %t1\;const16\t%0, %b1 + [a, Y; load , 3] movi\t%0, %y1 [a, T; load , 3] %v1l32r\t%0, %1 - [D, R; load , 2] %v1l32i.n\t%0, %1 - [R, d; store , 2] %v0s32i.n\t%1, %0 + [D, d; move , 2] mov.n\t%0, %1 [a, r; move , 3] mov\t%0, %1 + [f, f; farith, 3] mov.s\t%0, %1 [f, r; farith, 3] wfr\t%0, %1 [a, f; farith, 3] rfr\t%0, %1 - [a, Y; load , 3] movi\t%0, %y1 - [W, iF; move , 6] const16\t%0, %t1\;const16\t%0, %b1 + [D, R; load , 2] %v1l32i.n\t%0, %1 [a, U; load , 3] %v1l32i\t%0, %1 + [f, U; fload , 3] %v1lsi\t%0, %1 + [R, d; store , 2] %v0s32i.n\t%1, %0 [U, r; store , 3] %v0s32i\t%1, %0 + [U, f; fstore, 3] %v0ssi\t%1, %0 } [(set_attr "mode" "SF")]) -- 2.47.3