]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
xtensa: Make all memory constraints special
authorTakayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp>
Thu, 9 Oct 2025 21:33:36 +0000 (06:33 +0900)
committerMax Filippov <jcmvbkbc@gmail.com>
Mon, 20 Oct 2025 16:34:38 +0000 (09:34 -0700)
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
gcc/config/xtensa/xtensa.md

index 08fdab1c2e7f4ce675ecd69840867796e03ef899..7322107eaa37a21cb1150f22fffe1c7538e7748d 100644 (file)
 
 ;; 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)")))
  (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)")))
index 950c33f859f11dcdf9efdfe9d269b631ea4ba2aa..aa64808ea6220f5df2a2845a0f5aabe022925824 100644 (file)
   "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
   "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
   "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
     && !(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")])