An ICE in gcc.dg/tree-ssa/asm-3.c for msp430-elf exposed some inconsistencies in the classification of some of the "special" registers, R0 (PC), R2 (SR/CG1) and R3 (CG2).
REG_CLASS_CONTENTS[GEN_REGS] does not have the bit for any of these registers set, yet REGNO_REG_CLASS returns GEN_REGS for them. Fixed by setting bit 0 for R0 in REG_CLASS_CONTENTS[GEN_REGS], and for R2 and R3, REGNO_REG_CLASS will now return NO_REGS. It is appropriate for R0 (PC) to be in the GEN_REGS class, as it can be used as an operand in any instruction and using any addressing mode. Successfully regtested the attached patch on trunk, and committed.
>From 9e26066f2a0f979a6bea538d27524e03b81618f3 Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz <joze...@mittosystems.com> Date: Fri, 2 Nov 2018 20:59:10 +0000 Subject: [PATCH] [MSP430] Fix register classification of PC, CG1 and CG2 2018-11-06 Jozef Lawrynowicz <joze...@mittosystems.com> * gcc/config/msp430/msp430.h (REG_CLASS_CONTENTS): Add R0 to REG_CLASS_CONTENTS[GEN_REGS]. (REGNO_REG_CLASS): Return NO_REGS for R2 and R3. * gcc/testsuite/gcc.target/msp430/special-regs.c: New test. --- gcc/config/msp430/msp430.h | 11 +++++++++-- gcc/testsuite/gcc.target/msp430/special-regs.c | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/msp430/special-regs.c diff --git a/gcc/config/msp430/msp430.h b/gcc/config/msp430/msp430.h index 6bfe28c..380e63e 100644 --- a/gcc/config/msp430/msp430.h +++ b/gcc/config/msp430/msp430.h @@ -241,10 +241,15 @@ enum reg_class 0x00000000, \ 0x00001000, \ 0x00002000, \ - 0x0000fff2, \ + 0x0000fff3, \ 0x0001ffff \ } +/* GENERAL_REGS just means that the "g" and "r" constraints can use these + registers. + Even though R0 (PC) and R1 (SP) are not "general" in that they can be used + for any purpose by the register allocator, they are general in that they can + be used by any instruction in any addressing mode. */ #define GENERAL_REGS GEN_REGS #define BASE_REG_CLASS GEN_REGS #define INDEX_REG_CLASS GEN_REGS @@ -259,7 +264,9 @@ enum reg_class #define FIRST_PSEUDO_REGISTER 17 -#define REGNO_REG_CLASS(REGNO) ((REGNO) < 17 \ +#define REGNO_REG_CLASS(REGNO) (REGNO != 2 \ + && REGNO != 3 \ + && REGNO < 17 \ ? GEN_REGS : NO_REGS) #define TRAMPOLINE_SIZE 4 /* FIXME */ diff --git a/gcc/testsuite/gcc.target/msp430/special-regs.c b/gcc/testsuite/gcc.target/msp430/special-regs.c new file mode 100644 index 0000000..c9121e6 --- /dev/null +++ b/gcc/testsuite/gcc.target/msp430/special-regs.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +int foo (void) +{ + register int pc __asm__("R0"); + register int sp __asm__("R1"); + register int cg1 __asm__("R2"); /* { dg-error "the register specified for 'cg1' is not general enough" } */ + register int cg2 __asm__("R3"); /* { dg-error "the register specified for 'cg2' is not general enough" } */ + + asm("" : "=r"(pc)); + asm("" : "=r"(sp)); + asm("" : "=r"(cg1)); + asm("" : "=r"(cg2)); + + return pc + sp + cg1 + cg2; +} -- 2.7.4