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

Reply via email to