aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorClaudiu Zissulescu <claziss@synopsys.com>2017-08-31 16:25:55 +0200
committerClaudiu Zissulescu <claziss@gcc.gnu.org>2017-08-31 16:25:55 +0200
commit9f532472da3e506db3609ebb03cff3d5f20f7353 (patch)
tree3f3874a38140210c975019239a1fa6b37d2220fe /gcc/config
parentb6fb793374fd887aee2b08b44145961b28533be2 (diff)
downloadgcc-9f532472da3e506db3609ebb03cff3d5f20f7353.zip
gcc-9f532472da3e506db3609ebb03cff3d5f20f7353.tar.gz
gcc-9f532472da3e506db3609ebb03cff3d5f20f7353.tar.bz2
[ARC] Use -G option to control sdata behavior
gcc/ 2017-04-24 Claudiu Zissulescu <claziss@synopsys.com> * config.gcc: Use g.opt for arc. * config/arc/arc.c (LEGITIMATE_SCALED_ADDRESS_P): Deleted, functionality moved to ... (legitimate_scaled_address_p): New function, ...here. (LEGITIMATE_SMALL_DATA_OFFSET_P): New define. (LEGITIMATE_SMALL_DATA_ADDRESS_P): Use the above define. (legitimate_offset_address_p): Delete TARGET_NO_SDATA_SET condition. (arc_override_options): Handle G option. (arc_output_pic_addr_const): Correct function definition. (arc_legitimate_address_p): Use legitimate_scaled_address_p. (arc_decl_anon_ns_mem_p): Delete. (arc_in_small_data_p): Overhaul this function to take into consideration the value given via G option. (arc_rewrite_small_data_1): Renamed and corrected old arc_rewrite_small_data function. (arc_rewrite_small_data): New function. (small_data_pattern): Don't use pic_offset_table_rtx. * config/arc/arc.h (CC1_SPEC): Recognize G option. * config/arc/simdext.md (movmisalignv2hi): Use prepare_move_operands function. (mov*): Likewise. (movmisalign*): Likewise. gcc/testsuite/ 2017-04-24 Claudiu Zissulescu <claziss@synopsys.com> * gcc.target/arc/sdata-5.c: New test. * gcc.target/arc/arc700-stld-hazard.c: Update test options. Fix test From-SVN: r251564
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/arc/arc.c236
-rw-r--r--gcc/config/arc/arc.h6
-rw-r--r--gcc/config/arc/simdext.md22
3 files changed, 142 insertions, 122 deletions
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index c77a818..4dcac18 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -79,26 +79,21 @@ static const char *arc_cpu_string = arc_cpu_name;
? 0 \
: -(-GET_MODE_SIZE (MODE) | -4) >> 1)))
-#define LEGITIMATE_SCALED_ADDRESS_P(MODE, X, STRICT) \
-(GET_CODE (X) == PLUS \
- && GET_CODE (XEXP (X, 0)) == MULT \
- && RTX_OK_FOR_INDEX_P (XEXP (XEXP (X, 0), 0), (STRICT)) \
- && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \
- && ((GET_MODE_SIZE (MODE) == 2 && INTVAL (XEXP (XEXP (X, 0), 1)) == 2) \
- || (GET_MODE_SIZE (MODE) == 4 && INTVAL (XEXP (XEXP (X, 0), 1)) == 4)) \
- && (RTX_OK_FOR_BASE_P (XEXP (X, 1), (STRICT)) \
- || (flag_pic ? CONST_INT_P (XEXP (X, 1)) : CONSTANT_P (XEXP (X, 1)))))
-
-#define LEGITIMATE_SMALL_DATA_ADDRESS_P(X) \
- (GET_CODE (X) == PLUS \
- && (REG_P (XEXP ((X), 0)) && REGNO (XEXP ((X), 0)) == SDATA_BASE_REGNUM) \
- && ((GET_CODE (XEXP((X),1)) == SYMBOL_REF \
- && SYMBOL_REF_SMALL_P (XEXP ((X), 1))) \
- || (GET_CODE (XEXP ((X), 1)) == CONST \
- && GET_CODE (XEXP (XEXP ((X), 1), 0)) == PLUS \
- && GET_CODE (XEXP (XEXP (XEXP ((X), 1), 0), 0)) == SYMBOL_REF \
- && SYMBOL_REF_SMALL_P (XEXP (XEXP (XEXP ((X), 1), 0), 0)) \
- && GET_CODE (XEXP(XEXP (XEXP ((X), 1), 0), 1)) == CONST_INT)))
+#define LEGITIMATE_SMALL_DATA_OFFSET_P(X) \
+ (GET_CODE (X) == CONST \
+ && GET_CODE (XEXP ((X), 0)) == PLUS \
+ && GET_CODE (XEXP (XEXP ((X), 0), 0)) == SYMBOL_REF \
+ && SYMBOL_REF_SMALL_P (XEXP (XEXP ((X), 0), 0)) \
+ && GET_CODE (XEXP(XEXP ((X), 0), 1)) == CONST_INT \
+ && INTVAL (XEXP (XEXP ((X), 0), 1)) <= g_switch_value)
+
+#define LEGITIMATE_SMALL_DATA_ADDRESS_P(X) \
+ (GET_CODE (X) == PLUS \
+ && REG_P (XEXP ((X), 0)) \
+ && REGNO (XEXP ((X), 0)) == SDATA_BASE_REGNUM \
+ && ((GET_CODE (XEXP ((X), 1)) == SYMBOL_REF \
+ && SYMBOL_REF_SMALL_P (XEXP ((X), 1))) \
+ || LEGITIMATE_SMALL_DATA_OFFSET_P (XEXP ((X), 1))))
/* Array of valid operand punctuation characters. */
char arc_punct_chars[256];
@@ -276,6 +271,61 @@ static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT,
/* Globally visible information about currently selected cpu. */
const arc_cpu_t *arc_selected_cpu;
+static bool
+legitimate_scaled_address_p (machine_mode mode, rtx op, bool strict)
+{
+ if (GET_CODE (op) != PLUS)
+ return false;
+
+ if (GET_CODE (XEXP (op, 0)) != MULT)
+ return false;
+
+ /* Check multiplication operands. */
+ if (!RTX_OK_FOR_INDEX_P (XEXP (XEXP (op, 0), 0), strict))
+ return false;
+
+ if (!CONST_INT_P (XEXP (XEXP (op, 0), 1)))
+ return false;
+
+ switch (GET_MODE_SIZE (mode))
+ {
+ case 2:
+ if (INTVAL (XEXP (XEXP (op, 0), 1)) != 2)
+ return false;
+ break;
+ case 8:
+ if (!TARGET_LL64)
+ return false;
+ /* Fall through. */
+ case 4:
+ if (INTVAL (XEXP (XEXP (op, 0), 1)) != 4)
+ return false;
+ default:
+ return false;
+ }
+
+ /* Check the base. */
+ if (RTX_OK_FOR_BASE_P (XEXP (op, 1), (strict)))
+ return true;
+
+ if (flag_pic)
+ {
+ if (CONST_INT_P (XEXP (op, 1)))
+ return true;
+ return false;
+ }
+ if (CONSTANT_P (XEXP (op, 1)))
+ {
+ /* Scalled addresses for sdata is done other places. */
+ if (GET_CODE (XEXP (op, 1)) == SYMBOL_REF
+ && SYMBOL_REF_SMALL_P (XEXP (op, 1)))
+ return false;
+ return true;
+ }
+
+ return false;
+}
+
/* Check for constructions like REG + OFFS, where OFFS can be a
register, an immediate or an long immediate. */
@@ -301,8 +351,7 @@ legitimate_offset_address_p (machine_mode mode, rtx x, bool index, bool strict)
&& (GET_MODE_SIZE (mode) <= 4)
/* Avoid small data which ends in something like GP +
symb@sda. */
- && (!SYMBOL_REF_SMALL_P (XEXP (x, 1))
- || TARGET_NO_SDATA_SET))
+ && (!SYMBOL_REF_SMALL_P (XEXP (x, 1))))
return true;
return false;
@@ -1117,6 +1166,10 @@ arc_override_options (void)
if (TARGET_COMPACT_CASESI)
TARGET_CASE_VECTOR_PC_RELATIVE = 1;
+ /* Check for small data option */
+ if (!global_options_set.x_g_switch_value && !TARGET_NO_SDATA_SET)
+ g_switch_value = TARGET_LL64 ? 8 : 4;
+
/* These need to be done at start up. It's convenient to do them here. */
arc_init ();
}
@@ -5422,7 +5475,7 @@ arc_legitimize_pic_address (rtx orig, rtx oldx)
/* Output address constant X to FILE, taking PIC into account. */
-void
+static void
arc_output_pic_addr_const (FILE * file, rtx x, int code)
{
char buf[256];
@@ -5871,7 +5924,7 @@ arc_legitimate_address_p (machine_mode mode, rtx x, bool strict)
return true;
if (legitimate_offset_address_p (mode, x, TARGET_INDEXED_LOADS, strict))
return true;
- if (LEGITIMATE_SCALED_ADDRESS_P (mode, x, strict))
+ if (legitimate_scaled_address_p (mode, x, strict))
return true;
if (LEGITIMATE_SMALL_DATA_ADDRESS_P (x))
return true;
@@ -7465,28 +7518,6 @@ valid_brcc_with_delay_p (rtx *operands)
return brcc_nolimm_operator (operands[0], VOIDmode);
}
-/* ??? Hack. This should no really be here. See PR32143. */
-static bool
-arc_decl_anon_ns_mem_p (const_tree decl)
-{
- while (1)
- {
- if (decl == NULL_TREE || decl == error_mark_node)
- return false;
- if (TREE_CODE (decl) == NAMESPACE_DECL
- && DECL_NAME (decl) == NULL_TREE)
- return true;
- /* Classes and namespaces inside anonymous namespaces have
- TREE_PUBLIC == 0, so we can shortcut the search. */
- else if (TYPE_P (decl))
- return (TREE_PUBLIC (TYPE_NAME (decl)) == 0);
- else if (TREE_CODE (decl) == NAMESPACE_DECL)
- return (TREE_PUBLIC (decl) == 0);
- else
- decl = DECL_CONTEXT (decl);
- }
-}
-
/* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
access DECL using %gp_rel(...)($gp). */
@@ -7495,60 +7526,43 @@ 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)
+ /* Only variables are going into small data area. */
+ if (TREE_CODE (decl) != VAR_DECL)
return false;
if (TARGET_NO_SDATA_SET)
return false;
- if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl) != 0)
- {
- const char *name;
-
- /* Reject anything that isn't in a known small-data section. */
- name = DECL_SECTION_NAME (decl);
- if (strcmp (name, ".sdata") != 0 && strcmp (name, ".sbss") != 0)
- return false;
-
- /* If a symbol is defined externally, the assembler will use the
- usual -G rules when deciding how to implement macros. */
- if (!DECL_EXTERNAL (decl))
- return true;
- }
- /* Only global variables go into sdata section for now. */
- else
- {
- /* Don't put constants into the small data section: we want them
- to be in ROM rather than RAM. */
- if (TREE_CODE (decl) != VAR_DECL)
- return false;
-
- if (TREE_READONLY (decl)
- && !TREE_SIDE_EFFECTS (decl)
- && (!DECL_INITIAL (decl) || TREE_CONSTANT (DECL_INITIAL (decl))))
- return false;
-
- /* TREE_PUBLIC might change after the first call, because of the patch
- for PR19238. */
- if (default_binds_local_p_1 (decl, 1)
- || arc_decl_anon_ns_mem_p (decl))
- return false;
-
- /* To ensure -mvolatile-cache works
- ld.di does not have a gp-relative variant. */
- if (TREE_THIS_VOLATILE (decl))
- return false;
- }
-
/* Disable sdata references to weak variables. */
if (DECL_WEAK (decl))
return false;
- size = int_size_in_bytes (TREE_TYPE (decl));
+ /* Don't put constants into the small data section: we want them to
+ be in ROM rather than RAM. */
+ if (TREE_READONLY (decl))
+ return false;
+
+ /* To ensure -mvolatile-cache works ld.di does not have a
+ gp-relative variant. */
+ if (!TARGET_VOLATILE_CACHE_SET
+ && TREE_THIS_VOLATILE (decl))
+ return false;
- /* Allow only <=4B long data types into sdata. */
- return (size > 0 && size <= 4);
+ if (DECL_SECTION_NAME (decl) != 0)
+ {
+ const char *name = DECL_SECTION_NAME (decl);
+ if (strcmp (name, ".sdata") == 0
+ || strcmp (name, ".sbss") == 0)
+ return true;
+ }
+ /* If it's not public, there's no need to put it in the small data
+ section. */
+ else if (TREE_PUBLIC (decl))
+ {
+ size = int_size_in_bytes (TREE_TYPE (decl));
+ return (size > 0 && size <= g_switch_value);
+ }
+ return false;
}
/* Return true if X is a small data address that can be rewritten
@@ -7577,9 +7591,10 @@ arc_rewrite_small_data_p (const_rtx x)
/* If possible, rewrite OP so that it refers to small data using
explicit relocations. */
-rtx
-arc_rewrite_small_data (rtx op)
+static rtx
+arc_rewrite_small_data_1 (rtx op)
{
+ rtx rgp = gen_rtx_REG (Pmode, SDATA_BASE_REGNUM);
op = copy_insn (op);
subrtx_ptr_iterator::array_type array;
FOR_EACH_SUBRTX_PTR (iter, array, &op, ALL)
@@ -7587,28 +7602,33 @@ arc_rewrite_small_data (rtx op)
rtx *loc = *iter;
if (arc_rewrite_small_data_p (*loc))
{
- gcc_assert (SDATA_BASE_REGNUM == PIC_OFFSET_TABLE_REGNUM);
- *loc = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, *loc);
- if (loc != &op)
- {
- if (GET_CODE (op) == MEM && &XEXP (op, 0) == loc)
- ; /* OK. */
- else if (GET_CODE (op) == MEM
- && GET_CODE (XEXP (op, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (op, 0), 0)) == MULT)
- *loc = force_reg (Pmode, *loc);
- else
- gcc_unreachable ();
- }
+ *loc = gen_rtx_PLUS (Pmode, rgp, *loc);
iter.skip_subrtxes ();
}
else if (GET_CODE (*loc) == PLUS
- && rtx_equal_p (XEXP (*loc, 0), pic_offset_table_rtx))
+ && rtx_equal_p (XEXP (*loc, 0), rgp))
iter.skip_subrtxes ();
}
return op;
}
+rtx
+arc_rewrite_small_data (rtx op)
+{
+ op = arc_rewrite_small_data_1 (op);
+
+ /* Check if we fit small data constraints. */
+ if (MEM_P (op)
+ && !LEGITIMATE_SMALL_DATA_ADDRESS_P (XEXP (op, 0)))
+ {
+ rtx addr = XEXP (op, 0);
+ rtx tmp = gen_reg_rtx (Pmode);
+ emit_move_insn (tmp, addr);
+ op = replace_equiv_address_nv (op, tmp);
+ }
+ return op;
+}
+
/* Return true if OP refers to small data symbols directly, not through
a PLUS. */
@@ -7617,12 +7637,14 @@ small_data_pattern (rtx op, machine_mode)
{
if (GET_CODE (op) == SEQUENCE)
return false;
+
+ rtx rgp = gen_rtx_REG (Pmode, SDATA_BASE_REGNUM);
subrtx_iterator::array_type array;
FOR_EACH_SUBRTX (iter, array, op, ALL)
{
const_rtx x = *iter;
if (GET_CODE (x) == PLUS
- && rtx_equal_p (XEXP (x, 0), pic_offset_table_rtx))
+ && rtx_equal_p (XEXP (x, 0), rgp))
iter.skip_subrtxes ();
else if (arc_rewrite_small_data_p (x))
return true;
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index 82cd0ad..2c06f9f 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -65,9 +65,9 @@ along with GCC; see the file COPYING3. If not see
%(subtarget_cpp_spec)"
#undef CC1_SPEC
-#define CC1_SPEC "\
-%{EB:%{EL:%emay not use both -EB and -EL}} \
-%{EB:-mbig-endian} %{EL:-mlittle-endian} \
+#define CC1_SPEC "%{EB:%{EL:%emay not use both -EB and -EL}} \
+%{EB:-mbig-endian} %{EL:-mlittle-endian} \
+%{G*} \
"
extern const char *arc_cpu_to_as (int argc, const char **argv);
diff --git a/gcc/config/arc/simdext.md b/gcc/config/arc/simdext.md
index 6c102d3..9f5b4a8 100644
--- a/gcc/config/arc/simdext.md
+++ b/gcc/config/arc/simdext.md
@@ -1383,19 +1383,18 @@
[(set (match_operand:V2HI 0 "general_operand" "")
(match_operand:V2HI 1 "general_operand" ""))]
""
-{
- if (!register_operand (operands[0], V2HImode)
- && !register_operand (operands[1], V2HImode))
- operands[1] = force_reg (V2HImode, operands[1]);
-})
+ "{
+ if (prepare_move_operands (operands, V2HImode))
+ DONE;
+ }")
(define_expand "mov<mode>"
[(set (match_operand:VWH 0 "move_dest_operand" "")
(match_operand:VWH 1 "general_operand" ""))]
""
"{
- if (GET_CODE (operands[0]) == MEM)
- operands[1] = force_reg (<MODE>mode, operands[1]);
+ if (prepare_move_operands (operands, <MODE>mode))
+ DONE;
}")
(define_insn_and_split "*mov<mode>_insn"
@@ -1440,11 +1439,10 @@
[(set (match_operand:VWH 0 "general_operand" "")
(match_operand:VWH 1 "general_operand" ""))]
""
-{
- if (!register_operand (operands[0], <MODE>mode)
- && !register_operand (operands[1], <MODE>mode))
- operands[1] = force_reg (<MODE>mode, operands[1]);
-})
+ "{
+ if (prepare_move_operands (operands, <MODE>mode))
+ DONE;
+ }")
(define_insn "bswapv2hi2"
[(set (match_operand:V2HI 0 "register_operand" "=r,r")