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.39.5

Reply via email to