[PATCH][ARM]Tighten the conditions for arm_movw, arm_movt.
authorRenlin Li <renlin.li@arm.com>
Mon, 24 Aug 2015 14:59:58 +0000 (14:59 +0000)
committerRenlin Li <renlin@gcc.gnu.org>
Mon, 24 Aug 2015 14:59:58 +0000 (14:59 +0000)
gcc/

2015-08-24  Renlin Li  <renlin.li@arm.com>

* config/arm/arm-protos.h (arm_valid_symbolic_address_p): Declare.
* config/arm/arm.c (arm_valid_symbolic_address_p): Define.
* config/arm/arm.md (arm_movt): Use arm_valid_symbolic_address_p.
* config/arm/constraints.md ("j"): Add check for high code.

From-SVN: r227129

gcc/ChangeLog
gcc/config/arm/arm-protos.h
gcc/config/arm/arm.c
gcc/config/arm/arm.md
gcc/config/arm/constraints.md

index d1a9e3a5b13c9e5f47ec26bda3d81f41b59bd18c..33c91dca02379f85539cc0e8f8da679027e6b723 100644 (file)
@@ -1,3 +1,10 @@
+2015-08-24  Renlin Li  <renlin.li@arm.com>
+
+       * config/arm/arm-protos.h (arm_valid_symbolic_address_p): Declare.
+       * config/arm/arm.c (arm_valid_symbolic_address_p): Define.
+       * config/arm/arm.md (arm_movt): Use arm_valid_symbolic_address_p.
+       * config/arm/constraints.md ("j"): Add check for high code.
+
 2015-08-24  Tom de Vries  <tom@codesourcery.com>
 
        PR tree-optimization/65468
index cef9eec277d3e799f333d0a3704afb2189c7cd23..ff168bf2c5fa8e583cad6752615c0e17f3997617 100644 (file)
@@ -319,6 +319,7 @@ extern int vfp3_const_double_for_bits (rtx);
 
 extern void arm_emit_coreregs_64bit_shift (enum rtx_code, rtx, rtx, rtx, rtx,
                                           rtx);
+extern bool arm_valid_symbolic_address_p (rtx);
 extern bool arm_validize_comparison (rtx *, rtx *, rtx *);
 #endif /* RTX_CODE */
 
index c2095a32a64096b7bf82876d2c70e607a6f38d2f..7cc4d93476157309cf772bba536332d8dc71c00f 100644 (file)
@@ -28664,6 +28664,38 @@ arm_emit_coreregs_64bit_shift (enum rtx_code code, rtx out, rtx in,
   #undef BRANCH
 }
 
+/* Returns true if the pattern is a valid symbolic address, which is either a
+   symbol_ref or (symbol_ref + addend).
+
+   According to the ARM ELF ABI, the initial addend of REL-type relocations
+   processing MOVW and MOVT instructions is formed by interpreting the 16-bit
+   literal field of the instruction as a 16-bit signed value in the range
+   -32768 <= A < 32768.  */
+
+bool
+arm_valid_symbolic_address_p (rtx addr)
+{
+  rtx xop0, xop1 = NULL_RTX;
+  rtx tmp = addr;
+
+  if (GET_CODE (tmp) == SYMBOL_REF || GET_CODE (tmp) == LABEL_REF)
+    return true;
+
+  /* (const (plus: symbol_ref const_int))  */
+  if (GET_CODE (addr) == CONST)
+    tmp = XEXP (addr, 0);
+
+  if (GET_CODE (tmp) == PLUS)
+    {
+      xop0 = XEXP (tmp, 0);
+      xop1 = XEXP (tmp, 1);
+
+      if (GET_CODE (xop0) == SYMBOL_REF && CONST_INT_P (xop1))
+         return IN_RANGE (INTVAL (xop1), -0x8000, 0x7fff);
+    }
+
+  return false;
+}
 
 /* Returns true if a valid comparison operation and makes
    the operands in a form that is valid.  */
index 288bbb9f83638db0c5d298d17a60ff96ff3c982e..eefb7fa773fbb5f9c90884f9a2ad5ae1586f949f 100644 (file)
   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
        (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0")
                   (match_operand:SI 2 "general_operand"      "i")))]
-  "arm_arch_thumb2"
+  "arm_arch_thumb2 && arm_valid_symbolic_address_p (operands[2])"
   "movt%?\t%0, #:upper16:%c2"
   [(set_attr "predicable" "yes")
    (set_attr "predicable_short_it" "no")
index 42935a4ca6d43fef4c06aadbdcda7ca46a24447e..f9e11e0111879ffbd7bf0af77bb84d1e0503291c 100644 (file)
@@ -67,7 +67,8 @@
 (define_constraint "j"
  "A constant suitable for a MOVW instruction. (ARM/Thumb-2)"
  (and (match_test "TARGET_32BIT && arm_arch_thumb2")
-      (ior (match_code "high")
+      (ior (and (match_code "high")
+               (match_test "arm_valid_symbolic_address_p (XEXP (op, 0))"))
           (and (match_code "const_int")
                 (match_test "(ival & 0xffff0000) == 0")))))