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 <[email protected]>
Date: Wed, 17 Jul 2019 11:48:23 +0100
Subject: [PATCH] Implement CASE_INSENSITIVE_REGISTER_NAMES
gcc/ChangeLog:
2019-07-18 Jozef Lawrynowicz <[email protected]>
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 <[email protected]>
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