diff options
author | Yvan Roux <yvan.roux@linaro.org> | 2017-06-12 10:54:50 +0200 |
---|---|---|
committer | Yvan Roux <yvan.roux@linaro.org> | 2017-06-14 11:32:00 +0000 |
commit | 41af31768591291d4099c7c74a46cac23e331f8f (patch) | |
tree | 6c8a77a20d81705abde07c623a07bc3781932d41 | |
parent | a8e9362a9d31366981b14725883eded20cd867c9 (diff) |
gcc/
Backport from trunk r247603.
2016-05-04 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* 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/testsuite/
Backport from trunk r247603.
2016-05-04 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* gcc.target/aarch64/prfm_imm_offset_1.c: New test.
Change-Id: I048b116d85fedbf2e79bc1d075dfcd2160de40b3
-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 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/prfm_imm_offset_1.c | 18 |
6 files changed, 59 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 8dffe6f10e4..71f9819745f 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 adc280f67d9..7cc32dd037c 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 224beef7ced..b43f08b7bbd 100644 --- a/gcc/config/aarch64/constraints.md +++ b/gcc/config/aarch64/constraints.md @@ -222,3 +222,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") { diff --git a/gcc/testsuite/gcc.target/aarch64/prfm_imm_offset_1.c b/gcc/testsuite/gcc.target/aarch64/prfm_imm_offset_1.c new file mode 100644 index 00000000000..26ab9139cbc --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/prfm_imm_offset_1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +/* Check that we can generate the immediate-offset addressing + mode for PRFM. */ + +#define ARRSIZE 65 +int *bad_addr[ARRSIZE]; + +void +prefetch_for_read (void) +{ + int i; + for (i = 0; i < ARRSIZE; i++) + __builtin_prefetch (bad_addr[i] + 2, 0, 0); +} + +/* { dg-final { scan-assembler-times "prfm.*\\\[x\[0-9\]+, 8\\\]" 1 } } */ |