]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
MIPS: Add CACHE instruction for mips16e2
authorJie Mei <jie.mei@oss.cipunited.com>
Mon, 19 Jun 2023 08:29:57 +0000 (16:29 +0800)
committerYunQiang Su <yunqiang.su@cipunited.com>
Mon, 3 Jul 2023 03:38:20 +0000 (11:38 +0800)
This patch adds CACHE instruction from mips16e2
with corresponding tests.

gcc/ChangeLog:

* config/mips/mips.cc(mips_9bit_offset_address_p): Restrict the
address register to M16_REGS for MIPS16.
(BUILTIN_AVAIL_MIPS16E2): Defined a new macro.
(AVAIL_MIPS16E2_OR_NON_MIPS16): Same as above.
(AVAIL_NON_MIPS16 (cache..)): Update to
AVAIL_MIPS16E2_OR_NON_MIPS16.
* config/mips/mips.h (ISA_HAS_CACHE): Add clause for ISA_HAS_MIPS16E2.
* config/mips/mips.md (mips_cache): Mark as extended MIPS16.

gcc/testsuite/ChangeLog:

* gcc.target/mips/mips16e2-cache.c: New tests for mips16e2.

gcc/config/mips/mips.cc
gcc/config/mips/mips.h
gcc/config/mips/mips.md
gcc/testsuite/gcc.target/mips/mips16e2-cache.c [new file with mode: 0644]

index 78f368f680393c98849021ae0a3bcb3dfb1f35eb..fec25bdf8eac54595a486b033fc0edc44b49632a 100644 (file)
@@ -2926,6 +2926,9 @@ mips_9bit_offset_address_p (rtx x, machine_mode mode)
   return (mips_classify_address (&addr, x, mode, false)
          && addr.type == ADDRESS_REG
          && CONST_INT_P (addr.offset)
+         && (!TARGET_MIPS16E2
+             || M16_REG_P (REGNO (addr.reg))
+             || REGNO (addr.reg) >= FIRST_PSEUDO_REGISTER)
          && MIPS_9BIT_OFFSET_P (INTVAL (addr.offset)));
 }
 
@@ -15514,9 +15517,13 @@ mips_loongson_ext2_prefetch_cookie (rtx write, rtx)
        The function is available on the current target if !TARGET_MIPS16.
 
    BUILTIN_AVAIL_MIPS16
-       The function is available on the current target if TARGET_MIPS16.  */
+       The function is available on the current target if TARGET_MIPS16.
+
+   BUILTIN_AVAIL_MIPS16E2
+       The function is available on the current target if TARGET_MIPS16E2.  */
 #define BUILTIN_AVAIL_NON_MIPS16 1
 #define BUILTIN_AVAIL_MIPS16 2
+#define BUILTIN_AVAIL_MIPS16E2 4
 
 /* Declare an availability predicate for built-in functions that
    require non-MIPS16 mode and also require COND to be true.
@@ -15528,6 +15535,17 @@ mips_loongson_ext2_prefetch_cookie (rtx write, rtx)
    return (COND) ? BUILTIN_AVAIL_NON_MIPS16 : 0;                       \
  }
 
+/* Declare an availability predicate for built-in functions that
+   require non-MIPS16 mode or MIPS16E2 and also require COND to be true.
+   NAME is the main part of the predicate's name.  */
+#define AVAIL_MIPS16E2_OR_NON_MIPS16(NAME, COND)                       \
+ static unsigned int                                                   \
+ mips_builtin_avail_##NAME (void)                                      \
+ {                                                                     \
+   return ((COND) ? BUILTIN_AVAIL_NON_MIPS16 | BUILTIN_AVAIL_MIPS16E2  \
+          : 0);                                                        \
+ }
+
 /* Declare an availability predicate for built-in functions that
    support both MIPS16 and non-MIPS16 code and also require COND
    to be true.  NAME is the main part of the predicate's name.  */
@@ -15573,7 +15591,7 @@ AVAIL_NON_MIPS16 (dsp_32, !TARGET_64BIT && TARGET_DSP)
 AVAIL_NON_MIPS16 (dsp_64, TARGET_64BIT && TARGET_DSP)
 AVAIL_NON_MIPS16 (dspr2_32, !TARGET_64BIT && TARGET_DSPR2)
 AVAIL_NON_MIPS16 (loongson, TARGET_LOONGSON_MMI)
-AVAIL_NON_MIPS16 (cache, TARGET_CACHE_BUILTIN)
+AVAIL_MIPS16E2_OR_NON_MIPS16 (cache, TARGET_CACHE_BUILTIN)
 AVAIL_NON_MIPS16 (msa, TARGET_MSA)
 
 /* Construct a mips_builtin_description from the given arguments.
@@ -17573,7 +17591,8 @@ mips_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
   d = &mips_builtins[fcode];
   avail = d->avail ();
   gcc_assert (avail != 0);
-  if (TARGET_MIPS16 && !(avail & BUILTIN_AVAIL_MIPS16))
+  if (TARGET_MIPS16 && !(avail & BUILTIN_AVAIL_MIPS16)
+      && (!TARGET_MIPS16E2 || !(avail & BUILTIN_AVAIL_MIPS16E2)))
     {
       error ("built-in function %qE not supported for MIPS16",
             DECL_NAME (fndecl));
index 05ccd2061c72e84a2644737438e33444695b1c4f..0b6ea78290e985d01407c236cb8d65a713487284 100644 (file)
@@ -1386,7 +1386,8 @@ struct mips_cpu_info {
 #define TARGET_CACHE_BUILTIN (mips_isa >= MIPS_ISA_MIPS3)
 
 /* The CACHE instruction is available.  */
-#define ISA_HAS_CACHE (TARGET_CACHE_BUILTIN && !TARGET_MIPS16)
+#define ISA_HAS_CACHE (TARGET_CACHE_BUILTIN && (!TARGET_MIPS16 \
+                                               || TARGET_MIPS16E2))
 \f
 /* Tell collect what flags to pass to nm.  */
 #ifndef NM_FLAGS
index eec167a1aa8b9bdcffbffd507351d843d17f9d84..609416b8cc8078966f536f09916fcf4a409f9102 100644 (file)
                     (match_operand:QI 1 "address_operand" "ZD")]
                    UNSPEC_MIPS_CACHE))]
   "ISA_HAS_CACHE"
-  "cache\t%X0,%a1")
+  "cache\t%X0,%a1"
+  [(set_attr "extended_mips16" "yes")])
 
 ;; Similar, but with the operands hard-coded to an R10K cache barrier
 ;; operation.  We keep the pattern distinct so that we can identify
diff --git a/gcc/testsuite/gcc.target/mips/mips16e2-cache.c b/gcc/testsuite/gcc.target/mips/mips16e2-cache.c
new file mode 100644 (file)
index 0000000..dcc39b5
--- /dev/null
@@ -0,0 +1,34 @@
+/* { dg-options "-mno-abicalls -mgpopt -G8 -mabi=32 -mips32r2 -mips16 -mmips16e2" } */
+/* { dg-skip-if "naming registers makes this a code quality test" { *-*-* } { "-O0" } { "" } } */
+
+/* Test cache.  */
+
+void
+test01 (int *area)
+{
+  __builtin_mips_cache (20, area);
+}
+
+void
+test02 (const short *area)
+{
+  __builtin_mips_cache (24, area + 10);
+}
+
+void
+test03 (volatile unsigned int *area, int offset)
+{
+  __builtin_mips_cache (0, area + offset);
+}
+
+void
+test04 (const volatile unsigned char *area)
+{
+  __builtin_mips_cache (4, area - 80);
+}
+
+/* { dg-final { scan-assembler "\tcache\t0x14,0\\(\\\$4\\)" } } */
+/* { dg-final { scan-assembler "\tcache\t0x18,20\\(\\\$4\\)" } } */
+/* { dg-final { scan-assembler "\tcache\t(0x|)0,0\\(\\\$.\\)" } } */
+/* { dg-final { scan-assembler "\tcache\t0x4,-80\\(\\\$4\\)" } } */
+