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