This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Extending constraints using register subclasses


Hi!
I wanted to add finer (one per) register subclasses, so that I can more finely control
the register placement inside the inline assembly.
These are the relevant definitions inside my include file:

enum reg_class
{
        NO_REGS = 0,
        GENERAL_REGS,
        X_REGS,
        R0_REG, R1_REG, R2_REG, R3_REG,
        R4_REG, R5_REG, R6_REG, R7_REG,
        X0_REG, X1_REG, X2_REG, X3_REG,
        X4_REG, X5_REG, X6_REG, X7_REG,
        ALL_REGS,
        LIM_REG_CLASSES
};

#define N_REG_CLASSES ((int) LIM_REG_CLASSES)

/* Give names of register classes as strings for dump file.  */

#define REG_CLASS_NAMES                                         \
        {                                                       \
                "NO_REGS",                                      \
                        "GENERAL_REGS",                         \
                        "X_REGS",                               \
                        "R0_REG", "R1_REG", "R2_REG", "R3_REG", \
                        "R4_REG", "R5_REG", "R6_REG", "R7_REG", \
                        "X0_REG", "X1_REG", "X2_REG", "X3_REG", \
                        "X4_REG", "X5_REG", "X6_REG", "X7_REG", \
                        "ALL_REGS",                             \
                        "LIM_REGS"                              \
                        }

/* 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                                              \
        {                                                               \
                { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS      */ \
                { 0xffffffff, 0x007fffff, 0x00000000, 0x00000000 }, /* GENERAL_REGS */ \
                { 0x00000000, 0xff800000, 0xffffffff, 0x007fffff }, /* X_REGS   */ \
                { 0x00000001, 0x00000000, 0x00000000, 0x00000000 }, /* R0_REG      */ \
                { 0x00000002, 0x00000000, 0x00000000, 0x00000000 }, /* R1_REG      */ \
                { 0x00000004, 0x00000000, 0x00000000, 0x00000000 }, /* R2_REG      */ \
                { 0x00000008, 0x00000000, 0x00000000, 0x00000000 }, /* R3_REG      */ \
                { 0x00000010, 0x00000000, 0x00000000, 0x00000000 }, /* R4_REG      */ \
                { 0x00000020, 0x00000000, 0x00000000, 0x00000000 }, /* R5_REG      */ \
                { 0x00000040, 0x00000000, 0x00000000, 0x00000000 }, /* R6_REG      */ \
                { 0x00000080, 0x00000000, 0x00000000, 0x00000000 }, /* R7_REG      */ \
                { 0x00000000, 0x00800000, 0x00000000, 0x00000000 }, /* X0_REG   */ \
                { 0x00000000, 0x01000000, 0x00000000, 0x00000000 }, /* X1_REG   */ \
                { 0x00000000, 0x02000000, 0x00000000, 0x00000000 }, /* X2_REG   */ \
                { 0x00000000, 0x04000000, 0x00000000, 0x00000000 }, /* X3_REG   */ \
                { 0x00000000, 0x08000000, 0x00000000, 0x00000000 }, /* X4_REG   */ \
                { 0x00000000, 0x10000000, 0x00000000, 0x00000000 }, /* X5_REG   */ \
                { 0x00000000, 0x20000000, 0x00000000, 0x00000000 }, /* X6_REG   */ \
                { 0x00000000, 0x40000000, 0x00000000, 0x00000000 }, /* X7_REG   */ \
                { 0xffffffff, 0xffffffff, 0xffffffff, 0x007fffff }, /* ALL_REGS         */ \
                        }

/* The same information, inverted:
   Return the class number of the smallest class containing
   reg number REGNO.  This could be a conditional expression
   or could index an array.  */
#define REGNO_REG_CLASS(REGNO) xxx_regno_reg_class(REGNO)

/* The class value for index registers, and the one for base regs.  */
#define INDEX_REG_CLASS NO_REGS
#define BASE_REG_CLASS  GENERAL_REGS

#define CLASS_REG_SIZE(CLASS) xxx_class_reg_size(CLASS)

#define CONSTRAINT_LEN(C, STR)                                          \
        ((((STR)[0] == 'a' || (STR)[0] == 'b') && (STR)[1] >= '0' && (STR)[1] <= '7') ? 2: \
         DEFAULT_CONSTRAINT_LEN(C, STR))

/* Get reg_class from a letter and string, such as appears in the machine description.  */
#define REG_CLASS_FROM_CONSTRAINT(CHAR, STR)            \
        xxx_reg_class_from_constraint(CHAR, STR)


I then have this inside my main C file:

int
xxx_reg_class_from_constraint(int c, char const *str)
{
        if (str[0] == 'a' && str[1] >= '0' && str[1] <= '7')
                return R0_REG + (str[1] - '0');
        if (str[0] == 'b' && str[1] >= '0' && str[1] <= '7')
                return X0_REG + (str[1] - '0');

        return c == 'r' ? GENERAL_REGS: (c == 'x' ? X_REGS: NO_REGS);
}

int
xxx_regno_reg_class(int regno)
{
        if (regno >= 0 && regno <= 7)
                return R0_REG + regno;
        if (regno >= XXX_FIRST_XREG && regno <= XXX_FIRST_XREG + 7)
                return X0_REG + (regno - XXX_FIRST_XREG);

        return XXX_REG_32BIT(regno) ? GENERAL_REGS:
                (XXX_REG_XREG(regno) ? X_REGS: NO_REGS);
}

int
xxx_class_reg_size(enum reg_class rcls)
{
        if (rcls == GENERAL_REGS ||
            (rcls >= R0_REG && rcls <= R7_REG))
                return 4;
        if (rcls == X_REGS ||
            (rcls >= X0_REG && rcls <= X7_REG))
                return 8;

        return 0;
}


But upon something like this:

static inline void *test_copy(void *dst, void const *src, int n)
{
        asm volatile ("mcopy\n\t"
                      :: "a0" (dst), "a1" (src), "a2" (n));

        return dst;
}


I get an 'error: 'asm' operand has impossible constraints'.
My doubt is, inside the RTLs I only have 'r' and 'x' general classes listed, of which the
a0..7 and b0..7 are part of, do I have to explicitly list a0..7 and b0..7 in every RTL, or
GCC is smart enough to see that a contraint 'r' maps to a register class of which a0..7
are part of?




 - Jamie



      


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]