[cross-gcc] Enable libgcc building on cris [gcc BZ 61737].

David Howells dhowells at fedoraproject.org
Fri Jul 18 15:20:12 UTC 2014


commit aadca19142d5f293a72373bca23c953c7a9c9e1f
Author: David Howells <dhowells at redhat.com>
Date:   Fri Jul 18 16:10:51 2014 +0100

    Enable libgcc building on cris [gcc BZ 61737].

 cross-gcc-cris.patch        |  632 +++++++++++++++++++++++++++++++++++++++++++
 cross-gcc.spec              |   11 +-
 gcc49-tmake_in_config.patch |   13 -
 3 files changed, 639 insertions(+), 17 deletions(-)
---
diff --git a/cross-gcc-cris.patch b/cross-gcc-cris.patch
new file mode 100644
index 0000000..53db1c7
--- /dev/null
+++ b/cross-gcc-cris.patch
@@ -0,0 +1,632 @@
+2014-07-17  Hans-Peter Nilsson  <hp at axis.com>
+
+	Backport from trunk.
+	PR target/61737.
+	* config/cris/cris.c (TARGET_LEGITIMATE_CONSTANT_P)
+	(TARGET_CANNOT_FORCE_CONST_MEM): Define.
+	(cris_cannot_force_const_mem, cris_legitimate_constant_p): New
+	functions.
+	(cris_print_index, cris_print_operand, cris_constant_index_p)
+	(cris_side_effect_mode_ok): Replace CONSTANT_P with CRIS_CONSTANT_P.
+	(cris_address_cost): Ditto last CONSTANT_P.
+	(cris_symbol_type_of): Rename from cris_pic_symbol_type_of.  All
+        callers changed.  Yield cris_offsettable_symbol for non-PIC
+        constant symbolic expressions including labels.  Yield cris_unspec
+	for all unspecs.
+	(cris_expand_pic_call_address): New parameter MARKERP.  Set its
+        target to pic_offset_table_rtx for calls that will likely go
+        through PLT, const0_rtx when they can't.  All callers changed.
+	Assert flag_pic.  Use CONSTANT_P, not CONSTANT_ADDRESS_P, for
+	symbolic expressions to be PICified.  Remove second, redundant,
+	assert on can_create_pseudo_p returning non-zero.  Use
+	replace_equiv_address_nv, not replace_equiv_address, for final
+	operand update.
+	* config/cris/cris.md ("movsi"): Move variable t to pattern
+	toplevel. Adjust assert for new cris_symbol_type member.  Use
+	CONSTANT_P instead of CONSTANT_ADDRESS_P.
+	("*movsi_internal") <case 9>: Make check for valid unspec operands
+	for lapc stricter.
+	<case CRIS_UNSPEC_PCREL, CRIS_UNSPEC_PLT_PCREL>: Clear condition
+	codes.
+	("call", "call_value"): Use second incoming operand as a marker
+	for pic-offset-table-register being used.
+	("*expanded_call_non_v32", "*expanded_call_v32")
+        ("*expanded_call_value_non_v32", "*expanded_call_value_v32"): For
+	second incoming operand to CALL, match cris_call_type_marker.
+	("*expanded_call_value_side"): Ditto.  Disable before
+	reload_completed.
+	("*expanded_call_side"): Ditto.  Fix typo in comment.
+	(moverside, movemside peepholes): Check for CRIS_CONSTANT_P, not
+	CONSTANT_P.
+	* config/cris/predicates.md ("cris_call_type_marker"): New predicate.
+	* config/cris/cris.h (CRIS_CONSTANT_P): New macro.
+	(enum cris_symbol_type): Rename from cris_pic_symbol_type.  All
+        users changed.  Add members cris_offsettable_symbol and
+	cris_unspec.
+	(cris_symbol_type): Rename from cris_pic_symbol_type.
+	* config/cris/constraints.md ("T"): Use CRIS_CONSTANT_P, not
+        just CONSTANT_P.
+	* config/cris/cris-protos.h (cris_symbol_type_of,
+	cris_expand_pic_call_address): Adjust prototypes.
+	(cris_legitimate_constant_p): New prototype.
+
+	* config.gcc (crisv32-*-linux* | cris-*-linux*): Do not override
+	an existing tmake_file.  Don't add t-slibgcc and t-linux.
+
+diff --git a/gcc/config.gcc b/gcc/config.gcc
+index 63e1222..d526289 100644
+--- a/gcc/config.gcc
++++ b/gcc/config.gcc
+@@ -1129,8 +1129,7 @@ cris-*-elf | cris-*-none)
+ 	;;
+ crisv32-*-linux* | cris-*-linux*)
+ 	tm_file="dbxelf.h elfos.h ${tm_file} gnu-user.h linux.h glibc-stdint.h cris/linux.h"
+-	# We need to avoid using t-linux, so override default tmake_file
+-	tmake_file="cris/t-cris cris/t-linux t-slibgcc t-linux"
++	tmake_file="${tmake_file} cris/t-cris cris/t-linux"
+ 	extra_options="${extra_options} cris/linux.opt"
+ 	case $target in
+ 	  cris-*-*)
+diff --git a/gcc/config/cris/constraints.md b/gcc/config/cris/constraints.md
+index 651fbed..f927cca 100644
+--- a/gcc/config/cris/constraints.md
++++ b/gcc/config/cris/constraints.md
+@@ -118,7 +118,7 @@
+ 						       reload_in_progress
+ 						       || reload_completed)"))
+ 	    ;; Just an explicit indirect reference: [const]?
+-	    (match_test "CONSTANT_P (XEXP (op, 0))")
++	    (match_test "CRIS_CONSTANT_P (XEXP (op, 0))")
+ 	    ;; Something that is indexed; [...+...]?
+ 	    (and (match_code "plus" "0")
+ 		      ;; A BDAP constant: [reg+(8|16|32)bit offset]?
+@@ -159,6 +159,8 @@
+ (define_constraint "U"
+   "@internal"
+   (and (match_test "flag_pic")
++       ;; We're just interested in the ..._or_callable_symbol part.
++       ;; (Using CRIS_CONSTANT_P would exclude that too.)
+        (match_test "CONSTANT_P (op)")
+        (match_operand 0 "cris_nonmemory_operand_or_callable_symbol")))
+ 
+diff --git a/gcc/config/cris/cris-protos.h b/gcc/config/cris/cris-protos.h
+index 0fdcafe..b09babd 100644
+--- a/gcc/config/cris/cris-protos.h
++++ b/gcc/config/cris/cris-protos.h
+@@ -31,8 +31,9 @@ extern bool cris_cc0_user_requires_cmp (rtx);
+ extern rtx cris_return_addr_rtx (int, rtx);
+ extern rtx cris_split_movdx (rtx *);
+ extern int cris_legitimate_pic_operand (rtx);
+-extern enum cris_pic_symbol_type cris_pic_symbol_type_of (const_rtx);
++extern enum cris_symbol_type cris_symbol_type_of (const_rtx);
+ extern bool cris_valid_pic_const (const_rtx, bool);
++extern bool cris_legitimate_constant_p (enum machine_mode, rtx);
+ extern bool cris_constant_index_p (const_rtx);
+ extern bool cris_base_p (const_rtx, bool);
+ extern bool cris_base_or_autoincr_p (const_rtx, bool);
+@@ -46,7 +47,7 @@ extern int cris_cfun_uses_pic_table (void);
+ extern void cris_asm_output_case_end (FILE *, int, rtx);
+ extern rtx cris_gen_movem_load (rtx, rtx, int);
+ extern rtx cris_emit_movem_store (rtx, rtx, int, bool);
+-extern void cris_expand_pic_call_address (rtx *);
++extern void cris_expand_pic_call_address (rtx *, rtx *);
+ extern void cris_order_for_addsi3 (rtx *, int);
+ extern void cris_emit_trap_for_misalignment (rtx);
+ #endif /* RTX_CODE */
+diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c
+index 209f127..c15139f 100644
+--- a/gcc/config/cris/cris.c
++++ b/gcc/config/cris/cris.c
+@@ -147,6 +147,7 @@ static rtx cris_function_incoming_arg (cumulative_args_t,
+ static void cris_function_arg_advance (cumulative_args_t, enum machine_mode,
+ 				       const_tree, bool);
+ static tree cris_md_asm_clobbers (tree, tree, tree);
++static bool cris_cannot_force_const_mem (enum machine_mode, rtx);
+ 
+ static void cris_option_override (void);
+ 
+@@ -214,6 +215,9 @@ int cris_cpu_version = CRIS_DEFAULT_CPU_VERSION;
+ #undef TARGET_LEGITIMATE_ADDRESS_P
+ #define TARGET_LEGITIMATE_ADDRESS_P cris_legitimate_address_p
+ 
++#undef TARGET_LEGITIMATE_CONSTANT_P
++#define TARGET_LEGITIMATE_CONSTANT_P cris_legitimate_constant_p
++
+ #undef TARGET_PREFERRED_RELOAD_CLASS
+ #define TARGET_PREFERRED_RELOAD_CLASS cris_preferred_reload_class
+ 
+@@ -248,6 +252,10 @@ int cris_cpu_version = CRIS_DEFAULT_CPU_VERSION;
+ #define TARGET_FUNCTION_ARG_ADVANCE cris_function_arg_advance
+ #undef TARGET_MD_ASM_CLOBBERS
+ #define TARGET_MD_ASM_CLOBBERS cris_md_asm_clobbers
++
++#undef TARGET_CANNOT_FORCE_CONST_MEM
++#define TARGET_CANNOT_FORCE_CONST_MEM cris_cannot_force_const_mem
++
+ #undef TARGET_FRAME_POINTER_REQUIRED
+ #define TARGET_FRAME_POINTER_REQUIRED cris_frame_pointer_required
+ 
+@@ -506,6 +514,21 @@ cris_cfun_uses_pic_table (void)
+   return crtl->uses_pic_offset_table;
+ }
+ 
++/* Worker function for TARGET_CANNOT_FORCE_CONST_MEM.
++   We can't put PIC addresses in the constant pool, not even the ones that
++   can be reached as pc-relative as we can't tell when or how to do that.  */
++
++static bool
++cris_cannot_force_const_mem (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
++{
++  enum cris_symbol_type t = cris_symbol_type_of (x);
++
++  return
++    t == cris_unspec
++    || t == cris_got_symbol
++    || t == cris_rel_symbol;
++}
++
+ /* Given an rtx, return the text string corresponding to the CODE of X.
+    Intended for use in the assembly language output section of a
+    define_insn.  */
+@@ -601,7 +624,7 @@ cris_print_index (rtx index, FILE *file)
+ 
+   if (REG_P (index))
+     fprintf (file, "$%s.b", reg_names[REGNO (index)]);
+-  else if (CONSTANT_P (index))
++  else if (CRIS_CONSTANT_P (index))
+     cris_output_addr_const (file, index);
+   else if (GET_CODE (index) == MULT)
+     {
+@@ -1041,7 +1064,7 @@ cris_print_operand (FILE *file, rtx x, int code)
+       /* If this is a GOT symbol, force it to be emitted as :GOT and
+ 	 :GOTPLT regardless of -fpic (i.e. not as :GOT16, :GOTPLT16).
+ 	 Avoid making this too much of a special case.  */
+-      if (flag_pic == 1 && CONSTANT_P (operand))
++      if (flag_pic == 1 && CRIS_CONSTANT_P (operand))
+ 	{
+ 	  int flag_pic_save = flag_pic;
+ 
+@@ -1161,7 +1184,7 @@ cris_print_operand (FILE *file, rtx x, int code)
+     default:
+       /* No need to handle all strange variants, let output_addr_const
+ 	 do it for us.  */
+-      if (CONSTANT_P (operand))
++      if (CRIS_CONSTANT_P (operand))
+ 	{
+ 	  cris_output_addr_const (file, operand);
+ 	  return;
+@@ -1358,7 +1381,7 @@ reg_ok_for_index_p (const_rtx x, bool strict)
+ bool
+ cris_constant_index_p (const_rtx x)
+ {
+-  return (CONSTANT_P (x) && (!flag_pic || cris_valid_pic_const (x, true)));
++  return (CRIS_CONSTANT_P (x) && (!flag_pic || cris_valid_pic_const (x, true)));
+ }
+ 
+ /* True if X is a valid base register.  */
+@@ -1467,6 +1490,29 @@ cris_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
+   return false;
+ }
+ 
++/* Worker function for TARGET_LEGITIMATE_CONSTANT_P.  We have to handle
++   PIC constants that aren't legitimized.  FIXME: there used to be a
++   guarantee that the target LEGITIMATE_CONSTANT_P didn't have to handle
++   PIC constants, but no more (4.7 era); testcase: glibc init-first.c.
++   While that may be seen as a bug, that guarantee seems a wart by design,
++   so don't bother; fix the documentation instead.  */
++
++bool
++cris_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
++{
++  enum cris_symbol_type t;
++
++  if (flag_pic)
++    return LEGITIMATE_PIC_OPERAND_P (x);
++
++  t = cris_symbol_type_of (x);
++
++  return
++    t == cris_no_symbol
++    || t == cris_offsettable_symbol
++    || t == cris_unspec;
++}
++
+ /* Worker function for LEGITIMIZE_RELOAD_ADDRESS.  */
+ 
+ bool
+@@ -2214,7 +2260,7 @@ cris_address_cost (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED,
+ 	return (2 + 2) / 2;
+ 
+       /* A BDAP with some other constant is 2 bytes extra.  */
+-      if (CONSTANT_P (tem2))
++      if (CRIS_CONSTANT_P (tem2))
+ 	return (2 + 2 + 2) / 2;
+ 
+       /* BDAP with something indirect should have a higher cost than
+@@ -2312,7 +2358,7 @@ cris_side_effect_mode_ok (enum rtx_code code, rtx *ops,
+ 	return 0;
+ 
+       /* Check allowed cases, like [r(+)?].[bwd] and const.  */
+-      if (CONSTANT_P (val_rtx))
++      if (CRIS_CONSTANT_P (val_rtx))
+ 	return 1;
+ 
+       if (MEM_P (val_rtx)
+@@ -2464,32 +2510,34 @@ cris_valid_pic_const (const_rtx x, bool any_operand)
+ 	gcc_unreachable ();
+       }
+ 
+-  return cris_pic_symbol_type_of (x) == cris_no_symbol;
++  return cris_symbol_type_of (x) == cris_no_symbol;
+ }
+ 
+-/* Helper function to find the right PIC-type symbol to generate,
++/* Helper function to find the right symbol-type to generate,
+    given the original (non-PIC) representation.  */
+ 
+-enum cris_pic_symbol_type
+-cris_pic_symbol_type_of (const_rtx x)
++enum cris_symbol_type
++cris_symbol_type_of (const_rtx x)
+ {
+   switch (GET_CODE (x))
+     {
+     case SYMBOL_REF:
+-      return SYMBOL_REF_LOCAL_P (x)
+-	? cris_rel_symbol : cris_got_symbol;
++      return flag_pic
++	? (SYMBOL_REF_LOCAL_P (x)
++	   ? cris_rel_symbol : cris_got_symbol)
++	: cris_offsettable_symbol;
+ 
+     case LABEL_REF:
+-      return cris_rel_symbol;
++      return flag_pic ? cris_rel_symbol : cris_offsettable_symbol;
+ 
+     case CONST:
+-      return cris_pic_symbol_type_of (XEXP (x, 0));
++      return cris_symbol_type_of (XEXP (x, 0));
+ 
+     case PLUS:
+     case MINUS:
+       {
+-	enum cris_pic_symbol_type t1 = cris_pic_symbol_type_of (XEXP (x, 0));
+-	enum cris_pic_symbol_type t2 = cris_pic_symbol_type_of (XEXP (x, 1));
++	enum cris_symbol_type t1 = cris_symbol_type_of (XEXP (x, 0));
++	enum cris_symbol_type t2 = cris_symbol_type_of (XEXP (x, 1));
+ 
+ 	gcc_assert (t1 == cris_no_symbol || t2 == cris_no_symbol);
+ 
+@@ -2504,9 +2552,7 @@ cris_pic_symbol_type_of (const_rtx x)
+       return cris_no_symbol;
+ 
+     case UNSPEC:
+-      /* Likely an offsettability-test attempting to add a constant to
+-	 a GOTREAD symbol, which can't be handled.  */
+-      return cris_invalid_pic_symbol;
++      return cris_unspec;
+ 
+     default:
+       fatal_insn ("unrecognized supposed constant", x);
+@@ -3714,19 +3760,19 @@ cris_emit_movem_store (rtx dest, rtx nregs_rtx, int increment,
+ /* Worker function for expanding the address for PIC function calls.  */
+ 
+ void
+-cris_expand_pic_call_address (rtx *opp)
++cris_expand_pic_call_address (rtx *opp, rtx *markerp)
+ {
+   rtx op = *opp;
+ 
+-  gcc_assert (MEM_P (op));
++  gcc_assert (flag_pic && MEM_P (op));
+   op = XEXP (op, 0);
+ 
+   /* It might be that code can be generated that jumps to 0 (or to a
+      specific address).  Don't die on that.  (There is a
+      testcase.)  */
+-  if (CONSTANT_ADDRESS_P (op) && !CONST_INT_P (op))
++  if (CONSTANT_P (op) && !CONST_INT_P (op))
+     {
+-      enum cris_pic_symbol_type t = cris_pic_symbol_type_of (op);
++      enum cris_symbol_type t = cris_symbol_type_of (op);
+ 
+       CRIS_ASSERT (can_create_pseudo_p ());
+ 
+@@ -3752,18 +3798,21 @@ cris_expand_pic_call_address (rtx *opp)
+ 	    }
+ 	  else
+ 	    op = force_reg (Pmode, op);
++
++	  /* A local call.  */
++	  *markerp = const0_rtx;
+ 	}
+       else if (t == cris_got_symbol)
+ 	{
+ 	  if (TARGET_AVOID_GOTPLT)
+ 	    {
+ 	      /* Change a "jsr sym" into (allocate register rM, rO)
+-		 "move.d (const (unspec [sym rPIC] CRIS_UNSPEC_PLT_GOTREL)),rM"
++		 "move.d (const (unspec [sym] CRIS_UNSPEC_PLT_GOTREL)),rM"
+ 		 "add.d rPIC,rM,rO", "jsr rO" for pre-v32 and
+-		 "jsr (const (unspec [sym rPIC] CRIS_UNSPEC_PLT_PCREL))"
++		 "jsr (const (unspec [sym] CRIS_UNSPEC_PLT_PCREL))"
+ 		 for v32.  */
+ 	      rtx tem, rm, ro;
+-	      gcc_assert (can_create_pseudo_p ());
++
+ 	      crtl->uses_pic_offset_table = 1;
+ 	      tem = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op),
+ 				    TARGET_V32
+@@ -3817,14 +3866,27 @@ cris_expand_pic_call_address (rtx *opp)
+ 	      MEM_NOTRAP_P (mem) = 1;
+ 	      op = mem;
+ 	    }
++
++	  /* We need to prepare this call to go through the PLT; we
++	     need to make GOT available.  */
++	  *markerp = pic_offset_table_rtx;
+ 	}
+       else
+-	/* Can't possibly get a GOT-needing-fixup for a function-call,
+-	   right?  */
++	/* Can't possibly get anything else for a function-call, right?  */
+ 	fatal_insn ("unidentifiable call op", op);
+ 
+-      *opp = replace_equiv_address (*opp, op);
++      /* If the validizing variant is called, it will try to validize
++	 the address as a valid any-operand constant, but as it's only
++	 valid for calls and moves, it will fail and always be forced
++	 into a register.  */
++      *opp = replace_equiv_address_nv (*opp, op);
+     }
++  else
++    /* Can't tell what locality a call to a non-constant address has;
++       better make the GOT register alive at it.
++       FIXME: Can we see whether the register has known constant
++       contents?  */
++    *markerp = pic_offset_table_rtx;
+ }
+ 
+ /* Make sure operands are in the right order for an addsi3 insn as
+diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h
+index 37b562e..c5aa83e 100644
+--- a/gcc/config/cris/cris.h
++++ b/gcc/config/cris/cris.h
+@@ -794,6 +794,12 @@ struct cum_args {int regs;};
+     }									\
+   while (0)
+ 
++/* The mode argument to cris_legitimate_constant_p isn't used, so just
++   pass a cheap dummy.  N.B. we have to cast away const from the
++   parameter rather than adjust the parameter, as it's type is mandated
++   by the TARGET_LEGITIMATE_CONSTANT_P target hook interface.  */
++#define CRIS_CONSTANT_P(X) \
++  (CONSTANT_P (X) && cris_legitimate_constant_p (VOIDmode, CONST_CAST_RTX (X)))
+ 
+ /* Node: Condition Code */
+ 
+@@ -833,13 +839,14 @@ struct cum_args {int regs;};
+ 
+ /* Helper type.  */
+ 
+-enum cris_pic_symbol_type
++enum cris_symbol_type
+   {
+     cris_no_symbol = 0,
+     cris_got_symbol = 1,
+     cris_rel_symbol = 2,
+     cris_got_symbol_needing_fixup = 3,
+-    cris_invalid_pic_symbol = 4
++    cris_unspec = 7,
++    cris_offsettable_symbol = 8
+   };
+ 
+ #define PIC_OFFSET_TABLE_REGNUM (flag_pic ? CRIS_GOT_REGNUM : INVALID_REGNUM)
+diff --git a/gcc/config/cris/cris.md b/gcc/config/cris/cris.md
+index 47f6451..18b9787 100644
+--- a/gcc/config/cris/cris.md
++++ b/gcc/config/cris/cris.md
+@@ -919,6 +919,8 @@
+     (match_operand:SI 1 "cris_general_operand_or_symbol" ""))]
+   ""
+ {
++  enum cris_symbol_type t;
++
+   /* If the output goes to a MEM, make sure we have zero or a register as
+      input.  */
+   if (MEM_P (operands[0])
+@@ -934,12 +936,12 @@
+      valid symbol?  Can we exclude global PIC addresses with an added
+      offset?  */
+     if (flag_pic
+-	&& CONSTANT_ADDRESS_P (operands[1])
++	&& CONSTANT_P (operands[1])
+ 	&& !cris_valid_pic_const (operands[1], false))
+       {
+-	enum cris_pic_symbol_type t = cris_pic_symbol_type_of (operands[1]);
++	t = cris_symbol_type_of (operands[1]);
+ 
+-	gcc_assert (t != cris_no_symbol);
++	gcc_assert (t != cris_no_symbol && t != cris_offsettable_symbol);
+ 
+ 	if (! REG_S_P (operands[0]))
+ 	  {
+@@ -1086,7 +1088,12 @@
+ 	 if (!flag_pic
+ 	     && (GET_CODE (operands[1]) == SYMBOL_REF
+ 		 || GET_CODE (operands[1]) == LABEL_REF
+-		 || GET_CODE (operands[1]) == CONST))
++		 || (GET_CODE (operands[1]) == CONST
++		     && (GET_CODE (XEXP (operands[1], 0)) != UNSPEC
++			 || (XINT (XEXP (operands[1], 0), 1)
++			     == CRIS_UNSPEC_PLT_PCREL)
++			 || (XINT (XEXP (operands[1], 0), 1)
++			     == CRIS_UNSPEC_PCREL)))))
+ 	   {
+ 	     /* FIXME: Express this through (set_attr cc none) instead,
+ 		since we can't express the ``none'' at this point.  FIXME:
+@@ -1169,6 +1176,12 @@
+ 	  case CRIS_UNSPEC_PCREL:
+ 	  case CRIS_UNSPEC_PLT_PCREL:
+ 	    gcc_assert (TARGET_V32);
++	    /* LAPC doesn't set condition codes; clear them to make the
++	       (equivalence-marked) result of this insn not presumed
++	       present.  This instruction can be a PIC symbol load (for
++	       a hidden symbol) which for weak symbols will be followed
++	       by a test for NULL.  */
++	    CC_STATUS_INIT;
+ 	    return "lapc %1,%0";
+ 
+ 	  default:
+@@ -3710,15 +3723,16 @@
+ {
+   gcc_assert (MEM_P (operands[0]));
+   if (flag_pic)
+-    cris_expand_pic_call_address (&operands[0]);
++    cris_expand_pic_call_address (&operands[0], &operands[1]);
++  else
++    operands[1] = const0_rtx;
+ })
+ 
+-;; Accept *anything* as operand 1.  Accept operands for operand 0 in
+-;; order of preference.
++;; Accept operands for operand 0 in order of preference.
+ 
+ (define_insn "*expanded_call_non_v32"
+   [(call (mem:QI (match_operand:SI 0 "general_operand" "r,Q>,g"))
+-	 (match_operand 1 "" ""))
++	 (match_operand:SI 1 "cris_call_type_marker" "rM,rM,rM"))
+    (clobber (reg:SI CRIS_SRP_REGNUM))]
+   "!TARGET_V32"
+   "jsr %0")
+@@ -3727,7 +3741,7 @@
+   [(call
+     (mem:QI
+      (match_operand:SI 0 "cris_nonmemory_operand_or_callable_symbol" "n,r,U,i"))
+-    (match_operand 1 "" ""))
++    (match_operand:SI 1 "cris_call_type_marker" "rM,rM,rM,rM"))
+    (clobber (reg:SI CRIS_SRP_REGNUM))]
+   "TARGET_V32"
+   "@
+@@ -3740,19 +3754,21 @@
+ ;; Parallel when calculating and reusing address of indirect pointer
+ ;; with simple offset.  (Makes most sense with PIC.)  It looks a bit
+ ;; wrong not to have the clobber last, but that's the way combine
+-;; generates it (except it doesn' look into the *inner* mem, so this
++;; generates it (except it doesn't look into the *inner* mem, so this
+ ;; just matches a peephole2).  FIXME: investigate that.
+ (define_insn "*expanded_call_side"
+   [(call (mem:QI
+ 	  (mem:SI
+ 	   (plus:SI (match_operand:SI 0 "cris_bdap_operand" "%r,  r,r")
+ 		    (match_operand:SI 1 "cris_bdap_operand" "r>Rn,r,>Rn"))))
+-	 (match_operand 2 "" ""))
++	 (match_operand:SI 2 "cris_call_type_marker" "rM,rM,rM"))
+    (clobber (reg:SI CRIS_SRP_REGNUM))
+    (set (match_operand:SI 3 "register_operand" "=*0,r,r")
+ 	(plus:SI (match_dup 0)
+ 		 (match_dup 1)))]
+-  "!TARGET_AVOID_GOTPLT && !TARGET_V32"
++  ;; Disabled until after reload until we can avoid an output reload for
++  ;; operand 3 (being forbidden for call insns).
++  "reload_completed && !TARGET_AVOID_GOTPLT && !TARGET_V32"
+   "jsr [%3=%0%S1]")
+ 
+ (define_expand "call_value"
+@@ -3764,10 +3780,12 @@
+ {
+   gcc_assert (MEM_P (operands[1]));
+   if (flag_pic)
+-    cris_expand_pic_call_address (&operands[1]);
++    cris_expand_pic_call_address (&operands[1], &operands[2]);
++  else
++    operands[2] = const0_rtx;
+ })
+ 
+-;; Accept *anything* as operand 2.  The validity other than "general" of
++;; The validity other than "general" of
+ ;; operand 0 will be checked elsewhere.  Accept operands for operand 1 in
+ ;; order of preference (Q includes r, but r is shorter, faster).
+ ;;  We also accept a PLT symbol.  We output it as [rPIC+sym:GOTPLT] rather
+@@ -3776,7 +3794,7 @@
+ (define_insn "*expanded_call_value_non_v32"
+   [(set (match_operand 0 "nonimmediate_operand" "=g,g,g")
+ 	(call (mem:QI (match_operand:SI 1 "general_operand" "r,Q>,g"))
+-	      (match_operand 2 "" "")))
++	      (match_operand:SI 2 "cris_call_type_marker" "rM,rM,rM")))
+    (clobber (reg:SI CRIS_SRP_REGNUM))]
+   "!TARGET_V32"
+   "Jsr %1"
+@@ -3790,12 +3808,14 @@
+ 	  (mem:SI
+ 	   (plus:SI (match_operand:SI 1 "cris_bdap_operand" "%r,  r,r")
+ 		    (match_operand:SI 2 "cris_bdap_operand" "r>Rn,r,>Rn"))))
+-	      (match_operand 3 "" "")))
++	 (match_operand:SI 3 "cris_call_type_marker" "rM,rM,rM")))
+    (clobber (reg:SI CRIS_SRP_REGNUM))
+    (set (match_operand:SI 4 "register_operand" "=*1,r,r")
+ 	(plus:SI (match_dup 1)
+ 		 (match_dup 2)))]
+-  "!TARGET_AVOID_GOTPLT && !TARGET_V32"
++  ;; Disabled until after reload until we can avoid an output reload for
++  ;; operand 4 (being forbidden for call insns).
++  "reload_completed && !TARGET_AVOID_GOTPLT && !TARGET_V32"
+   "Jsr [%4=%1%S2]"
+   [(set_attr "cc" "clobber")])
+ 
+@@ -3805,7 +3825,7 @@
+     (call
+      (mem:QI
+       (match_operand:SI 1 "cris_nonmemory_operand_or_callable_symbol" "n,r,U,i"))
+-     (match_operand 2 "" "")))
++     (match_operand:SI 2 "cris_call_type_marker" "rM,rM,rM,rM")))
+    (clobber (reg:SI 16))]
+   "TARGET_V32"
+   "@
+@@ -4827,7 +4847,7 @@
+   /* Make sure we have canonical RTX so we match the insn pattern -
+      not a constant in the first operand.  We also require the order
+      (plus reg mem) to match the final pattern.  */
+-  if (CONSTANT_P (otherop) || MEM_P (otherop))
++  if (CRIS_CONSTANT_P (otherop) || MEM_P (otherop))
+     {
+       operands[7] = operands[1];
+       operands[8] = otherop;
+@@ -4878,7 +4898,7 @@
+   /* Make sure we have canonical RTX so we match the insn pattern -
+      not a constant in the first operand.  We also require the order
+      (plus reg mem) to match the final pattern.  */
+-  if (CONSTANT_P (otherop) || MEM_P (otherop))
++  if (CRIS_CONSTANT_P (otherop) || MEM_P (otherop))
+     {
+       operands[7] = operands[1];
+       operands[8] = otherop;
+diff --git a/gcc/config/cris/predicates.md b/gcc/config/cris/predicates.md
+index 0169b0b..ddb090e 100644
+--- a/gcc/config/cris/predicates.md
++++ b/gcc/config/cris/predicates.md
+@@ -142,7 +142,7 @@
+   (ior (match_operand 0 "general_operand")
+        (and (match_code "const, symbol_ref, label_ref")
+        	    ; The following test is actually just an assertion.
+-	    (match_test "cris_pic_symbol_type_of (op) != cris_no_symbol"))))
++	    (match_test "cris_symbol_type_of (op) != cris_no_symbol"))))
+ 
+ ;; A predicate for the anon movsi expansion, one that fits a PCREL
+ ;; operand as well as general_operand.
+@@ -176,3 +176,15 @@
+        (ior (match_operand 0 "memory_operand")
+ 	    (match_test "cris_general_operand_or_symbol (XEXP (op, 0),
+ 							 Pmode)"))))
++
++;; A marker for the call-insn: (const_int 0) for a call to a
++;; hidden or static function and non-pic and
++;; pic_offset_table_rtx for a call that *might* go through the
++;; PLT.
++
++(define_predicate "cris_call_type_marker"
++  (ior (and (match_operand 0 "const_int_operand")
++	    (match_test "op == const0_rtx"))
++       (and (and (match_operand 0 "register_operand")
++		 (match_test "op == pic_offset_table_rtx"))
++	    (match_test "flag_pic != 0"))))
diff --git a/cross-gcc.spec b/cross-gcc.spec
index 2f072db..fffd1bb 100644
--- a/cross-gcc.spec
+++ b/cross-gcc.spec
@@ -56,7 +56,7 @@
 %global multilib_64_archs sparc64 ppc64 s390x x86_64
 
 # we won't build libgcc for these as it depends on C library or kernel headers
-%define no_libgcc_targets	cris*|sh*|tile-*
+%define no_libgcc_targets	sh*|tile-*
 
 ###############################################################################
 #
@@ -72,7 +72,7 @@
 # line.  gcc_release is the Fedora gcc release that the patches were
 # taken from.
 %global gcc_release 14
-%global cross_gcc_release 3
+%global cross_gcc_release 4
 %global cross_binutils_version 2.24-2
 
 Summary: Cross C compiler
@@ -120,7 +120,7 @@ Patch100: cross-intl-filename.patch
 # alpha - http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55344
 Patch101: cross-gcc-with-libgcc.patch
 Patch102: cross-gcc-sh-libgcc.patch
-Patch103: gcc49-tmake_in_config.patch
+Patch103: cross-gcc-cris.patch
 Patch104: cross-gcc-bfin.patch
 Patch105: cross-gcc-c6x.patch
 
@@ -285,7 +285,7 @@ rm -f libgo/go/crypto/elliptic/p224{,_test}.go
 %patch100 -p0 -b .cross-intl~
 %patch101 -p1 -b .with-libgcc~
 %patch102 -p0 -b .sh-libgcc~
-%patch103 -p0 -b .tmake~
+%patch103 -p1 -b .cris~
 %patch104 -p0 -b .bfin~
 %patch105 -p0 -b .c6x~
 
@@ -866,6 +866,9 @@ rm -rf %{buildroot}
 %do_files xtensa-linux-gnu	%{build_xtensa}
 
 %changelog
+* Fri Jul 18 2014 David Howells <dhowells at redhat.com> - 4.9.0-4
+- Enable libgcc building on cris [gcc BZ 61737].
+
 * Mon Jul 7 2014 David Howells <dhowells at redhat.com> - 4.9.0-3
 - Enable libgcc building on s390x [BZ 1116185].
 


More information about the scm-commits mailing list