Add extensive commentary to sparc's "U" constraint.
authordavem <davem@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 8 Nov 2012 03:26:49 +0000 (03:26 +0000)
committerdavem <davem@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 8 Nov 2012 03:26:49 +0000 (03:26 +0000)
* config/sparc/constraints.md ("U"): Document, in detail,
which this constraint is necessary.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@193322 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/sparc/constraints.md

index 0c363c2..9f9e874 100644 (file)
@@ -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
index 2f8c6ad..8963a31 100644 (file)
       (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")