[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
This commit is contained in:
parent
a621861e39
commit
b6fb793374
7 changed files with 126 additions and 12 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
32
gcc/testsuite/gcc.target/arc/sdata-3.c
Normal file
32
gcc/testsuite/gcc.target/arc/sdata-3.c
Normal file
|
@ -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\\\]" } } */
|
15
gcc/testsuite/gcc.target/arc/sdata-4.c
Normal file
15
gcc/testsuite/gcc.target/arc/sdata-4.c
Normal file
|
@ -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" } } */
|
Loading…
Add table
Reference in a new issue