+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
/* 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);
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;
{
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;
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. */
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);
}
/* 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)
/* 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. */
"@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
(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
+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
--- /dev/null
+/* 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\\\]" } } */
--- /dev/null
+/* 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" } } */