aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-11-08 03:26:49 +0000
committerDavid S. Miller <davem@gcc.gnu.org>2012-11-07 19:26:49 -0800
commitcd933185e858f1318976657fde5ee0abc395eb5f (patch)
tree3e3687e37f5fa4fc9dfa1bff3ce6a1eacaa688d2
parent6dfd4c50890552cf276132c4d89fbae1e4cf8173 (diff)
downloadgcc-cd933185e858f1318976657fde5ee0abc395eb5f.zip
gcc-cd933185e858f1318976657fde5ee0abc395eb5f.tar.gz
gcc-cd933185e858f1318976657fde5ee0abc395eb5f.tar.bz2
Add extensive commentary to sparc's "U" constraint.
* config/sparc/constraints.md ("U"): Document, in detail, which this constraint is necessary. From-SVN: r193322
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/sparc/constraints.md38
2 files changed, 42 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0c363c2..9f9e874 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2012-11-07 David S. Miller <davem@davemloft.net>
+
+ * config/sparc/constraints.md ("U"): Document, in detail,
+ which this constraint is necessary.
+
2012-11-07 Uros Bizjak <ubizjak@gmail.com>
PR middle-end/55235
diff --git a/gcc/config/sparc/constraints.md b/gcc/config/sparc/constraints.md
index 2f8c6ad..8963a31 100644
--- a/gcc/config/sparc/constraints.md
+++ b/gcc/config/sparc/constraints.md
@@ -130,7 +130,43 @@
(match_code "mem")
(match_test "memory_ok_for_ldd (op)")))
-;; Not needed in 64-bit mode
+;; This awkward register constraint is necessary because it is not
+;; possible to express the "must be even numbered register" condition
+;; using register classes. The problem is that membership in a
+;; register class requires that all registers of a multi-regno
+;; register be included in the set. It is add_to_hard_reg_set
+;; and in_hard_reg_set_p which populate and test regsets with these
+;; semantics.
+;;
+;; So this means that we would have to put both the even and odd
+;; register into the register class, which would not restrict things
+;; at all.
+;;
+;; Using a combination of GENERAL_REGS and HARD_REGNO_MODE_OK is not a
+;; full solution either. In fact, even though IRA uses the macro
+;; HARD_REGNO_MODE_OK to calculate which registers are prohibited from
+;; use in certain modes, it still can allocate an odd hard register
+;; for DImode values. This is due to how IRA populates the table
+;; ira_useful_class_mode_regs[][]. It suffers from the same problem
+;; as using a register class to describe this restriction. Namely, it
+;; sets both the odd and even part of an even register pair in the
+;; regset. Therefore IRA can and will allocate odd registers for
+;; DImode values on 32-bit.
+;;
+;; There are legitimate cases where DImode values can end up in odd
+;; hard registers, the most notable example is argument passing.
+;;
+;; What saves us is reload and the DImode splitters. Both are
+;; necessary. The odd register splitters cannot match if, for
+;; example, we have a non-offsetable MEM. Reload will notice this
+;; case and reload the address into a single hard register.
+;;
+;; The real downfall of this awkward register constraint is that it does
+;; not evaluate to a true register class like a bonafide use of
+;; define_register_constraint would. This currently means that we cannot
+;; use LRA on Sparc, since the constraint processing of LRA really depends
+;; upon whether an extra constraint is for registers or not. It uses
+;; REG_CLASS_FROM_CONSTRAINT, and checks it against NO_REGS.
(define_constraint "U"
"Pseudo-register or hard even-numbered integer register"
(and (match_test "TARGET_ARCH32")