[committed,MSP430] Fix classification of PC, CG1 and CG2 registers
diff mbox series

Message ID 022ef79f-d4b1-5fe9-95ee-7259b6e4dfed@mittosystems.com
State New
Headers show
Series
  • [committed,MSP430] Fix classification of PC, CG1 and CG2 registers
Related show

Commit Message

Jozef Lawrynowicz Nov. 6, 2018, 12:05 p.m. UTC
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.

Patch
diff mbox series

From 9e26066f2a0f979a6bea538d27524e03b81618f3 Mon Sep 17 00:00:00 2001
From: Jozef Lawrynowicz <jozef.l@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  <jozef.l@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