The -mno-code-density flag was not working correctly on ARCv2 EM, causing
compact load/store instructions (ld_s, st_s, ldb_s, ldh_s, stb_s, sth_s) to
still be generated even when code density was explicitly disabled.
The memory constraints T, S, Uts, Ucd, and Usd control when compact instructions
can be used. Compact instructions are always available on ARCv1 (ARC600/ARC700)
and ARCv2 HS (cannot be disabled), but on ARCv2 EM they can be toggled with the
-mcode-density flag.
This patch adds (!TARGET_V2 || TARGET_CODE_DENSITY) checks to constraints T, S,
Uts, and Usd, enabling them unconditionally on ARCv1 and conditionally on ARCv2.
Constraint Ucd now uses (TARGET_V2 && TARGET_CODE_DENSITY) for ARCv2-specific
code density addressing.
gcc/ChangeLog:
* config/arc/constraints.md (T): Add TARGET_V2 and
TARGET_CODE_DENSITY check to constraint condition.
(S): Likewise.
(Usd): Likewise.
(Uts): Add TARGET_V2 check to allow constraint on ARC600/ARC700,
and pass true instead of TARGET_CODE_DENSITY to
compact_memory_operand_p.
(Ucd): Add TARGET_CODE_DENSITY check to constraint condition.
gcc/testsuite/ChangeLog:
* gcc.target/arc/sdata-6.c: Update patterns to accept both
compact and non-compact instruction variants, as base mcpu=em
does not enable code density by default.
* gcc.target/arc/code-density-ld-1.c: New test.
* gcc.target/arc/code-density-ld-2.c: New test.
* gcc.target/arc/code-density-ld-3.c: New test.
* gcc.target/arc/code-density-ldb-ldh-1.c: New test.
* gcc.target/arc/code-density-st-1.c: New test.
* gcc.target/arc/code-density-st-2.c: New test.
* gcc.target/arc/code-density-st-3.c: New test.
* gcc.target/arc/code-density-stb-sth-1.c: New test.
Signed-off-by: Luis Silva <[email protected]>
---
gcc/config/arc/constraints.md | 8 ++++--
.../gcc.target/arc/code-density-ld-1.c | 26 ++++++++++++++++++
.../gcc.target/arc/code-density-ld-2.c | 27 +++++++++++++++++++
.../gcc.target/arc/code-density-ld-3.c | 18 +++++++++++++
.../gcc.target/arc/code-density-ldb-ldh-1.c | 22 +++++++++++++++
.../gcc.target/arc/code-density-st-1.c | 26 ++++++++++++++++++
.../gcc.target/arc/code-density-st-2.c | 27 +++++++++++++++++++
.../gcc.target/arc/code-density-st-3.c | 18 +++++++++++++
.../gcc.target/arc/code-density-stb-sth-1.c | 23 ++++++++++++++++
gcc/testsuite/gcc.target/arc/sdata-6.c | 4 +--
10 files changed, 195 insertions(+), 4 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/arc/code-density-ld-1.c
create mode 100644 gcc/testsuite/gcc.target/arc/code-density-ld-2.c
create mode 100644 gcc/testsuite/gcc.target/arc/code-density-ld-3.c
create mode 100644 gcc/testsuite/gcc.target/arc/code-density-ldb-ldh-1.c
create mode 100644 gcc/testsuite/gcc.target/arc/code-density-st-1.c
create mode 100644 gcc/testsuite/gcc.target/arc/code-density-st-2.c
create mode 100644 gcc/testsuite/gcc.target/arc/code-density-st-3.c
create mode 100644 gcc/testsuite/gcc.target/arc/code-density-stb-sth-1.c
diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md
index e2becdc43d6..2a8f0f5697b 100644
--- a/gcc/config/arc/constraints.md
+++ b/gcc/config/arc/constraints.md
@@ -292,18 +292,21 @@
"@internal
A valid memory operand for ARCompact load instructions"
(and (match_code "mem")
+ (match_test "!TARGET_V2 || TARGET_CODE_DENSITY")
(match_test "compact_memory_operand_p (op, mode, false, false)")))
(define_memory_constraint "Uts"
"@internal
A valid memory operand for ARCompact load instructions scaled"
(and (match_code "mem")
- (match_test "compact_memory_operand_p (op, mode, false,
TARGET_CODE_DENSITY)")))
+ (match_test "!TARGET_V2 || TARGET_CODE_DENSITY")
+ (match_test "compact_memory_operand_p (op, mode, false, true)")))
(define_memory_constraint "S"
"@internal
A valid memory operand for ARCompact store instructions"
(and (match_code "mem")
+ (match_test "!TARGET_V2 || TARGET_CODE_DENSITY")
(match_test "compact_store_memory_operand (op, VOIDmode)")))
(define_memory_constraint "Uex"
@@ -317,6 +320,7 @@
"@internal
A valid _small-data_ memory operand for ARCompact instructions"
(and (match_code "mem")
+ (match_test "!TARGET_V2 || TARGET_CODE_DENSITY")
(match_test "compact_sda_memory_operand (op, VOIDmode, true)")))
; Usc constant is only used for storing long constants, hence we can
@@ -479,7 +483,7 @@
A valid memory operand for use with code density load ops"
(and (match_code "mem")
(match_test "compact_memory_operand_p (op, mode, true, false)")
- (match_test "TARGET_V2")))
+ (match_test "TARGET_V2 && TARGET_CODE_DENSITY")))
(define_register_constraint "h"
"TARGET_V2 ? AC16_H_REGS : NO_REGS"
diff --git a/gcc/testsuite/gcc.target/arc/code-density-ld-1.c
b/gcc/testsuite/gcc.target/arc/code-density-ld-1.c
new file mode 100644
index 00000000000..569b733a318
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/code-density-ld-1.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target codedensity } */
+/* { dg-options "-Os" } */
+
+volatile int *p = (int *)0xa30000;
+
+int
+test_ld_s_volatile (void)
+{
+ return *p;
+}
+
+int
+test_ld_s_array (void)
+{
+ int arr[10] = {0};
+ return arr[2];
+}
+
+int
+test_ld_s_pointer (int *ptr)
+{
+ return *ptr;
+}
+
+/* { dg-final { scan-assembler "ld_s\\s+r\[0-9\]" } } */
diff --git a/gcc/testsuite/gcc.target/arc/code-density-ld-2.c
b/gcc/testsuite/gcc.target/arc/code-density-ld-2.c
new file mode 100644
index 00000000000..a7b02b44073
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/code-density-ld-2.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arcem } */
+/* { dg-options "-Os -mno-code-density" } */
+
+volatile int *p = (int *)0xa30000;
+
+int
+test_no_ld_s_volatile (void)
+{
+ return *p;
+}
+
+int
+test_no_ld_s_array (void)
+{
+ int arr[10] = {0};
+ return arr[2];
+}
+
+int
+test_no_ld_s_pointer (int *ptr)
+{
+ return *ptr;
+}
+
+/* { dg-final { scan-assembler-not "ld_s\\s+r\[0-9\]" } } */
+/* { dg-final { scan-assembler "ld\\s+r\[0-9\]" } } */
diff --git a/gcc/testsuite/gcc.target/arc/code-density-ld-3.c
b/gcc/testsuite/gcc.target/arc/code-density-ld-3.c
new file mode 100644
index 00000000000..82647dc8e01
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/code-density-ld-3.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { ! { arc6xx || arc700 } } } */
+/* { dg-options "-Os" } */
+
+int
+test_ld_s_arcv1_array (void)
+{
+ int arr[10] = {0};
+ return arr[2];
+}
+
+int
+test_ld_s_arcv1_pointer (int *ptr)
+{
+ return *ptr;
+}
+
+/* { dg-final { scan-assembler "ld_s\\s+r\[0-9\]" } } */
diff --git a/gcc/testsuite/gcc.target/arc/code-density-ldb-ldh-1.c
b/gcc/testsuite/gcc.target/arc/code-density-ldb-ldh-1.c
new file mode 100644
index 00000000000..1daf3b117aa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/code-density-ldb-ldh-1.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arcem } */
+/* { dg-options "-Os -mno-code-density" } */
+
+char
+test_no_ldb_s (void)
+{
+ char arr[10];
+ return arr[2];
+}
+
+short
+test_no_ldh_s (void)
+{
+ short arr[10];
+ return arr[2];
+}
+
+/* { dg-final { scan-assembler-not "ldb_s\\s+r\[0-9\]" } } */
+/* { dg-final { scan-assembler-not "ldh_s\\s+r\[0-9\]" } } */
+/* { dg-final { scan-assembler "ldb\\s+r\[0-9\]" } } */
+/* { dg-final { scan-assembler "ldh(\\.x)?\\s+r\[0-9\]" } } */
diff --git a/gcc/testsuite/gcc.target/arc/code-density-st-1.c
b/gcc/testsuite/gcc.target/arc/code-density-st-1.c
new file mode 100644
index 00000000000..74f9aa15021
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/code-density-st-1.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target codedensity } */
+/* { dg-options "-Os" } */
+
+volatile int *p = (int *)0xa30000;
+
+void
+test_st_s_volatile (int val)
+{
+ *p = val;
+}
+
+void
+test_st_s_array (int val)
+{
+ int arr[10];
+ arr[2] = val;
+}
+
+void
+test_st_s_pointer (int *ptr, int val)
+{
+ *ptr = val;
+}
+
+/* { dg-final { scan-assembler "st_s\\s+r\[0-9\]" } } */
diff --git a/gcc/testsuite/gcc.target/arc/code-density-st-2.c
b/gcc/testsuite/gcc.target/arc/code-density-st-2.c
new file mode 100644
index 00000000000..1f76d5c1e1b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/code-density-st-2.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arcem } */
+/* { dg-options "-Os -mno-code-density" } */
+
+volatile int *p = (int *)0xa30000;
+
+void
+test_no_st_s_volatile (int val)
+{
+ *p = val;
+}
+
+void
+test_no_st_s_array (int val)
+{
+ int arr[10];
+ arr[2] = val;
+}
+
+void
+test_no_st_s_pointer (int *ptr, int val)
+{
+ *ptr = val;
+}
+
+/* { dg-final { scan-assembler-not "st_s\\s+r\[0-9\]" } } */
+/* { dg-final { scan-assembler "st\\s+r\[0-9\]" } } */
diff --git a/gcc/testsuite/gcc.target/arc/code-density-st-3.c
b/gcc/testsuite/gcc.target/arc/code-density-st-3.c
new file mode 100644
index 00000000000..6968de658c8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/code-density-st-3.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { ! { arc6xx || arc700 } } } */
+/* { dg-options "-Os" } */
+
+void
+test_st_s_arcv1_array (int val)
+{
+ int arr[10];
+ arr[2] = val;
+}
+
+void
+test_st_s_arcv1_pointer (int *ptr, int val)
+{
+ *ptr = val;
+}
+
+/* { dg-final { scan-assembler "st_s\\s+r\[0-9\]" } } */
diff --git a/gcc/testsuite/gcc.target/arc/code-density-stb-sth-1.c
b/gcc/testsuite/gcc.target/arc/code-density-stb-sth-1.c
new file mode 100644
index 00000000000..adbc73fc3f3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/code-density-stb-sth-1.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arcem } */
+/* { dg-options "-Os -mno-code-density" } */
+
+volatile char vchar;
+volatile short vshort;
+
+void
+test_no_stb_s (char x)
+{
+ vchar = x;
+}
+
+void
+test_no_sth_s (short x)
+{
+ vshort = x;
+}
+
+/* { dg-final { scan-assembler-not "stb_s\\s+r\[0-9\]" } } */
+/* { dg-final { scan-assembler-not "sth_s\\s+r\[0-9\]" } } */
+/* { dg-final { scan-assembler "stb\\s+r\[0-9\]" } } */
+/* { dg-final { scan-assembler "sth(\\.as)?\\s+r\[0-9\]" } } */
diff --git a/gcc/testsuite/gcc.target/arc/sdata-6.c
b/gcc/testsuite/gcc.target/arc/sdata-6.c
index 2be261790a9..c056ad47dfb 100644
--- a/gcc/testsuite/gcc.target/arc/sdata-6.c
+++ b/gcc/testsuite/gcc.target/arc/sdata-6.c
@@ -28,7 +28,7 @@ TEST (short, 255)
TEST (int, 255)
TEST (int64_t, 127)
-/* { dg-final { scan-assembler "ldb_s\\s+r0,\\\[gp,@a@sda\\+255\\\]" } } */
+/* { dg-final { scan-assembler "ldb(_s)?\\s+r0,\\\[gp,@a@sda\\+255\\\]" } } */
/* { dg-final { scan-assembler "ldb\\s+r0,\\\[@a\\+256\\\]" } } */
/* { dg-final { scan-assembler "ldb\\s+r4,\\\[gp,@a@sda\\+255\\\]" } } */
/* { dg-final { scan-assembler "ldb\\s+r4,\\\[@a\\+256\\\]" } } */
@@ -38,7 +38,7 @@ TEST (int64_t, 127)
/* { dg-final { scan-assembler "ld\[hw\].x.as\\s+r4,\\\[gp,@a@sda\\+510\\\]" }
} */
/* { dg-final { scan-assembler "ld\[hw\].x\\s+r4,\\\[@a\\+512\\\]" } } */
-/* { dg-final { scan-assembler "ld_s\\s+r0,\\\[gp,@a@sda\\+1020\\\]" } } */
+/* { dg-final { scan-assembler "ld(_s|\\.as)?\\s+r0,\\\[gp,@a@sda\\+1020\\\]"
} } */
/* { dg-final { scan-assembler "ld\\s+r0,\\\[@a\\+1024\\\]" } } */
/* { dg-final { scan-assembler "ld.as\\s+r4,\\\[gp,@a@sda\\+1020\\\]" } } */
/* { dg-final { scan-assembler "ld\\s+r4,\\\[@a\\+1024\\\]" } } */
--
2.34.0