From: Renlin Li Date: Mon, 24 Aug 2015 14:59:58 +0000 (+0000) Subject: [PATCH][ARM]Tighten the conditions for arm_movw, arm_movt. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6ce436451477990cb52ba22d31620547cbbff5ff;p=gcc.git [PATCH][ARM]Tighten the conditions for arm_movw, arm_movt. gcc/ 2015-08-24 Renlin Li * 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d1a9e3a5b13..33c91dca023 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2015-08-24 Renlin Li + + * 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 PR tree-optimization/65468 diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index cef9eec277d..ff168bf2c5f 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 c2095a32a64..7cc4d934761 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 288bbb9f836..eefb7fa773f 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 42935a4ca6d..f9e11e01118 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")))))