This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[m68k] pass --pcrel to assembler


We discovered that the linux and uclinux m68k configs were not passing --pcrel to the assembler when generating PIC, sep-data or id-shared-lib code. This lead to non-PIC relocations being used for assembly inserts, assembly source files and out-of-range branch fixups on ISA C.

This patch fixes the driver to pass --pcrel, ok?

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

Index: config-ml.in
===================================================================
--- config-ml.in	(revision 123987)
+++ config-ml.in	(working copy)
@@ -789,11 +789,11 @@ if [ -n "${multidirs}" ] && [ -z "${ml_n
     ml_config_env='CC="${CC_}$flags" CXX="${CXX_}$flags" F77="${F77_}$flags" GCJ="${GCJ_}$flags" GFORTRAN="${GFORTRAN_}$flags"'
 
     if [ "${with_target_subdir}" = "." ]; then
-	CC_=$CC' '
-	CXX_=$CXX' '
-	F77_=$F77' '
-	GCJ_=$GCJ' '
-	GFORTRAN_=$GFORTRAN' '
+	CC_=$CC
+	CXX_=$CXX
+	F77_=$F77
+	GCJ_=$GCJ
+	GFORTRAN_=$GFORTRAN
     else
 	# Create a regular expression that matches any string as long
 	# as ML_POPDIR.
@@ -802,11 +802,11 @@ if [ -n "${multidirs}" ] && [ -z "${ml_n
 	for arg in ${CC}; do
 	  case $arg in
 	  -[BIL]"${ML_POPDIR}"/*)
-	    CC_="${CC_}"`echo "X${arg}" | sed -n "s/X\\(-[BIL]${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X-[BIL]${popdir_rx}\\(.*\\)/\1/p"`' ' ;;
+	    CC_="${CC_} "`echo "X${arg}" | sed -n "s/X\\(-[BIL]${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X-[BIL]${popdir_rx}\\(.*\\)/\1/p"` ;;
 	  "${ML_POPDIR}"/*)
-	    CC_="${CC_}"`echo "X${arg}" | sed -n "s/X\\(${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X${popdir_rx}\\(.*\\)/\\1/p"`' ' ;;
+	    CC_="${CC_} "`echo "X${arg}" | sed -n "s/X\\(${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X${popdir_rx}\\(.*\\)/\\1/p"` ;;
 	  *)
-	    CC_="${CC_}${arg} " ;;
+	    CC_="${CC_} ${arg}" ;;
 	  esac
 	done
 
@@ -814,11 +814,11 @@ if [ -n "${multidirs}" ] && [ -z "${ml_n
 	for arg in ${CXX}; do
 	  case $arg in
 	  -[BIL]"${ML_POPDIR}"/*)
-	    CXX_="${CXX_}"`echo "X${arg}" | sed -n "s/X\\(-[BIL]${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X-[BIL]${popdir_rx}\\(.*\\)/\\1/p"`' ' ;;
+	    CXX_="${CXX_} "`echo "X${arg}" | sed -n "s/X\\(-[BIL]${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X-[BIL]${popdir_rx}\\(.*\\)/\\1/p"` ;;
 	  "${ML_POPDIR}"/*)
-	    CXX_="${CXX_}"`echo "X${arg}" | sed -n "s/X\\(${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X${popdir_rx}\\(.*\\)/\\1/p"`' ' ;;
+	    CXX_="${CXX_} "`echo "X${arg}" | sed -n "s/X\\(${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X${popdir_rx}\\(.*\\)/\\1/p"` ;;
 	  *)
-	    CXX_="${CXX_}${arg} " ;;
+	    CXX_="${CXX_} ${arg}" ;;
 	  esac
 	done
 
@@ -826,11 +826,11 @@ if [ -n "${multidirs}" ] && [ -z "${ml_n
 	for arg in ${F77}; do
 	  case $arg in
 	  -[BIL]"${ML_POPDIR}"/*)
-	    F77_="${F77_}"`echo "X${arg}" | sed -n "s/X\\(-[BIL]${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X-[BIL]${popdir_rx}\\(.*\\)/\\1/p"`' ' ;;
+	    F77_="${F77_} "`echo "X${arg}" | sed -n "s/X\\(-[BIL]${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X-[BIL]${popdir_rx}\\(.*\\)/\\1/p"` ;;
 	  "${ML_POPDIR}"/*)
-	    F77_="${F77_}"`echo "X${arg}" | sed -n "s/X\\(${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X${popdir_rx}\\(.*\\)/\\1/p"`' ' ;;
+	    F77_="${F77_} "`echo "X${arg}" | sed -n "s/X\\(${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X${popdir_rx}\\(.*\\)/\\1/p"` ;;
 	  *)
-	    F77_="${F77_}${arg} " ;;
+	    F77_="${F77_} ${arg}" ;;
 	  esac
 	done
 
@@ -838,11 +838,11 @@ if [ -n "${multidirs}" ] && [ -z "${ml_n
 	for arg in ${GCJ}; do
 	  case $arg in
 	  -[BIL]"${ML_POPDIR}"/*)
-	    GCJ_="${GCJ_}"`echo "X${arg}" | sed -n "s/X\\(-[BIL]${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X-[BIL]${popdir_rx}\\(.*\\)/\\1/p"`' ' ;;
+	    GCJ_="${GCJ_} "`echo "X${arg}" | sed -n "s/X\\(-[BIL]${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X-[BIL]${popdir_rx}\\(.*\\)/\\1/p"` ;;
 	  "${ML_POPDIR}"/*)
-	    GCJ_="${GCJ_}"`echo "X${arg}" | sed -n "s/X\\(${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X${popdir_rx}\\(.*\\)/\\1/p"`' ' ;;
+	    GCJ_="${GCJ_} "`echo "X${arg}" | sed -n "s/X\\(${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X${popdir_rx}\\(.*\\)/\\1/p"` ;;
 	  *)
-	    GCJ_="${GCJ_}${arg} " ;;
+	    GCJ_="${GCJ_} ${arg}" ;;
 	  esac
 	done
 
@@ -850,11 +850,11 @@ if [ -n "${multidirs}" ] && [ -z "${ml_n
 	for arg in ${GFORTRAN}; do
 	  case $arg in
 	  -[BIL]"${ML_POPDIR}"/*)
-	    GFORTRAN_="${GFORTRAN_}"`echo "X${arg}" | sed -n "s/X\\(-[BIL]${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X-[BIL]${popdir_rx}\\(.*\\)/\\1/p"`' ' ;;
+	    GFORTRAN_="${GFORTRAN_} "`echo "X${arg}" | sed -n "s/X\\(-[BIL]${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X-[BIL]${popdir_rx}\\(.*\\)/\\1/p"` ;;
 	  "${ML_POPDIR}"/*)
-	    GFORTRAN_="${GFORTRAN_}"`echo "X${arg}" | sed -n "s/X\\(${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X${popdir_rx}\\(.*\\)/\\1/p"`' ' ;;
+	    GFORTRAN_="${GFORTRAN_} "`echo "X${arg}" | sed -n "s/X\\(${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X${popdir_rx}\\(.*\\)/\\1/p"` ;;
 	  *)
-	    GFORTRAN_="${GFORTRAN_}${arg} " ;;
+	    GFORTRAN_="${GFORTRAN_} ${arg}" ;;
 	  esac
 	done
 
Index: gcc/tree-pass.h
===================================================================
--- gcc/tree-pass.h	(revision 123987)
+++ gcc/tree-pass.h	(working copy)
@@ -380,6 +380,7 @@ extern struct tree_opt_pass pass_remove_
 extern struct tree_opt_pass pass_postreload_cse;
 extern struct tree_opt_pass pass_gcse2;
 extern struct tree_opt_pass pass_flow2;
+extern struct tree_opt_pass pass_nonexceptional_receiver;
 extern struct tree_opt_pass pass_stack_adjustments;
 extern struct tree_opt_pass pass_peephole2;
 extern struct tree_opt_pass pass_if_after_reload;
Index: gcc/ChangeLog
===================================================================
--- gcc/ChangeLog	(revision 123987)
+++ gcc/ChangeLog	(working copy)
@@ -1,3 +1,19 @@
+2007-04-20  Nathan Sidwell  <nathan@codesourcery.com>
+
+	* tree-pass.h (pass_nonexceptional_receiver): Declare.
+	* flow.c (has_nonexceptional_receiver,
+	rest_of_handle_nonexceptional_reciever,
+	pass_nonexceptional_receiver): New.
+	* function.h (struct function): Add has_nonexceptional_receiver.
+	(current_function_has_nonexceptional_receiver): Define.
+	* except.c (expand_builtin_unwind_init): Set
+	current_function_has_nonexceptional_receiver.
+	* passes.c (init_optimization_passes): Add
+	pass_nonexceptional_receiver.
+	* reload1.c (reload): Check
+	current_function_has_nonexceptional_receiver not
+	current_function_has_nonlocal_label for saving caller saves.
+
 2007-04-19  Bernd Schmidt  <bernd.schmidt@analog.com>
 
 	* reload.c (combine_reloads): When trying to use a dying register,
Index: gcc/flow.c
===================================================================
--- gcc/flow.c	(revision 123987)
+++ gcc/flow.c	(working copy)
@@ -4778,3 +4778,88 @@ struct tree_opt_pass pass_flow2 =
   'w'                                   /* letter */
 };
 
+/* Determine if the current function has an exception receiver block
+   that reaches the exit block via non-exceptional edges  */
+
+static bool
+has_nonexceptional_receiver (void)
+{
+  edge e;
+  edge_iterator ei;
+  basic_block *tos, *worklist, bb;
+
+  /* If we're not optimizing, then just err on the safe side.  */
+  if (!optimize)
+    return true;
+  
+  /* First determine which blocks can reach exit via normal paths.  */
+  tos = worklist = xmalloc (sizeof (basic_block) * (n_basic_blocks + 1));
+
+  FOR_EACH_BB (bb)
+    bb->flags &= ~BB_REACHABLE;
+
+  /* Place the exit block on our worklist.  */
+  EXIT_BLOCK_PTR->flags |= BB_REACHABLE;
+  *tos++ = EXIT_BLOCK_PTR;
+  
+  /* Iterate: find everything reachable from what we've already seen.  */
+  while (tos != worklist)
+    {
+      bb = *--tos;
+
+      FOR_EACH_EDGE (e, ei, bb->preds)
+	if (!(e->flags & EDGE_ABNORMAL))
+	  {
+	    basic_block src = e->src;
+
+	    if (!(src->flags & BB_REACHABLE))
+	      {
+		src->flags |= BB_REACHABLE;
+		*tos++ = src;
+	      }
+	  }
+    }
+  free (worklist);
+
+  /* Now see if there's a reachable block with an exceptional incoming
+     edge.  */
+  FOR_EACH_BB (bb)
+    if (bb->flags & BB_REACHABLE)
+      FOR_EACH_EDGE (e, ei, bb->preds)
+	if (e->flags & EDGE_ABNORMAL)
+	  return true;
+
+  /* No exceptional block reached exit unexceptionally.  */
+  return false;
+}
+
+static unsigned
+rest_of_handle_nonexceptional_receiver (void)
+{
+  /* If we have no receivers, then we can't have a non-exceptional
+     one.  */
+  if (!current_function_has_nonlocal_label)
+    return 0;
+
+  current_function_has_nonexceptional_receiver
+    = has_nonexceptional_receiver ();
+  return 0;
+}
+
+struct tree_opt_pass pass_nonexceptional_receiver =
+{
+  "ner",                                /* name */
+  NULL,                                 /* gate */
+  rest_of_handle_nonexceptional_receiver, /* execute */
+  NULL,                                 /* sub */
+  NULL,                                 /* next */
+  0,                                    /* static_pass_number */
+  0,         				/* tv_id */
+  0,                                    /* properties_required */
+  0,                                    /* properties_provided */
+  0,                                    /* properties_destroyed */
+  TODO_verify_flow,                     /* todo_flags_start */
+  0,                                    /* todo_flags_finish */
+  0                                     /* letter */
+};
+
Index: gcc/function.h
===================================================================
--- gcc/function.h	(revision 123987)
+++ gcc/function.h	(working copy)
@@ -406,6 +406,10 @@ struct function GTY(())
      from nested functions.  */
   unsigned int has_nonlocal_label : 1;
 
+  /* Nonzero if function has non-local label which reaches exit block
+     via non-exceptional route.  */
+  unsigned int has_nonexceptional_receiver : 1;
+  
   /* Nonzero if function being compiled has nonlocal gotos to parent
      function.  */
   unsigned int has_nonlocal_goto : 1;
@@ -523,6 +527,8 @@ extern int trampolines_created;
 #define current_function_uses_const_pool (cfun->uses_const_pool)
 #define current_function_epilogue_delay_list (cfun->epilogue_delay_list)
 #define current_function_has_nonlocal_label (cfun->has_nonlocal_label)
+#define current_function_has_nonexceptional_receiver \
+	(cfun->has_nonexceptional_receiver)
 #define current_function_has_nonlocal_goto (cfun->has_nonlocal_goto)
 
 #define return_label (cfun->x_return_label)
Index: gcc/except.c
===================================================================
--- gcc/except.c	(revision 123987)
+++ gcc/except.c	(working copy)
@@ -2859,7 +2859,7 @@ expand_builtin_unwind_init (void)
 {
   /* Set this so all the registers get saved in our frame; we need to be
      able to copy the saved values for any registers from frames we unwind.  */
-  current_function_has_nonlocal_label = 1;
+  current_function_has_nonexceptional_receiver = 1;
 
 #ifdef SETUP_FRAME_ADDRESSES
   SETUP_FRAME_ADDRESSES ();
Index: gcc/passes.c
===================================================================
--- gcc/passes.c	(revision 123987)
+++ gcc/passes.c	(working copy)
@@ -687,6 +687,7 @@ init_optimization_passes (void)
       NEXT_PASS (pass_rtl_fwprop_addr);
       NEXT_PASS (pass_outof_cfg_layout_mode);
       NEXT_PASS (pass_life);
+      NEXT_PASS (pass_nonexceptional_receiver);
       NEXT_PASS (pass_combine);
       NEXT_PASS (pass_if_after_combine);
       NEXT_PASS (pass_partition_blocks);
Index: gcc/reload1.c
===================================================================
--- gcc/reload1.c	(revision 123987)
+++ gcc/reload1.c	(working copy)
@@ -688,9 +688,10 @@ reload (rtx first, int global)
   for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
     mark_home_live (i);
 
-  /* A function that receives a nonlocal goto must save all call-saved
+  /* A function that has a nonlocal label that can reach the exit
+     block via non-exceptional paths must save all call-saved
      registers.  */
-  if (current_function_has_nonlocal_label)
+  if (current_function_has_nonexceptional_receiver)
     for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
       if (! call_used_regs[i] && ! fixed_regs[i] && ! LOCAL_REGNO (i))
 	regs_ever_live[i] = 1;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]