msp430.c (msp430_check_index_not_high_mem): New.
authorJozef Lawrynowicz <jozef.l@mittosystems.com>
Wed, 30 Oct 2019 14:01:12 +0000 (14:01 +0000)
committerJozef Lawrynowicz <jozefl@gcc.gnu.org>
Wed, 30 Oct 2019 14:01:12 +0000 (14:01 +0000)
gcc/ChangeLog:

2019-10-30  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-30  Jozef Lawrynowicz  <jozef.l@mittosystems.com>

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

From-SVN: r277623

gcc/ChangeLog
gcc/config/msp430/msp430.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/msp430/mlarge-use-430-insn.c [new file with mode: 0644]

index b48bb4d838c91f1cd23def8a29f07d05be1b7fea..7b90915be6676cd7f2e8e8560472dda379a66c85 100644 (file)
@@ -1,3 +1,11 @@
+2019-10-30  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.
+
 2019-10-30  Martin Jambor  <mjambor@suse.cz>
 
        * ipa-prop.c (ipa_compute_jump_functions_for_bb): Fix the call to
index fe1fcc0db4353a7e8019c788130fa5a44015a5f0..a3d0d9cf64b8ad16b9a09c053a77fee02b707991 100644 (file)
@@ -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.  */
index 10cf941529247b7598a1bc1fa67a8bbeb3b1528e..889e33bbc65415e13c164d212ef23b23afd8dd43 100644 (file)
@@ -1,3 +1,7 @@
+2019-10-30  Jozef Lawrynowicz  <jozef.l@mittosystems.com>
+
+       * gcc.target/msp430/mlarge-use-430-insn.c: New test.
+
 2019-10-30  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/92275
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 (file)
index 0000000..efa598b
--- /dev/null
@@ -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;
+}