aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRenlin Li <renlin.li@arm.com>2015-08-24 14:59:58 +0000
committerRenlin Li <renlin@gcc.gnu.org>2015-08-24 14:59:58 +0000
commit6ce436451477990cb52ba22d31620547cbbff5ff (patch)
tree2191874de4bf18d207205043b5856b67c3009e08 /gcc
parent55466f20d76b4c619ae777f40d06f83e23dd5170 (diff)
downloadgcc-6ce436451477990cb52ba22d31620547cbbff5ff.zip
gcc-6ce436451477990cb52ba22d31620547cbbff5ff.tar.gz
gcc-6ce436451477990cb52ba22d31620547cbbff5ff.tar.bz2
[PATCH][ARM]Tighten the conditions for arm_movw, arm_movt.
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/arm/arm-protos.h1
-rw-r--r--gcc/config/arm/arm.c32
-rw-r--r--gcc/config/arm/arm.md2
-rw-r--r--gcc/config/arm/constraints.md3
5 files changed, 43 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d1a9e3a..33c91dc 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index cef9eec..ff168bf 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -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 */
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index c2095a3..7cc4d934 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -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. */
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 288bbb9..eefb7fa 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -5774,7 +5774,7 @@
[(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")
diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md
index 42935a4..f9e11e0 100644
--- a/gcc/config/arm/constraints.md
+++ b/gcc/config/arm/constraints.md
@@ -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")))))