diff options
author | ktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2017-05-04 16:14:37 +0000 |
---|---|---|
committer | ktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2017-05-04 16:14:37 +0000 |
commit | 4328bd71cf51d0c25bfe0435763d1a33db1f13ef (patch) | |
tree | 16f7572235259d3af564038314b1a61a4227c071 /gcc/config/aarch64 | |
parent | d87051b4a155e4b0c4af64032bfbb2e82e9b2d6f (diff) | |
download | gcc-4328bd71cf51d0c25bfe0435763d1a33db1f13ef.tar.gz |
[AArch64] Accept more addressing modes for PRFM
* config/aarch64/aarch64.md (prefetch); Adjust predicate and
constraint on operand 0 to allow more general addressing modes.
Adjust output template.
* config/aarch64/aarch64.c (aarch64_address_valid_for_prefetch_p):
New function.
* config/aarch64/aarch64-protos.h
(aarch64_address_valid_for_prefetch_p): Declare prototype.
* config/aarch64/constraints.md (Dp): New address constraint.
* config/aarch64/predicates.md (aarch64_prefetch_operand): New
predicate.
* gcc.target/aarch64/prfm_imm_offset_1.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@247603 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/aarch64')
-rw-r--r-- | gcc/config/aarch64/aarch64-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.c | 18 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.md | 24 | ||||
-rw-r--r-- | gcc/config/aarch64/constraints.md | 5 | ||||
-rw-r--r-- | gcc/config/aarch64/predicates.md | 3 |
5 files changed, 41 insertions, 10 deletions
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 9543f8c9f29..2895a2a97b5 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -301,6 +301,7 @@ extern struct tune_params aarch64_tune_params; HOST_WIDE_INT aarch64_initial_elimination_offset (unsigned, unsigned); int aarch64_get_condition_code (rtx); +bool aarch64_address_valid_for_prefetch_p (rtx, bool); 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); diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index b760905ce3b..43fc928b460 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -4549,6 +4549,24 @@ aarch64_classify_address (struct aarch64_address_info *info, } } +/* Return true if the address X is valid for a PRFM instruction. + STRICT_P is true if we should do strict checking with + aarch64_classify_address. */ + +bool +aarch64_address_valid_for_prefetch_p (rtx x, bool strict_p) +{ + struct aarch64_address_info addr; + + /* PRFM accepts the same addresses as DImode... */ + bool res = aarch64_classify_address (&addr, x, DImode, MEM, strict_p); + if (!res) + return false; + + /* ... except writeback forms. */ + return addr.type != ADDRESS_REG_WB; +} + bool aarch64_symbolic_address_p (rtx x) { diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 51368e29f2d..d39b8507c75 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -519,27 +519,31 @@ ) (define_insn "prefetch" - [(prefetch (match_operand:DI 0 "register_operand" "r") + [(prefetch (match_operand:DI 0 "aarch64_prefetch_operand" "Dp") (match_operand:QI 1 "const_int_operand" "") (match_operand:QI 2 "const_int_operand" ""))] "" { - const char * pftype[2][4] = + const char * pftype[2][4] = { - {"prfm\\tPLDL1STRM, %a0", - "prfm\\tPLDL3KEEP, %a0", - "prfm\\tPLDL2KEEP, %a0", - "prfm\\tPLDL1KEEP, %a0"}, - {"prfm\\tPSTL1STRM, %a0", - "prfm\\tPSTL3KEEP, %a0", - "prfm\\tPSTL2KEEP, %a0", - "prfm\\tPSTL1KEEP, %a0"}, + {"prfm\\tPLDL1STRM, %0", + "prfm\\tPLDL3KEEP, %0", + "prfm\\tPLDL2KEEP, %0", + "prfm\\tPLDL1KEEP, %0"}, + {"prfm\\tPSTL1STRM, %0", + "prfm\\tPSTL3KEEP, %0", + "prfm\\tPSTL2KEEP, %0", + "prfm\\tPSTL1KEEP, %0"}, }; int locality = INTVAL (operands[2]); gcc_assert (IN_RANGE (locality, 0, 3)); + /* PRFM accepts the same addresses as a 64-bit LDR so wrap + the address into a DImode MEM so that aarch64_print_operand knows + how to print it. */ + operands[0] = gen_rtx_MEM (DImode, operands[0]); return pftype[INTVAL(operands[1])][locality]; } [(set_attr "type" "load1")] diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md index 5a252c07afa..b8293376fde 100644 --- a/gcc/config/aarch64/constraints.md +++ b/gcc/config/aarch64/constraints.md @@ -214,3 +214,8 @@ A constraint that matches an immediate operand valid for AdvSIMD scalar." (and (match_code "const_int") (match_test "aarch64_simd_imm_scalar_p (op, GET_MODE (op))"))) + +(define_address_constraint "Dp" + "@internal + An address valid for a prefetch instruction." + (match_test "aarch64_address_valid_for_prefetch_p (op, true)")) diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md index e83d45b3945..8e3ea9b4696 100644 --- a/gcc/config/aarch64/predicates.md +++ b/gcc/config/aarch64/predicates.md @@ -165,6 +165,9 @@ (match_test "aarch64_legitimate_address_p (mode, XEXP (op, 0), PARALLEL, 0)"))) +(define_predicate "aarch64_prefetch_operand" + (match_test "aarch64_address_valid_for_prefetch_p (op, false)")) + (define_predicate "aarch64_valid_symref" (match_code "const, symbol_ref, label_ref") { |