[MSP430] Use 430 insns in the large memory model for more patterns

Message ID 20191025132425.75af5473@jozef-kubuntu
State New
Headers show
Series
  • [MSP430] Use 430 insns in the large memory model for more patterns
Related show

Commit Message

Jozef Lawrynowicz Oct. 25, 2019, 12:24 p.m.
Where possible, it is always desirable to use 430 format instructions when
compiling for the 430X ISA and the large memory model. 430 instructions have
reduced code size and faster execution time.

This patch recognizes a couple of new patterns in which we can use 430 insns in
the large memory model.

Successfully regtested on trunk.

Ok to apply?

Comments

Jeff Law Oct. 26, 2019, 6:26 p.m. | #1
On 10/25/19 6:24 AM, Jozef Lawrynowicz wrote:
> Where possible, it is always desirable to use 430 format instructions when

> compiling for the 430X ISA and the large memory model. 430 instructions have

> reduced code size and faster execution time.

> 

> This patch recognizes a couple of new patterns in which we can use 430 insns in

> the large memory model.

> 

> Successfully regtested on trunk.

> 

> Ok to apply?

> 

> 

> 0001-MSP430-Use-430-insns-in-the-large-memory-model-for-m.patch

> 

> From ba3a8eafeba08dc034e219f892f2784c16f94c40 Mon Sep 17 00:00:00 2001

> From: Jozef Lawrynowicz <jozef.l@mittosystems.com>

> Date: Thu, 24 Oct 2019 15:17:29 +0100

> Subject: [PATCH] MSP430: Use 430 insns in the large memory model for more

>  patterns

> 

> gcc/ChangeLog:

> 

> 2019-10-25  Jozef Lawrynowicz  <jozef.l@mittosystems.com>

> 

> 	* config/msp430/msp430.c (msp430_check_index_not_high_mem): New.

> 	(msp430_check_plus_not_high_mem): New.

> 	(msp430_op_not_in_high_mem): Use new functions to check if the operand

> 	might be in low memory.

> 	Indicate that a 16-bit absolute address is in lower memory.

> 

> gcc/testsuite/ChangeLog:

> 

> 2019-10-25  Jozef Lawrynowicz  <jozef.l@mittosystems.com>

> 

> 	* gcc.target/msp430/mlarge-use-430-insn.c: New test.

> 

OK
jeff

Patch

From ba3a8eafeba08dc034e219f892f2784c16f94c40 Mon Sep 17 00:00:00 2001
From: Jozef Lawrynowicz <jozef.l@mittosystems.com>
Date: Thu, 24 Oct 2019 15:17:29 +0100
Subject: [PATCH] MSP430: Use 430 insns in the large memory model for more
 patterns

gcc/ChangeLog:

2019-10-25  Jozef Lawrynowicz  <jozef.l@mittosystems.com>

	* config/msp430/msp430.c (msp430_check_index_not_high_mem): New.
	(msp430_check_plus_not_high_mem): New.
	(msp430_op_not_in_high_mem): Use new functions to check if the operand
	might be in low memory.
	Indicate that a 16-bit absolute address is in lower memory.

gcc/testsuite/ChangeLog:

2019-10-25  Jozef Lawrynowicz  <jozef.l@mittosystems.com>

	* gcc.target/msp430/mlarge-use-430-insn.c: New test.

---
 gcc/config/msp430/msp430.c                    | 43 ++++++++++++++++---
 .../gcc.target/msp430/mlarge-use-430-insn.c   | 33 ++++++++++++++
 2 files changed, 70 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/msp430/mlarge-use-430-insn.c

diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c
index fe1fcc0db43..a3d0d9cf64b 100644
--- a/gcc/config/msp430/msp430.c
+++ b/gcc/config/msp430/msp430.c
@@ -3232,10 +3232,37 @@  msp430_print_operand_addr (FILE * file, machine_mode /*mode*/, rtx addr)
   msp430_print_operand_raw (file, addr);
 }
 
+/* We can only allow signed 15-bit indexes i.e. +/-32K.  */
+static bool
+msp430_check_index_not_high_mem (rtx op)
+{
+  if (CONST_INT_P (op)
+      && IN_RANGE (INTVAL (op), HOST_WIDE_INT_M1U << 15, (1 << 15) - 1))
+    return true;
+  return false;
+}
+
+/* If this returns true, we don't need a 430X insn.  */
+static bool
+msp430_check_plus_not_high_mem (rtx op)
+{
+  if (GET_CODE (op) != PLUS)
+    return false;
+  rtx op0 = XEXP (op, 0);
+  rtx op1 = XEXP (op, 1);
+  if (SYMBOL_REF_P (op0)
+      && (SYMBOL_REF_FLAGS (op0) & SYMBOL_FLAG_LOW_MEM)
+      && msp430_check_index_not_high_mem (op1))
+    return true;
+  return false;
+}
+
 /* Determine whether an RTX is definitely not a MEM referencing an address in
    the upper memory region.  Returns true if we've decided the address will be
    in the lower memory region, or the RTX is not a MEM.  Returns false
-   otherwise.  */
+   otherwise.
+   The Ys constraint will catch (mem (plus (const/reg)) but we catch cases
+   involving a symbol_ref here.  */
 bool
 msp430_op_not_in_high_mem (rtx op)
 {
@@ -3251,11 +3278,15 @@  msp430_op_not_in_high_mem (rtx op)
        memory.  */
     return true;
 
-  /* Catch (mem (const (plus ((symbol_ref) (const_int))))) e.g. &addr+2.  */
-  if ((GET_CODE (op0) == CONST)
-      && (GET_CODE (XEXP (op0, 0)) == PLUS)
-      && (SYMBOL_REF_P (XEXP (XEXP (op0, 0), 0)))
-      && (SYMBOL_REF_FLAGS (XEXP (XEXP (op0, 0), 0)) & SYMBOL_FLAG_LOW_MEM))
+  /* Check possibilites for (mem (plus)).
+     e.g. (mem (const (plus ((symbol_ref) (const_int))))) : &addr+2.  */
+  if (msp430_check_plus_not_high_mem (op0)
+      || ((GET_CODE (op0) == CONST)
+	  && msp430_check_plus_not_high_mem (XEXP (op0, 0))))
+    return true;
+
+  /* An absolute 16-bit address is allowed.  */
+  if ((CONST_INT_P (op0) && (IN_RANGE (INTVAL (op0), 0, (1 << 16) - 1))))
     return true;
 
   /* Return false when undecided.  */
diff --git a/gcc/testsuite/gcc.target/msp430/mlarge-use-430-insn.c b/gcc/testsuite/gcc.target/msp430/mlarge-use-430-insn.c
new file mode 100644
index 00000000000..efa598be685
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/mlarge-use-430-insn.c
@@ -0,0 +1,33 @@ 
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-mcpu=msp430" "-mcpu=430" "-msmall" } { "" } } */
+/* { dg-options "-mlarge -O1" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+/* Test to verify cases where we can use a 430 insn even in the large memory
+   model.  */
+
+int foo[2];
+
+/*
+** func:  { target msp430_region_lower }
+** ...
+**	MOV.W	#-4088, &foo
+**	MOV.W	#-8531, &40960
+**	MOVX.W	#-16657, &106496
+** ...
+*/
+/*
+** func:  { target msp430_region_not_lower }
+** ...
+**	MOVX.W	#-4088, &foo
+**	MOV.W	#-8531, &40960
+**	MOVX.W	#-16657, &106496
+** ...
+*/
+void
+func (void)
+{
+  foo[0] = 0xF008;
+  (*(int *)0xA000) = 0xDEAD;
+  (*(int *)0x1A000) = 0xBEEF;
+}
-- 
2.17.1