diff options
author | Umesh Kalappa <ukalappa.mips@gmail.com> | 2025-08-15 07:35:40 -0600 |
---|---|---|
committer | Jeff Law <jlaw@ventanamicro.com> | 2025-08-15 07:36:29 -0600 |
commit | ef5f0e9c510231d56aebdaa1a3db9b41a962d23c (patch) | |
tree | 3179e019c14c4073d0daea6d53e7e335e0f0da58 | |
parent | 7232a131d7c672995989750e0f11020b0f5789d2 (diff) | |
download | gcc-ef5f0e9c510231d56aebdaa1a3db9b41a962d23c.zip gcc-ef5f0e9c510231d56aebdaa1a3db9b41a962d23c.tar.gz gcc-ef5f0e9c510231d56aebdaa1a3db9b41a962d23c.tar.bz2 |
RISC-V: MIPS prefetch extensions for MIPS RV64 P8700 and can be enabled with xmipscbop.
Addressed the comments and tested "runtest --tool gcc --target_board='riscv-sim/-march=rv64gc_zba_zbb_zbc_zbs/-mabi=lp64/-mcmodel=medlow' riscv.exp" and 32 bit too
lint warnings can be ignored for riscv-ext.opt.
gcc/ChangeLog:
* config/riscv/riscv-ext-mips.def (DEFINE_RISCV_EXT):
Added mips prefetch extension.
* 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 nine 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.
-rw-r--r-- | gcc/config/riscv/constraints.md | 4 | ||||
-rw-r--r-- | gcc/config/riscv/predicates.md | 20 | ||||
-rw-r--r-- | gcc/config/riscv/riscv-ext-mips.def | 13 | ||||
-rw-r--r-- | gcc/config/riscv/riscv-ext.opt | 2 | ||||
-rw-r--r-- | gcc/config/riscv/riscv-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/riscv/riscv.cc | 31 | ||||
-rw-r--r-- | gcc/config/riscv/riscv.h | 11 | ||||
-rw-r--r-- | gcc/config/riscv/riscv.md | 18 | ||||
-rw-r--r-- | gcc/doc/riscv-ext.texi | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/mipsprefetch.c | 31 |
10 files changed, 131 insertions, 5 deletions
diff --git a/gcc/config/riscv/constraints.md b/gcc/config/riscv/constraints.md index 5ecaa19..979e0df 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 381f96c..bdb3d22 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,20 @@ (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") + (match_test "prefetch_const_operand (op, VOIDmode)") + (and (match_code "plus") + (match_test "register_operand (XEXP (op, 0), word_mode)") + (match_test "prefetch_const_operand (XEXP (op, 1), VOIDmode)")))) + +;; 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 5d7836d..132f6c1 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 26d6e68..ced05d2 100644 --- a/gcc/config/riscv/riscv-ext.opt +++ b/gcc/config/riscv/riscv-ext.opt @@ -449,3 +449,5 @@ 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 cf417e7..595dfd2 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -841,6 +841,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 9c38849..ffc0948 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -15451,6 +15451,37 @@ synthesize_add (rtx operands[3]) return true; } +/* + HINT : argument specify the target cache + + TODO : LOCALITY is unused. + + Return the first operand of the associated PREF or PREFX insn. */ +rtx +riscv_prefetch_cookie (rtx hint, rtx locality) +{ + return (GEN_INT (INTVAL (hint) + + CacheHint::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 #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index 29342d8..a728de4 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -1325,4 +1325,15 @@ 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. */ +typedef enum { + ICACHE_HINT = 0 << 3, + DCACHE_HINT = 1 << 3, + SCACHE_HINT = 2 << 3, + TCACHE_HINT = 3 << 3 +} CacheHint; + #endif /* ! GCC_RISCV_H */ diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index a72604e..af8adb0 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -4422,11 +4422,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 572b70e..185084e 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 0000000..b58aa0f --- /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 } } */ + |