Hi @Jeff Law <jeffreya...@gmail.com> and @kito.ch...@sifive.com <kito.ch...@sifive.com> ,
Please do needful with your comments for the subjected patch . Thank you ~U On Wed, Jul 30, 2025 at 6:50 PM Umesh Kalappa <ukalappa.m...@gmail.com> wrote: > Hi All, > > Please do needful with reviewing the below changes (that enable mips > custom prefetch instruction ) and your comments helps us to push more > changes and stabilize the changes . > > Thank you > ~U > > On Mon, Jul 21, 2025 at 9:04 AM Umesh Kalappa <ukalappa.m...@gmail.com> > wrote: > >> Hi @Jeff Law <jeffreya...@gmail.com> , >> >> Please share your feedback and comments on the below changes . >> >> >> https://patchwork.sourceware.org/project/gcc/patch/20250717051448.733449-1-ukalappa.m...@gmail.com/ >> >> Thank you >> ~U >> >> >> On Thu, Jul 17, 2025 at 10:44 AM Umesh Kalappa <ukalappa.m...@gmail.com> >> wrote: >> >>> Updated the testcase for the prefetch write too. >>> >>> gcc/ChangeLog: >>> >>> * config/riscv/riscv-ext-mips.def (DEFINE_RISCV_EXT): >>> Added mips prefetch extension. >>> * config/riscv/riscv-ext.def: Likewise. >>> * config/riscv/riscv-ext.opt: Generated file. >>> * config/riscv/riscv.md (prefetch):. >>> Added mips prefetch address operand constraint. >>> * config/riscv/constraints.md: Added mips specific constraint. >>> * config/riscv/predicates.md (prefetch_operand): >>> Updated for mips 9 bits offset. >>> * config/riscv/riscv.cc (riscv_prefetch_offset_address_p): >>> Legitimate address with offset for prefetch check. >>> * config/riscv/riscv-protos.h: Likewise. >>> * config/riscv/riscv.h: >>> Macros to support for mips cached type. >>> * doc/riscv-ext.texi: Updated for mips prefetch. >>> >>> gcc/testsuite/ChangeLog: >>> >>> * gcc.target/riscv/mipsprefetch.c: Test file for mips.pref. >>> --- >>> gcc/config/riscv/constraints.md | 4 +++ >>> gcc/config/riscv/predicates.md | 22 ++++++++++++- >>> gcc/config/riscv/riscv-ext-mips.def | 13 ++++++++ >>> gcc/config/riscv/riscv-ext.opt | 3 ++ >>> gcc/config/riscv/riscv-protos.h | 2 ++ >>> gcc/config/riscv/riscv.cc | 28 +++++++++++++++++ >>> gcc/config/riscv/riscv.h | 9 ++++++ >>> gcc/config/riscv/riscv.md | 18 ++++++++--- >>> gcc/doc/riscv-ext.texi | 4 +++ >>> gcc/testsuite/gcc.target/riscv/mipsprefetch.c | 31 +++++++++++++++++++ >>> 10 files changed, 129 insertions(+), 5 deletions(-) >>> create mode 100644 gcc/testsuite/gcc.target/riscv/mipsprefetch.c >>> >>> diff --git a/gcc/config/riscv/constraints.md >>> b/gcc/config/riscv/constraints.md >>> index 5ecaa19eb01..979e0df06f1 100644 >>> --- a/gcc/config/riscv/constraints.md >>> +++ b/gcc/config/riscv/constraints.md >>> @@ -330,3 +330,7 @@ >>> (define_constraint "Q" >>> "An address operand that is valid for a prefetch instruction" >>> (match_operand 0 "prefetch_operand")) >>> + >>> +(define_address_constraint "ZD" >>> + "An address operand that is valid for a mips prefetch instruction" >>> + (match_test "riscv_prefetch_offset_address_p (op, mode)")) >>> diff --git a/gcc/config/riscv/predicates.md >>> b/gcc/config/riscv/predicates.md >>> index 1f9a6b562e5..ed7b34438c4 100644 >>> --- a/gcc/config/riscv/predicates.md >>> +++ b/gcc/config/riscv/predicates.md >>> @@ -27,10 +27,14 @@ >>> (ior (match_operand 0 "const_arith_operand") >>> (match_operand 0 "register_operand"))) >>> >>> +(define_predicate "prefetch_const_operand" >>> + (and (match_code "const_int") >>> + (match_test "(IN_RANGE (INTVAL (op), 0, 511))"))) >>> + >>> ;; REG or REG+D where D fits in a simm12 and has the low 5 bits >>> ;; off. The REG+D form can be reloaded into a temporary if needed >>> ;; after FP elimination if that exposes an invalid offset. >>> -(define_predicate "prefetch_operand" >>> +(define_predicate "zicbop_prefetch_operand" >>> (ior (match_operand 0 "register_operand") >>> (and (match_test "const_arith_operand (op, VOIDmode)") >>> (match_test "(INTVAL (op) & 0x1f) == 0")) >>> @@ -39,6 +43,22 @@ >>> (match_test "const_arith_operand (XEXP (op, 1), VOIDmode)") >>> (match_test "(INTVAL (XEXP (op, 1)) & 0x1f) == 0")))) >>> >>> +;; REG or REG+D where D fits in a uimm9 >>> +(define_predicate "mips_prefetch_operand" >>> + (ior (match_operand 0 "register_operand") >>> + (and (match_test "prefetch_const_operand (op, VOIDmode)") >>> + (match_test "(IN_RANGE (INTVAL (XEXP (op, 1)), 0, 511))")) >>> + (and (match_code "plus") >>> + (match_test "register_operand (XEXP (op, 0), word_mode)") >>> + (match_test "prefetch_const_operand (XEXP (op, 1), VOIDmode)") >>> + (match_test "(IN_RANGE (INTVAL (XEXP (op, 1)), 0, 511))")))) >>> + >>> +;; MIPS specific or Standard RISCV Extension >>> +(define_predicate "prefetch_operand" >>> + (if_then_else (match_test "TARGET_XMIPSCBOP") >>> + (match_operand 0 "mips_prefetch_operand") >>> + (match_operand 0 "zicbop_prefetch_operand"))) >>> + >>> (define_predicate "lui_operand" >>> (and (match_code "const_int") >>> (match_test "LUI_OPERAND (INTVAL (op))"))) >>> diff --git a/gcc/config/riscv/riscv-ext-mips.def >>> b/gcc/config/riscv/riscv-ext-mips.def >>> index 5d7836d5999..132f6c1060d 100644 >>> --- a/gcc/config/riscv/riscv-ext-mips.def >>> +++ b/gcc/config/riscv/riscv-ext-mips.def >>> @@ -33,3 +33,16 @@ DEFINE_RISCV_EXT ( >>> /* BITMASK_GROUP_ID. */ BITMASK_NOT_YET_ALLOCATED, >>> /* BITMASK_BIT_POSITION. */ BITMASK_NOT_YET_ALLOCATED, >>> /* EXTRA_EXTENSION_FLAGS. */ 0) >>> + >>> +DEFINE_RISCV_EXT ( >>> + /* NAME. */ xmipscbop, >>> + /* UPPERCASE_NAME. */ XMIPSCBOP, >>> + /* FULL_NAME. */ "Mips Prefetch extension", >>> + /* DESC. */ "", >>> + /* URL. */ , >>> + /* DEP_EXTS. */ ({}), >>> + /* SUPPORTED_VERSIONS. */ ({{1, 0}}), >>> + /* FLAG_GROUP. */ xmips, >>> + /* BITMASK_GROUP_ID. */ BITMASK_NOT_YET_ALLOCATED, >>> + /* BITMASK_BIT_POSITION. */ BITMASK_NOT_YET_ALLOCATED, >>> + /* EXTRA_EXTENSION_FLAGS. */ 0) >>> diff --git a/gcc/config/riscv/riscv-ext.opt >>> b/gcc/config/riscv/riscv-ext.opt >>> index 26d6e683acd..11ed64c0ad5 100644 >>> --- a/gcc/config/riscv/riscv-ext.opt >>> +++ b/gcc/config/riscv/riscv-ext.opt >>> @@ -449,3 +449,6 @@ Mask(XTHEADVECTOR) Var(riscv_xthead_subext) >>> Mask(XVENTANACONDOPS) Var(riscv_xventana_subext) >>> >>> Mask(XMIPSCMOV) Var(riscv_xmips_subext) >>> + >>> +Mask(XMIPSCBOP) Var(riscv_xmips_subext) >>> + >>> diff --git a/gcc/config/riscv/riscv-protos.h >>> b/gcc/config/riscv/riscv-protos.h >>> index a41c4c299fa..a193b1f26d3 100644 >>> --- a/gcc/config/riscv/riscv-protos.h >>> +++ b/gcc/config/riscv/riscv-protos.h >>> @@ -826,6 +826,8 @@ riscv_process_target_version_attr (tree, location_t); >>> extern void >>> riscv_override_options_internal (struct gcc_options *); >>> extern void riscv_option_override (void); >>> +extern rtx riscv_prefetch_cookie (rtx, rtx); >>> +extern bool riscv_prefetch_offset_address_p (rtx, machine_mode); >>> >>> struct riscv_tune_param; >>> /* Information about one micro-arch we know about. */ >>> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc >>> index 1275b034cf8..ef772659734 100644 >>> --- a/gcc/config/riscv/riscv.cc >>> +++ b/gcc/config/riscv/riscv.cc >>> @@ -15389,6 +15389,34 @@ synthesize_and (rtx operands[3]) >>> return true; >>> } >>> >>> +/* Given that we have an rtx of the form (prefetch ... WRITE LOCALITY), >>> + return the first operand of the associated PREF or PREFX insn. */ >>> +rtx >>> +riscv_prefetch_cookie (rtx write, rtx locality) >>> +{ >>> + /* store / load to data cache. */ >>> + /* locality is unused. */ >>> + return GEN_INT (INTVAL (write) + DCACHE_HINT + INTVAL (locality) * 0); >>> +} >>> + >>> +/* Return true if X is a legitimate address with offset for prefetch. >>> + MODE is the mode of the value being accessed. */ >>> +bool >>> +riscv_prefetch_offset_address_p (rtx x, machine_mode mode) >>> +{ >>> + struct riscv_address_info addr; >>> + >>> + if (riscv_classify_address (&addr, x, mode, false) >>> + && addr.type == ADDRESS_REG) >>> + { >>> + if (TARGET_XMIPSCBOP) >>> + return CONST_INT_P (addr.offset) >>> + && MIPS_RISCV_9BIT_OFFSET_P (INTVAL (addr.offset)); >>> + } >>> + >>> + return true; >>> +} >>> + >>> >>> /* Initialize the GCC target structure. */ >>> #undef TARGET_ASM_ALIGNED_HI_OP >>> diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h >>> index 45fa521f219..270b3fafc7d 100644 >>> --- a/gcc/config/riscv/riscv.h >>> +++ b/gcc/config/riscv/riscv.h >>> @@ -1319,4 +1319,13 @@ extern void >>> riscv_remove_unneeded_save_restore_calls (void); >>> >>> #define TARGET_HAS_FMV_TARGET_ATTRIBUTE 0 >>> >>> +/* mips pref valid offset range. */ >>> +#define MIPS_RISCV_9BIT_OFFSET_P(OFFSET) (IN_RANGE (OFFSET, 0, 511)) >>> + >>> +/* mips pref cache hint type. */ >>> +#define ICACHE_HINT (0 << 3) >>> +#define DCACHE_HINT (1 << 3) >>> +#define SCACHE_HINT (2 << 3) >>> +#define TCACHE_HINT (3 << 3) >>> + >>> #endif /* ! GCC_RISCV_H */ >>> diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md >>> index c3b504d0883..707a681bcf3 100644 >>> --- a/gcc/config/riscv/riscv.md >>> +++ b/gcc/config/riscv/riscv.md >>> @@ -4402,11 +4402,21 @@ >>> ) >>> >>> (define_insn "prefetch" >>> - [(prefetch (match_operand 0 "prefetch_operand" "Qr") >>> - (match_operand 1 "imm5_operand" "i") >>> - (match_operand 2 "const_int_operand" "n"))] >>> - "TARGET_ZICBOP" >>> + [(prefetch (match_operand 0 "prefetch_operand" "Qr,ZD") >>> + (match_operand 1 "imm5_operand" "i,i") >>> + (match_operand 2 "const_int_operand" "n,n"))] >>> + "TARGET_ZICBOP || TARGET_XMIPSCBOP" >>> { >>> + if (TARGET_XMIPSCBOP) >>> + { >>> + /* Mips Prefetch write is nop for p8700. */ >>> + if (operands[1] != CONST0_RTX (GET_MODE (operands[1]))) >>> + return "nop"; >>> + >>> + operands[1] = riscv_prefetch_cookie (operands[1], operands[2]); >>> + return "mips.pref\t%1,%a0"; >>> + } >>> + >>> switch (INTVAL (operands[1])) >>> { >>> case 0: >>> diff --git a/gcc/doc/riscv-ext.texi b/gcc/doc/riscv-ext.texi >>> index 572b70e20fa..185084edde7 100644 >>> --- a/gcc/doc/riscv-ext.texi >>> +++ b/gcc/doc/riscv-ext.texi >>> @@ -718,4 +718,8 @@ >>> @tab 1.0 >>> @tab Mips conditional move extension >>> >>> +@item xmipscbop >>> +@tab 1.0 >>> +@tab Mips Prefetch extension >>> + >>> @end multitable >>> diff --git a/gcc/testsuite/gcc.target/riscv/mipsprefetch.c >>> b/gcc/testsuite/gcc.target/riscv/mipsprefetch.c >>> new file mode 100644 >>> index 00000000000..b58aa0fa085 >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/riscv/mipsprefetch.c >>> @@ -0,0 +1,31 @@ >>> +/* pic used here to prevent the assembler to emit .nopic directive. */ >>> +/* { dg-do compile } */ >>> +/* { dg-options "-march=rv32imafd_xmipscbop -fpic" { target { rv32 } } >>> } */ >>> +/* { dg-options "-march=rv64imafd_xmipscbop -fpic -mabi=lp64d" { target >>> { rv64 } } } */ >>> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" } } */ >>> + >>> + >>> +void prefetch_read(char *a) >>> +{ >>> + __builtin_prefetch (&a[3], 0, 0); >>> +} >>> + >>> +void prefetch_write(char *a) >>> +{ >>> + __builtin_prefetch (&a[1], 1, 0); >>> +} >>> + >>> +void prefetch_read_out_range_offset(char *a) >>> +{ >>> + __builtin_prefetch (&a[512], 0, 1); >>> +} >>> + >>> +void prefetch_write_out_range_offset(char *a) >>> +{ >>> + __builtin_prefetch (&a[1024], 1, 1); >>> +} >>> + >>> +/* { dg-final { scan-assembler-times "mips.pref\t8,0\\(\[a-x0-9\]+\\)" >>> 1 } } */ >>> +/* { dg-final { scan-assembler-times "mips.pref\t8,3\\(\[a-x0-9\]+\\)" >>> 1 } } */ >>> +/* { dg-final { scan-assembler-times "nop" 2 } } */ >>> + >>> >>> base-commit: c163bbd75b600cc6d1ec752425ee895ef5b9b37d >>> -- >>> 2.43.0 >>> >>>