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
>>
>>

Reply via email to