+2016-11-22 Michael Collison <michael.collison@arm.com>
+
+ * config/aarch64/aarch64-protos.h
+ (aarch64_and_split_imm1, aarch64_and_split_imm2)
+ (aarch64_and_bitmask_imm): New prototypes
+ * config/aarch64/aarch64.c (aarch64_and_split_imm1):
+ New overloaded function to create bit mask covering the
+ lowest to highest bits set.
+ (aarch64_and_split_imm2): New overloaded functions to create bit
+ mask of zeros between first and last bit set.
+ (aarch64_and_bitmask_imm): New function to determine if a integer
+ is a valid two instruction "and" operation.
+ * config/aarch64/aarch64.md:(and<mode>3): New define_insn and _split
+ allowing wider range of constants with "and" operations.
+ * (ior<mode>3, xor<mode>3): Use new LOGICAL2 iterator to prevent
+ "and" operator from matching restricted constant range used for
+ ior and xor operators.
+ * config/aarch64/constraints.md (UsO constraint): New SImode constraint
+ for constants in "and" operantions.
+ (UsP constraint): New DImode constraint for constants in "and" operations.
+ * config/aarch64/iterators.md (lconst2): New mode iterator.
+ (LOGICAL2): New code iterator.
+ * config/aarch64/predicates.md (aarch64_logical_and_immediate): New
+ predicate
+ (aarch64_logical_and_operand): New predicate allowing extended constants
+ for "and" operations.
+
2016-11-22 Walter Lee <walt@tilera.com>
* config/tilegx/tilegx.md (trap): New pattern.
HOST_WIDE_INT aarch64_initial_elimination_offset (unsigned, unsigned);
int aarch64_get_condition_code (rtx);
bool aarch64_bitmask_imm (HOST_WIDE_INT val, machine_mode);
+unsigned HOST_WIDE_INT aarch64_and_split_imm1 (HOST_WIDE_INT val_in);
+unsigned HOST_WIDE_INT aarch64_and_split_imm2 (HOST_WIDE_INT val_in);
+bool aarch64_and_bitmask_imm (unsigned HOST_WIDE_INT val_in, machine_mode mode);
int aarch64_branch_cost (bool, bool);
enum aarch64_symbol_type aarch64_classify_symbolic_expression (rtx);
bool aarch64_const_vec_all_same_int_p (rtx, HOST_WIDE_INT);
return val == mask * bitmask_imm_mul[__builtin_clz (bits) - 26];
}
+/* Create mask of ones, covering the lowest to highest bits set in VAL_IN.
+ Assumed precondition: VAL_IN Is not zero. */
+
+unsigned HOST_WIDE_INT
+aarch64_and_split_imm1 (HOST_WIDE_INT val_in)
+{
+ int lowest_bit_set = ctz_hwi (val_in);
+ int highest_bit_set = floor_log2 (val_in);
+ gcc_assert (val_in != 0);
+
+ return ((HOST_WIDE_INT_UC (2) << highest_bit_set) -
+ (HOST_WIDE_INT_1U << lowest_bit_set));
+}
+
+/* Create constant where bits outside of lowest bit set to highest bit set
+ are set to 1. */
+
+unsigned HOST_WIDE_INT
+aarch64_and_split_imm2 (HOST_WIDE_INT val_in)
+{
+ return val_in | ~aarch64_and_split_imm1 (val_in);
+}
+
+/* Return true if VAL_IN is a valid 'and' bitmask immediate. */
+
+bool
+aarch64_and_bitmask_imm (unsigned HOST_WIDE_INT val_in, machine_mode mode)
+{
+ if (aarch64_bitmask_imm (val_in, mode))
+ return false;
+
+ if (aarch64_move_imm (val_in, mode))
+ return false;
+
+ unsigned HOST_WIDE_INT imm2 = aarch64_and_split_imm2 (val_in);
+
+ return aarch64_bitmask_imm (imm2, mode);
+}
/* Return true if val is an immediate that can be loaded into a
register in a single instruction. */
;; Logical operations
;; -------------------------------------------------------------------
+
+(define_insn_and_split "*aarch64_and<mode>_imm2"
+ [(set (match_operand:GPI 0 "register_operand" "=rk")
+ (and:GPI (match_operand:GPI 1 "register_operand" "%r")
+ (match_operand:GPI 2 "aarch64_logical_and_immediate" "<lconst2>")))]
+ ""
+ "#"
+ "true"
+ [(const_int 0)]
+ {
+ HOST_WIDE_INT val = INTVAL (operands[2]);
+ rtx imm1 = GEN_INT (aarch64_and_split_imm1 (val));
+ rtx imm2 = GEN_INT (aarch64_and_split_imm2 (val));
+
+ emit_insn (gen_and<mode>3 (operands[0], operands[1], imm1));
+ emit_insn (gen_and<mode>3 (operands[0], operands[0], imm2));
+ DONE;
+ }
+)
+
(define_insn "<optab><mode>3"
[(set (match_operand:GPI 0 "register_operand" "=r,rk,w")
(LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r,w")
(and (match_code "const_int")
(match_test "aarch64_move_imm (ival, DImode)")))
+(define_constraint "UsO"
+ "A constant that can be used with a 32-bit and operation."
+ (and (match_code "const_int")
+ (match_test "aarch64_and_bitmask_imm (ival, SImode)")))
+
+(define_constraint "UsP"
+ "A constant that can be used with a 64-bit and operation."
+ (and (match_code "const_int")
+ (match_test "aarch64_and_bitmask_imm (ival, DImode)")))
+
(define_constraint "S"
"A constraint that matches an absolute symbolic address."
(and (match_code "const,symbol_ref,label_ref")
;; Attribute to describe constants acceptable in logical operations
(define_mode_attr lconst [(SI "K") (DI "L")])
+;; Attribute to describe constants acceptable in logical and operations
+(define_mode_attr lconst2 [(SI "UsO") (DI "UsP")])
+
;; Map a mode to a specific constraint character.
(define_mode_attr cmode [(QI "q") (HI "h") (SI "s") (DI "d")])
(ior (match_operand 0 "register_operand")
(match_operand 0 "aarch64_logical_immediate")))
+(define_predicate "aarch64_logical_and_immediate"
+ (and (match_code "const_int")
+ (match_test "aarch64_and_bitmask_imm (INTVAL (op), mode)")))
+
(define_predicate "aarch64_shift_imm_si"
(and (match_code "const_int")
(match_test "(unsigned HOST_WIDE_INT) INTVAL (op) < 32")))
+2016-11-23 Michael Collison <michael.collison@arm.com>
+
+ * testsuite/gcc.target/aarch64/and_const.c: New test to verify
+ additional constants are recognized and fewer instructions generated.
+ * testsuite/gcc.target/aarch64/and_const2.c: New test to verify
+ additional constants are recognized and fewer instructions generated.
+
2016-11-22 Ian Lance Taylor <iant@golang.org>
* gcc.misc-tests/godump-1.c: Update expected output for recent
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int f2 (int x)
+{
+ x &= 0x0ffffff8;
+
+ x &= 0xff001fff;
+
+ return x;
+}
+
+/* { dg-final { scan-assembler-times "and\t" 2 } } */
+/* { dg-final { scan-assembler-not "movk\t" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+long long f2 (long x)
+{
+ x &= 0x0ffffffffffffff8LL;
+
+ x &= 0xff001fffLL;
+
+ return x;
+}
+
+/* { dg-final { scan-assembler-times "and\t" 2 } } */
+/* { dg-final { scan-assembler-not "movk\t" } } */