Commit 43fd192f by Michael Collison Committed by Michael Collison

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.
	* 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.

From-SVN: r242739
parent ed9e2fa9
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> 2016-11-22 Walter Lee <walt@tilera.com>
* config/tilegx/tilegx.md (trap): New pattern. * config/tilegx/tilegx.md (trap): New pattern.
...@@ -296,6 +296,9 @@ extern struct tune_params aarch64_tune_params; ...@@ -296,6 +296,9 @@ extern struct tune_params aarch64_tune_params;
HOST_WIDE_INT aarch64_initial_elimination_offset (unsigned, unsigned); HOST_WIDE_INT aarch64_initial_elimination_offset (unsigned, unsigned);
int aarch64_get_condition_code (rtx); int aarch64_get_condition_code (rtx);
bool aarch64_bitmask_imm (HOST_WIDE_INT val, machine_mode); 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); int aarch64_branch_cost (bool, bool);
enum aarch64_symbol_type aarch64_classify_symbolic_expression (rtx); enum aarch64_symbol_type aarch64_classify_symbolic_expression (rtx);
bool aarch64_const_vec_all_same_int_p (rtx, HOST_WIDE_INT); bool aarch64_const_vec_all_same_int_p (rtx, HOST_WIDE_INT);
......
...@@ -3674,6 +3674,44 @@ aarch64_bitmask_imm (HOST_WIDE_INT val_in, machine_mode mode) ...@@ -3674,6 +3674,44 @@ aarch64_bitmask_imm (HOST_WIDE_INT val_in, machine_mode mode)
return val == mask * bitmask_imm_mul[__builtin_clz (bits) - 26]; 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 /* Return true if val is an immediate that can be loaded into a
register in a single instruction. */ register in a single instruction. */
......
...@@ -3397,6 +3397,26 @@ ...@@ -3397,6 +3397,26 @@
;; Logical operations ;; 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" (define_insn "<optab><mode>3"
[(set (match_operand:GPI 0 "register_operand" "=r,rk,w") [(set (match_operand:GPI 0 "register_operand" "=r,rk,w")
(LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r,w") (LOGICAL:GPI (match_operand:GPI 1 "register_operand" "%r,r,w")
......
...@@ -69,6 +69,16 @@ ...@@ -69,6 +69,16 @@
(and (match_code "const_int") (and (match_code "const_int")
(match_test "aarch64_move_imm (ival, DImode)"))) (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" (define_constraint "S"
"A constraint that matches an absolute symbolic address." "A constraint that matches an absolute symbolic address."
(and (match_code "const,symbol_ref,label_ref") (and (match_code "const,symbol_ref,label_ref")
......
...@@ -440,6 +440,9 @@ ...@@ -440,6 +440,9 @@
;; Attribute to describe constants acceptable in logical operations ;; Attribute to describe constants acceptable in logical operations
(define_mode_attr lconst [(SI "K") (DI "L")]) (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. ;; Map a mode to a specific constraint character.
(define_mode_attr cmode [(QI "q") (HI "h") (SI "s") (DI "d")]) (define_mode_attr cmode [(QI "q") (HI "h") (SI "s") (DI "d")])
......
...@@ -106,6 +106,10 @@ ...@@ -106,6 +106,10 @@
(ior (match_operand 0 "register_operand") (ior (match_operand 0 "register_operand")
(match_operand 0 "aarch64_logical_immediate"))) (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" (define_predicate "aarch64_shift_imm_si"
(and (match_code "const_int") (and (match_code "const_int")
(match_test "(unsigned HOST_WIDE_INT) INTVAL (op) < 32"))) (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> 2016-11-22 Ian Lance Taylor <iant@golang.org>
* gcc.misc-tests/godump-1.c: Update expected output for recent * gcc.misc-tests/godump-1.c: Update expected output for recent
......
/* { 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" } } */
/* { 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" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment