aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorClaudiu Zissulescu <claziss@synopsys.com>2017-08-31 15:52:31 +0200
committerClaudiu Zissulescu <claziss@gcc.gnu.org>2017-08-31 15:52:31 +0200
commitb6fb793374fd887aee2b08b44145961b28533be2 (patch)
tree79bcd5b426f24fa391f4e3f8e998c334ea950953 /gcc
parenta621861e39a42ee8b770d660b36041f2ac8bc4a4 (diff)
downloadgcc-b6fb793374fd887aee2b08b44145961b28533be2.zip
gcc-b6fb793374fd887aee2b08b44145961b28533be2.tar.gz
gcc-b6fb793374fd887aee2b08b44145961b28533be2.tar.bz2
[ARC] Improves and fixes for small data support.
Add alignment check for short load/store instructions used for sdata, as they request 32-bit aligned short immediate. Use sdata symbol alignment information and emit scalled loads/stores whenever is possible. The scalled address will extend the access range for sdata symbols. Allow 64-bit datum into small data section, if double load/store instructions are present. gcc/ 2017-04-12 Claudiu Zissulescu <claziss@synopsys.com> * config/arc/arc-protos.h (compact_sda_memory_operand): Update prototype. * config/arc/arc.c (arc_print_operand): Output scalled address for sdata whenever is possible. (arc_in_small_data_p): Allow sdata for 64bit datum when double load/stores are available. (compact_sda_memory_operand): Check for the alignment required by code density instructions. * config/arc/arc.md (movsi_insn): Use newly introduced Us0 constraint. * config/arc/constraints.md (Usd): Update constraint. (Us0): New constraint. (Usc): Update constraint. gcc/testsuite/ 2017-04-12 Claudiu Zissulescu <claziss@synopsys.com> * gcc.target/arc/sdata-3.c: New file. From-SVN: r251562
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/config/arc/arc-protos.h2
-rw-r--r--gcc/config/arc/arc.c64
-rw-r--r--gcc/config/arc/constraints.md4
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/arc/sdata-3.c32
-rw-r--r--gcc/testsuite/gcc.target/arc/sdata-4.c15
7 files changed, 126 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 175759c..f0be29f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,19 @@
+2017-08-31 Claudiu Zissulescu <claziss@synopsys.com>
+
+ * config/arc/arc-protos.h (compact_sda_memory_operand): Update
+ prototype.
+ * config/arc/arc.c (arc_print_operand): Output scalled address for
+ sdata whenever is possible.
+ (arc_in_small_data_p): Allow sdata for 64bit datum when double
+ load/stores are available.
+ (compact_sda_memory_operand): Check for the alignment required by
+ code density instructions.
+ * config/arc/arc.md (movsi_insn): Use newly introduced Us0
+ constraint.
+ * config/arc/constraints.md (Usd): Update constraint.
+ (Us0): New constraint.
+ (Usc): Update constraint.
+
2017-08-31 Richard Biener <rguenther@suse.de>
PR middle-end/82054
diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
index 8a9af46..1c7031c 100644
--- a/gcc/config/arc/arc-protos.h
+++ b/gcc/config/arc/arc-protos.h
@@ -27,7 +27,7 @@ extern struct rtx_def *gen_compare_reg (rtx, machine_mode);
/* Declarations for various fns used in the .md file. */
extern void arc_output_function_epilogue (FILE *, HOST_WIDE_INT, int);
extern const char *output_shift (rtx *);
-extern bool compact_sda_memory_operand (rtx op,machine_mode mode);
+extern bool compact_sda_memory_operand (rtx, machine_mode, bool);
extern bool arc_double_limm_p (rtx);
extern void arc_print_operand (FILE *, rtx, int);
extern void arc_print_operand_address (FILE *, rtx);
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 9b83a46..c77a818 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -3804,6 +3804,26 @@ arc_print_operand (FILE *file, rtx x, int code)
fputs (".as", file);
output_scaled = 1;
}
+ else if (LEGITIMATE_SMALL_DATA_ADDRESS_P (addr)
+ && GET_MODE_SIZE (GET_MODE (x)) > 1)
+ {
+ tree decl = NULL_TREE;
+ int align = 0;
+ if (GET_CODE (XEXP (addr, 1)) == SYMBOL_REF)
+ decl = SYMBOL_REF_DECL (XEXP (addr, 1));
+ else if (GET_CODE (XEXP (XEXP (XEXP (addr, 1), 0), 0))
+ == SYMBOL_REF)
+ decl = SYMBOL_REF_DECL (XEXP (XEXP (XEXP (addr, 1), 0), 0));
+ if (decl)
+ align = DECL_ALIGN (decl);
+ align = align / BITS_PER_UNIT;
+ if ((GET_MODE_SIZE (GET_MODE (x)) == 2)
+ && align && ((align & 1) == 0))
+ fputs (".as", file);
+ if ((GET_MODE_SIZE (GET_MODE (x)) >= 4)
+ && align && ((align & 3) == 0))
+ fputs (".as", file);
+ }
break;
case REG:
break;
@@ -7475,12 +7495,10 @@ arc_in_small_data_p (const_tree decl)
{
HOST_WIDE_INT size;
+ /* Strings and functions are never in small data area. */
if (TREE_CODE (decl) == STRING_CST || TREE_CODE (decl) == FUNCTION_DECL)
return false;
-
- /* We don't yet generate small-data references for -mabicalls. See related
- -G handling in override_options. */
if (TARGET_NO_SDATA_SET)
return false;
@@ -7499,7 +7517,7 @@ arc_in_small_data_p (const_tree decl)
return true;
}
/* Only global variables go into sdata section for now. */
- else if (1)
+ else
{
/* Don't put constants into the small data section: we want them
to be in ROM rather than RAM. */
@@ -7529,9 +7547,6 @@ arc_in_small_data_p (const_tree decl)
size = int_size_in_bytes (TREE_TYPE (decl));
-/* if (AGGREGATE_TYPE_P (TREE_TYPE (decl))) */
-/* return false; */
-
/* Allow only <=4B long data types into sdata. */
return (size > 0 && size <= 4);
}
@@ -7623,10 +7638,13 @@ small_data_pattern (rtx op, machine_mode)
/* volatile cache option still to be handled. */
bool
-compact_sda_memory_operand (rtx op, machine_mode mode)
+compact_sda_memory_operand (rtx op, machine_mode mode, bool short_p)
{
rtx addr;
int size;
+ tree decl = NULL_TREE;
+ int align = 0;
+ int mask = 0;
/* Eliminate non-memory operations. */
if (GET_CODE (op) != MEM)
@@ -7644,7 +7662,35 @@ compact_sda_memory_operand (rtx op, machine_mode mode)
/* Decode the address now. */
addr = XEXP (op, 0);
- return LEGITIMATE_SMALL_DATA_ADDRESS_P (addr);
+ if (!LEGITIMATE_SMALL_DATA_ADDRESS_P (addr))
+ return false;
+
+ if (!short_p || size == 1)
+ return true;
+
+ /* Now check for the alignment, the short loads using gp require the
+ addresses to be aligned. */
+ if (GET_CODE (XEXP (addr, 1)) == SYMBOL_REF)
+ decl = SYMBOL_REF_DECL (XEXP (addr, 1));
+ else if (GET_CODE (XEXP (XEXP (XEXP (addr, 1), 0), 0)) == SYMBOL_REF)
+ decl = SYMBOL_REF_DECL (XEXP (XEXP (XEXP (addr, 1), 0), 0));
+ if (decl)
+ align = DECL_ALIGN (decl);
+ align = align / BITS_PER_UNIT;
+
+ switch (mode)
+ {
+ case E_HImode:
+ mask = 1;
+ break;
+ default:
+ mask = 3;
+ break;
+ }
+
+ if (align && ((align & mask) == 0))
+ return true;
+ return false;
}
/* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */
diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md
index 6620daf..0ad318c 100644
--- a/gcc/config/arc/constraints.md
+++ b/gcc/config/arc/constraints.md
@@ -355,7 +355,7 @@
"@internal
A valid _small-data_ memory operand for ARCompact instructions"
(and (match_code "mem")
- (match_test "compact_sda_memory_operand (op, VOIDmode)")))
+ (match_test "compact_sda_memory_operand (op, VOIDmode, true)")))
(define_memory_constraint "Usc"
"@internal
@@ -363,7 +363,7 @@
(and (match_code "mem")
(match_test "!CONSTANT_P (XEXP (op,0))")
;; ??? the assembler rejects stores of immediates to small data.
- (match_test "!compact_sda_memory_operand (op, VOIDmode)")))
+ (match_test "!compact_sda_memory_operand (op, VOIDmode, false)")))
(define_constraint "Us<"
"@internal
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ff5169ae..9de87dd 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2017-08-31 Claudiu Zissulescu <claziss@synopsys.com>
+
+ * gcc.target/arc/sdata-3.c: New file.
+ * gcc.target/arc/sdata-4.c: Likewise.
+
2017-08-31 Richard Biener <rguenther@suse.de>
PR middle-end/82054
diff --git a/gcc/testsuite/gcc.target/arc/sdata-3.c b/gcc/testsuite/gcc.target/arc/sdata-3.c
new file mode 100644
index 0000000..cdf3b6d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/sdata-3.c
@@ -0,0 +1,32 @@
+/* Check if sdata access is done correctly, specially
+ for variables which are having a different alignment
+ than the default data type indicates. */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int g_a __attribute__ ((aligned (1)));
+int g_b;
+short g_c;
+char g_d;
+
+#define TEST(name, optype) \
+ void test_ ## name (optype x) \
+ { \
+ g_ ## name += x; \
+ }
+
+TEST (a, int)
+TEST (b, int)
+TEST (c, short)
+TEST (d, char)
+
+/* { dg-final { scan-assembler "ld r2,\\\[gp,@g_a@sda\\\]" } } */
+/* { dg-final { scan-assembler "ld.as r2,\\\[gp,@g_b@sda\\\]" } } */
+/* { dg-final { scan-assembler "ld\[hw\]\\\.as r2,\\\[gp,@g_c@sda\\\]" } } */
+/* { dg-final { scan-assembler "ldb r2,\\\[gp,@g_d@sda\\\]" } } */
+
+/* { dg-final { scan-assembler "st r0,\\\[gp,@g_a@sda\\\]" } } */
+/* { dg-final { scan-assembler "st_s r0,\\\[gp,@g_b@sda\\\]" { target { arcem || archs } } } } */
+/* { dg-final { scan-assembler "st\\\.as r0,\\\[gp,@g_b@sda\\\]" { target { arc700 || arc6xx } } } } */
+/* { dg-final { scan-assembler "st\[hw\]\\\.as r0,\\\[gp,@g_c@sda\\\]" } } */
+/* { dg-final { scan-assembler "stb r0,\\\[gp,@g_d@sda\\\]" } } */
diff --git a/gcc/testsuite/gcc.target/arc/sdata-4.c b/gcc/testsuite/gcc.target/arc/sdata-4.c
new file mode 100644
index 0000000..45fe712
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/sdata-4.c
@@ -0,0 +1,15 @@
+/* Check if sdata access is done correctly, specially
+ for variables which are having a different alignment
+ than the default data type indicates. */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+short gA __attribute__ ((aligned(1)));
+
+void foo (void)
+{
+ gA += gA + 3;
+}
+
+/* { dg-final { scan-assembler-not "ld\[wh\]_s r0,\\\[gp" } } */
+/* { dg-final { scan-assembler-not "st\[wh\]\\\.as.*gp" } } */