On Thu, Oct 03, 2019 at 04:26:55PM +0100, Richard Earnshaw (lists) wrote:
> Well if that's how tightly ALL_REGS is defined, then really no back-end 
> should be defining it at all.  Instead the build system (or the run-time 
> initialization code) should be constructing it on the fly.  Similarly 
> for NO_REGS.

It's all very old.  Every target should define NO_REGS and ALL_REGS as
enumerators.  All of this used to be completely manual (and still
largely is).  (I'm not sure how we could do much better, except for the
trivial cases, and who cares for that?)


Like this from the first revision of rs6000.h, from 1992.  It said:

+/* Define the classes of registers for register constraints in the
+   machine description.  Also define ranges of constants.
+
+   One of the classes must always be named ALL_REGS and include all hard regs.
+   If there is more than one class, another class must be named NO_REGS
+   and contain no registers.
+
+   The name GENERAL_REGS must be the name of a class (or an alias for
+   another name such as ALL_REGS).  This is the class of registers
+   that is allowed by "g" or "r" in a register constraint.
+   Also, registers outside this class are allocated only when
+   instructions express preferences for them.
+
+   The classes must be numbered in nondecreasing order; that is,
+   a larger-numbered class must never be contained completely
+   in a smaller-numbered class.
+
+   For any two classes, it is very desirable that there be another
+   class that represents their union.  */

and

+/* The RS/6000 has three types of registers, fixed-point, floating-point,
+   and condition registers, plus three special registers, MQ, CTR, and the
+   link register.
+
+   However, r0 is special in that it cannot be used as a base register.
+   So make a class for registers valid as base registers.
+
+   Also, cr0 is the only condition code register that can be used in
+   arithmetic insns, so make a separate class for it. */
+
+enum reg_class { NO_REGS, BASE_REGS, GENERAL_REGS, FLOAT_REGS,
+  NON_SPECIAL_REGS, MQ_REGS, LINK_REGS, CTR_REGS, LINK_OR_CTR_REGS,
+  SPECIAL_REGS, CR0_REGS, CR_REGS, ALL_REGS, LIM_REG_CLASSES };

and

+/* Define which registers fit in which classes.
+   This is an initializer for a vector of HARD_REG_SET
+   of length N_REG_CLASSES.  */
+
+#define REG_CLASS_CONTENTS                             \
+  { {0, 0, 0}, {0xfffffffe, 0, 8}, {~0, 0, 8},         \
+    {0, ~0, 0}, {~0, ~0, 0}, {0, 0, 1}, {0, 0, 2},     \
+    {0, 0, 4}, {0, 0, 6}, {0, 0, 7}, {0, 0, 16},       \
+    {0, 0, 0xff0}, {~0, ~0, 0xfff5} }


Yes, I'm sure we could make a somewhat nicer interface now.  As you see
we *do* have a little bit nicer things than this, already.  But it is so
fundamental that changing anything means changing quite some passes, and
changing all backends, and none of this is trivial.


Segher

Reply via email to