From c738bfe0214141d183ae0abd0a46ce2e2453c5b1 Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Sat, 20 Feb 2021 13:19:10 +0000 Subject: [PATCH] aarch64, Darwin : Match conditions for a PRFUM insn. This unpessimizes the prefetch cases for Darwin where the assembler is not able to substitute the prfum instructions automagically. This improves the fix for Issue #43. * config/aarch64/aarch64-protos.h * config/aarch64/aarch64.c * config/aarch64/aarch64.md * config/aarch64/constraints.md * config/aarch64/predicates.md --- gcc/config/aarch64/aarch64-protos.h | 1 + gcc/config/aarch64/aarch64.c | 23 +++++++++++++++++++++ gcc/config/aarch64/aarch64.md | 31 +++++++++++++++++++++++++++++ gcc/config/aarch64/constraints.md | 5 +++++ gcc/config/aarch64/predicates.md | 3 +++ 5 files changed, 63 insertions(+) diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 7aebb521ef06..e9f4f2a5f8cc 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -745,6 +745,7 @@ void aarch64_post_cfi_startproc (void); poly_int64 aarch64_initial_elimination_offset (unsigned, unsigned); int aarch64_get_condition_code (rtx); bool aarch64_address_valid_for_prefetch_p (rtx, bool); +bool aarch64_address_valid_for_unscaled_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 5a2987fec482..010ee7ac0685 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -10409,6 +10409,29 @@ aarch64_address_valid_for_prefetch_p (rtx x, bool strict_p) return addr.type != ADDRESS_REG_WB; } +/* Return true if the address X is valid for a PRFUM instruction. + STRICT_P is true if we should do strict checking with + aarch64_classify_address. */ + +bool +aarch64_address_valid_for_unscaled_prefetch_p (rtx x, bool strict_p) +{ + struct aarch64_address_info addr; + + /* PRFUM accepts the same addresses as DImode, but constrained to a range + -256..255. */ + bool res = aarch64_classify_address (&addr, x, DImode, strict_p); + if (!res) + return false; + + if (addr.offset && ((INTVAL (addr.offset) > 255) + || (INTVAL (addr.offset) < -256))) + 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 a2ba2e7196e2..dd58bd0bdf8c 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -850,6 +850,37 @@ [(set_attr "type" "load_4")] ) +(define_insn "prefetch_unscaled" + [(prefetch (match_operand:DI 0 "aarch64_unscaled_prefetch_operand" "Du") + (match_operand:QI 1 "const_int_operand" "") + (match_operand:QI 2 "const_int_operand" ""))] + "" + { + const char * pftype[2][4] = + { + {"prfum\\tPLDL1STRM, %0", + "prfum\\tPLDL3KEEP, %0", + "prfum\\tPLDL2KEEP, %0", + "prfum\\tPLDL1KEEP, %0"}, + {"prfum\\tPSTL1STRM, %0", + "prfum\\tPSTL3KEEP, %0", + "prfum\\tPSTL2KEEP, %0", + "prfum\\tPSTL1KEEP, %0"}, + }; + + int locality = INTVAL (operands[2]); + + gcc_assert (IN_RANGE (locality, 0, 3)); + + /* PRFUM 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" "load_4")] +) + (define_insn "trap" [(trap_if (const_int 1) (const_int 8))] "" diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md index 95881e58f3a2..705f25a0ff4b 100644 --- a/gcc/config/aarch64/constraints.md +++ b/gcc/config/aarch64/constraints.md @@ -492,6 +492,11 @@ An address valid for a prefetch instruction." (match_test "aarch64_address_valid_for_prefetch_p (op, true)")) +(define_address_constraint "Du" + "@internal + An address valid for a prefetch instruction with an unscaled offset." + (match_test "aarch64_address_valid_for_unscaled_prefetch_p (op, true)")) + (define_constraint "vgb" "@internal A constraint that matches an immediate offset valid for SVE LD1B diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md index 7fd4f9e7d06d..3eb94c22b194 100644 --- a/gcc/config/aarch64/predicates.md +++ b/gcc/config/aarch64/predicates.md @@ -257,6 +257,9 @@ (define_predicate "aarch64_prefetch_operand" (match_test "aarch64_address_valid_for_prefetch_p (op, false)")) +(define_predicate "aarch64_unscaled_prefetch_operand" + (match_test "aarch64_address_valid_for_unscaled_prefetch_p (op, false)")) + (define_predicate "aarch64_valid_symref" (match_code "const, symbol_ref, label_ref") {