The attached patch adds a new target macro called CASE_INSENSITIVE_REGISTER_NAMES, which allows the case of register names used in an asm statement clobber list, or given in a command line option, to be disregarded when comparing with the register names defined for the target in REGISTER_NAMES.
The macro is set to 1 for msp430 only, and set to 0 by default, so comparisons continue to be case-sensitive for all targets except msp430. Previously, a register name provided by the user using one of the aforementioned methods must exactly match those defined in the targets REGISTER_NAMES macro. This means that, for example, for msp430-elf the following code emits an ambiguous error: > void > foo (void) > { > __asm__ ("" : : : "r4", "R6"); > } > asm-register-names.c:8:3: error: unknown register name 'r4' in 'asm' All the register names defined in the msp430 REGISTER_NAMES macro use an upper case 'R', so use of lower case 'r' gets rejected. Successfully bootstrapped and regtested on trunk for x86_64-pc-linux-gnu, and regtested for msp430-elf. Ok for trunk?
>From 82eadcdcbb8914b06818f7c8a10156336518e8d1 Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz <joze...@mittosystems.com> Date: Wed, 17 Jul 2019 11:48:23 +0100 Subject: [PATCH] Implement CASE_INSENSITIVE_REGISTER_NAMES gcc/ChangeLog: 2019-07-18 Jozef Lawrynowicz <joze...@mittosystems.com> PR target/70320 * doc/tm.texi.in: Document new macro CASE_INSENSITIVE_REGISTER_NAMES. * doc/tm.texi: Likewise. * defaults.h: Define CASE_INSENSITIVE_REGISTER_NAMES to 0. * config/msp430/msp430.h: Define CASE_INSENSITIVE_REGISTER_NAMES to 1. * varasm.c (decode_reg_name_and_count): Use strcasecmp instead of strcmp for comparisons of asmspec with a register name if CASE_INSENSITIVE_REGISTER_NAMES is defined to 1. gcc/testsuite/ChangeLog: 2019-07-18 Jozef Lawrynowicz <joze...@mittosystems.com> PR target/70320 * gcc.target/msp430/asm-register-names.c: New test. --- gcc/config/msp430/msp430.h | 1 + gcc/defaults.h | 4 ++++ gcc/doc/tm.texi | 19 +++++++++++++++++++ gcc/doc/tm.texi.in | 19 +++++++++++++++++++ .../gcc.target/msp430/asm-register-names.c | 14 ++++++++++++++ gcc/varasm.c | 18 ++++++++++++++++-- 6 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/msp430/asm-register-names.c diff --git a/gcc/config/msp430/msp430.h b/gcc/config/msp430/msp430.h index 1288b1a263d..7b02c5fe28d 100644 --- a/gcc/config/msp430/msp430.h +++ b/gcc/config/msp430/msp430.h @@ -317,6 +317,7 @@ enum reg_class #define REGNO_OK_FOR_BASE_P(regno) 1 #define REGNO_OK_FOR_INDEX_P(regno) 1 +#define CASE_INSENSITIVE_REGISTER_NAMES 1 typedef struct diff --git a/gcc/defaults.h b/gcc/defaults.h index af7ea185f1e..2a22d52ba2f 100644 --- a/gcc/defaults.h +++ b/gcc/defaults.h @@ -1254,6 +1254,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define SHORT_IMMEDIATES_SIGN_EXTEND 0 #endif +#ifndef CASE_INSENSITIVE_REGISTER_NAMES +#define CASE_INSENSITIVE_REGISTER_NAMES 0 +#endif + #ifndef WORD_REGISTER_OPERATIONS #define WORD_REGISTER_OPERATIONS 0 #endif diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 8e5b01c9383..b895dfaa4b0 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -2000,6 +2000,25 @@ If the program counter has a register number, define this as that register number. Otherwise, do not define it. @end defmac +@defmac CASE_INSENSITIVE_REGISTER_NAMES +Define this macro to 1 if it is safe to disregard the case of register +names when comparing user-provided register names with the +names defined by @code{REGISTER_NAMES}. By default this is set to +0. + +This affects the register clobber list in an @code{asm} statement and +command line options which accept register names, such as +@option{-ffixed-@var{reg}}. + +For example, if @code{REGISTER_NAMES} defines a register called @var{R4}, +then the following use of lower case @var{r4} will not result in an error +if this macro is defined to 1. +@smallexample +asm ("" : : : "r4"); +@end smallexample + +@end defmac + @node Allocation Order @subsection Order of Allocation of Registers @cindex order of register allocation diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index b4d57b86e2f..4aba454248e 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -1749,6 +1749,25 @@ If the program counter has a register number, define this as that register number. Otherwise, do not define it. @end defmac +@defmac CASE_INSENSITIVE_REGISTER_NAMES +Define this macro to 1 if it is safe to disregard the case of register +names when comparing user-provided register names with the +names defined by @code{REGISTER_NAMES}. By default this is set to +0. + +This affects the register clobber list in an @code{asm} statement and +command line options which accept register names, such as +@option{-ffixed-@var{reg}}. + +For example, if @code{REGISTER_NAMES} defines a register called @var{R4}, +then the following use of lower case @var{r4} will not result in an error +if this macro is defined to 1. +@smallexample +asm ("" : : : "r4"); +@end smallexample + +@end defmac + @node Allocation Order @subsection Order of Allocation of Registers @cindex order of register allocation diff --git a/gcc/testsuite/gcc.target/msp430/asm-register-names.c b/gcc/testsuite/gcc.target/msp430/asm-register-names.c new file mode 100644 index 00000000000..3a963eb61d9 --- /dev/null +++ b/gcc/testsuite/gcc.target/msp430/asm-register-names.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-ffixed-r6 -ffixed-R7" } */ +/* { dg-final { scan-assembler "PUSH.*R4" } } */ +/* { dg-final { scan-assembler "PUSH.*R5" } } */ + +/* PR target/70320 + Check that both lower and upper case "r" in register names is accepted in + an asm statement clobber list and as arguments to command line options. */ + +void +foo (void) +{ + __asm__ ("" : : : "r4", "R5"); +} diff --git a/gcc/varasm.c b/gcc/varasm.c index e886cdc71b8..ab04bc2c332 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -947,7 +947,12 @@ decode_reg_name_and_count (const char *asmspec, int *pnregs) for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (reg_names[i][0] - && ! strcmp (asmspec, strip_reg_name (reg_names[i]))) +#if CASE_INSENSITIVE_REGISTER_NAMES + && ! strcasecmp (asmspec, strip_reg_name (reg_names[i])) +#else + && ! strcmp (asmspec, strip_reg_name (reg_names[i])) +#endif /* CASE_INSENSITIVE_REGISTER_NAMES */ + ) return i; #ifdef OVERLAPPING_REGISTER_NAMES @@ -961,7 +966,12 @@ decode_reg_name_and_count (const char *asmspec, int *pnregs) for (i = 0; i < (int) ARRAY_SIZE (table); i++) if (table[i].name[0] - && ! strcmp (asmspec, table[i].name)) +#if CASE_INSENSITIVE_REGISTER_NAMES + && ! strcasecmp (asmspec, table[i].name) +#else + && ! strcmp (asmspec, table[i].name) +#endif /* CASE_INSENSITIVE_REGISTER_NAMES */ + ) { *pnregs = table[i].nregs; return table[i].number; @@ -976,7 +986,11 @@ decode_reg_name_and_count (const char *asmspec, int *pnregs) for (i = 0; i < (int) ARRAY_SIZE (table); i++) if (table[i].name[0] +#if CASE_INSENSITIVE_REGISTER_NAMES + && ! strcasecmp (asmspec, table[i].name) +#else && ! strcmp (asmspec, table[i].name) +#endif /* CASE_INSENSITIVE_REGISTER_NAMES */ && reg_names[table[i].number][0]) return table[i].number; } -- 2.17.1