From b6ee63f6d7e6488bd2d3d9ddd12e0a4a174eca60 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.cc | 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 7e82a92171e0..a3bca84493ba 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.cc b/gcc/config/aarch64/aarch64.cc index ae65b330ad88..86ab4cb5e013 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -10552,6 +10552,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 c345e44054d3..78694da603bd 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 6d8ba73fda08..cb73a2daae89 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 c308015ac2c1..c286a0f4f150 100644 --- a/gcc/config/aarch64/predicates.md +++ b/gcc/config/aarch64/predicates.md @@ -261,6 +261,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") {