diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a1b15007c982d9fa22dbec3f9d12f18e77128b88..b9baa5d98167a611c1fefa46613875c3d09a1619 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,19 @@
+2003-06-10  J"orn Rennecke <joern.rennecke@superh.com>
+
+	* sh-protos.h (function_symbol): Declare.
+	* sh.c (expand_block_move, expand_ashiftrt): Use it.
+	(sh_expand_prologue, sh_expand_epilogue): Likewise.
+	(sh_initialize_trampoline): Likewise.
+	(function_symbol): New function.
+	* sh.md (udivsi3, divsi3, mulsi3, ic_invalidate_line): Use it.
+	(initialize_trampoline, call, call_pop, call_value, sibcall): Likewise.
+	(call_value_pop, shcompact_return_tramp): Likewise.
+
+	* sh.h (OVERRIDE_OPTIONS): Don't suppress --profile-arc-flag.
+
+	* sh.md (GOTaddr2picreg): Use gen_lowpart to get lowpart of
+	target register.
+
 2003-06-10  DJ Delorie  <dj@redhat.com>
 
 	* doc/md.texi (Machine Constraints): Document stormy's Z
diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h
index 45bcea638d1a23657cfbd8e6450ca7433137e435..709a0e400723f34556e19e9b47eece7dbe7f464b 100644
--- a/gcc/config/sh/sh-protos.h
+++ b/gcc/config/sh/sh-protos.h
@@ -136,5 +136,6 @@ extern void fpscr_set_from_mem PARAMS ((int, HARD_REG_SET));
 extern void sh_pr_interrupt PARAMS ((struct cpp_reader *));
 extern void sh_pr_trapa PARAMS ((struct cpp_reader *));
 extern void sh_pr_nosave_low_regs PARAMS ((struct cpp_reader *));
+extern rtx function_symbol (const char *);
 
 #endif /* ! GCC_SH_PROTOS_H */
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 482350af621de85d90c0a112af2e6f9d47f30325..0b82d791f52ead707bb6f1be5875a30964b5c46f 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -626,7 +626,7 @@ expand_block_move (operands)
 
 	  entry_name = get_identifier ("__movstrSI12_i4");
 
-	  sym = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (entry_name));
+	  sym = function_symbol (IDENTIFIER_POINTER (entry_name));
 	  func_addr_rtx = copy_to_mode_reg (Pmode, sym);
 	  force_into (XEXP (operands[0], 0), r4);
 	  force_into (XEXP (operands[1], 0), r5);
@@ -646,7 +646,7 @@ expand_block_move (operands)
 	  entry_name = get_identifier (bytes & 4
 				       ? "__movstr_i4_odd"
 				       : "__movstr_i4_even");
-	  sym = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (entry_name));
+	  sym = function_symbol (IDENTIFIER_POINTER (entry_name));
 	  func_addr_rtx = copy_to_mode_reg (Pmode, sym);
 	  force_into (XEXP (operands[0], 0), r4);
 	  force_into (XEXP (operands[1], 0), r5);
@@ -670,7 +670,7 @@ expand_block_move (operands)
 
       sprintf (entry, "__movstrSI%d", bytes);
       entry_name = get_identifier (entry);
-      sym = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (entry_name));
+      sym = function_symbol (IDENTIFIER_POINTER (entry_name));
       func_addr_rtx = copy_to_mode_reg (Pmode, sym);
       force_into (XEXP (operands[0], 0), r4);
       force_into (XEXP (operands[1], 0), r5);
@@ -691,7 +691,7 @@ expand_block_move (operands)
       rtx r6 = gen_rtx_REG (SImode, 6);
 
       entry_name = get_identifier ("__movstr");
-      sym = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (entry_name));
+      sym = function_symbol (IDENTIFIER_POINTER (entry_name));
       func_addr_rtx = copy_to_mode_reg (Pmode, sym);
       force_into (XEXP (operands[0], 0), r4);
       force_into (XEXP (operands[1], 0), r5);
@@ -1908,7 +1908,7 @@ expand_ashiftrt (operands)
   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
   sprintf (func, "__ashiftrt_r4_%d", value);
   func_name = get_identifier (func);
-  sym = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (func_name));
+  sym = function_symbol (IDENTIFIER_POINTER (func_name));
   emit_move_insn (wrk, sym);
   emit_insn (gen_ashrsi3_n (GEN_INT (value), wrk));
   emit_move_insn (operands[0], gen_rtx_REG (SImode, 4));
@@ -5110,10 +5110,9 @@ sh_expand_prologue ()
   if (SHMEDIA_REGS_STACK_ADJUST ())
     {
       emit_move_insn (gen_rtx_REG (Pmode, R0_REG),
-		      gen_rtx_SYMBOL_REF (Pmode,
-					  TARGET_FPU_ANY
-					  ? "__GCC_push_shmedia_regs"
-					  : "__GCC_push_shmedia_regs_nofpu"));
+		      function_symbol (TARGET_FPU_ANY
+				       ? "__GCC_push_shmedia_regs"
+				       : "__GCC_push_shmedia_regs_nofpu"));
       /* This must NOT go through the PLT, otherwise mach and macl
 	 may be clobbered.  */
       emit_insn (gen_shmedia_save_restore_regs_compact
@@ -5146,8 +5145,7 @@ sh_expand_prologue ()
       /* This must NOT go through the PLT, otherwise mach and macl
 	 may be clobbered.  */
       emit_move_insn (gen_rtx_REG (Pmode, R0_REG),
-		      gen_rtx_SYMBOL_REF (Pmode,
-					  "__GCC_shcompact_incoming_args"));
+		      function_symbol ("__GCC_shcompact_incoming_args"));
       emit_insn (gen_shcompact_incoming_args ());
     }
 }
@@ -5195,10 +5193,9 @@ sh_expand_epilogue ()
   if (SHMEDIA_REGS_STACK_ADJUST ())
     {
       emit_move_insn (gen_rtx_REG (Pmode, R0_REG),
-		      gen_rtx_SYMBOL_REF (Pmode,
-					  TARGET_FPU_ANY
-					  ? "__GCC_pop_shmedia_regs"
-					  : "__GCC_pop_shmedia_regs_nofpu"));
+		      function_symbol (TARGET_FPU_ANY
+				       ? "__GCC_pop_shmedia_regs"
+				       : "__GCC_pop_shmedia_regs_nofpu"));
       /* This must NOT go through the PLT, otherwise mach and macl
 	 may be clobbered.  */
       emit_insn (gen_shmedia_save_restore_regs_compact
@@ -7823,7 +7820,7 @@ sh_initialize_trampoline (tramp, fnaddr, cxt)
   if (TARGET_HARVARD)
     {
       if (TARGET_USERMODE)
-	emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__ic_invalidate"),
+	emit_library_call (function_symbol ("__ic_invalidate"),
 			   0, VOIDmode, 1, tramp, SImode);
       else
 	emit_insn (gen_ic_invalidate_line (tramp));
@@ -8479,4 +8476,12 @@ sh_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
   no_new_pseudos = 0;
 }
 
+rtx
+function_symbol (const char *name)
+{
+  rtx sym = gen_rtx_SYMBOL_REF (Pmode, name);
+  SYMBOL_REF_FLAGS (sym) = SYMBOL_FLAG_FUNCTION;
+  return sym;
+}
+
 #include "gt-sh.h"
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index d135224b09a0cd0af8ca7bbab04ab8334fdf942a..6623fb0114899bc39cad9ecdb4c48009e5ec7a9d 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -456,7 +456,11 @@ do {									\
 	  /* Relaxation isn't yet supported for SHmedia */		\
 	  target_flags &= ~RELAX_BIT;					\
 	}								\
-      if (profile_flag || profile_arc_flag)				\
+      /* -fprofile-arcs needs a working libgcov .  In unified tree	\
+	 configurations with newlib, this requires to configure with	\
+	 --with-newlib --with-headers.  But there is no way to check	\
+	 here we have a working libgcov, so just assume that we have.  */\
+      if (profile_flag)							\
 	{								\
 	  warning ("Profiling is not supported on this target.");	\
 	  profile_flag = profile_arc_flag = 0;				\
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index e9e0862c22919c6aa8b011f16e8e0e2a8648d260..26ec41259b862bc1fbf75af59f778f9f48a27172 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -1358,8 +1358,7 @@
   /* Emit the move of the address to a pseudo outside of the libcall.  */
   if (TARGET_HARD_SH4 && TARGET_SH2E)
     {
-      emit_move_insn (operands[3],
-		      gen_rtx_SYMBOL_REF (SImode, \"__udivsi3_i4\"));
+      emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
       if (TARGET_FPU_SINGLE)
 	last = gen_udivsi3_i4_single (operands[0], operands[3]);
       else
@@ -1375,10 +1374,9 @@
   else if (TARGET_SH5)
     {
       emit_move_insn (operands[3],
-		      gen_rtx_SYMBOL_REF (Pmode,
-					  (TARGET_FPU_ANY
-					   ? \"__udivsi3_i4\"
-					   : \"__udivsi3\")));
+		      function_symbol (TARGET_FPU_ANY
+				       ? \"__udivsi3_i4\"
+				       : \"__udivsi3\"));
 
       if (TARGET_SHMEDIA)
 	last = gen_udivsi3_i1_media (operands[0],
@@ -1393,8 +1391,7 @@
     }
   else
     {
-      emit_move_insn (operands[3],
-		      gen_rtx_SYMBOL_REF (SImode, \"__udivsi3\"));
+      emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
       last = gen_udivsi3_i1 (operands[0], operands[3]);
     }
   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
@@ -1508,8 +1505,7 @@
   /* Emit the move of the address to a pseudo outside of the libcall.  */
   if (TARGET_HARD_SH4 && TARGET_SH2E)
     {
-      emit_move_insn (operands[3],
-		      gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3_i4\"));
+      emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
       if (TARGET_FPU_SINGLE)
 	last = gen_divsi3_i4_single (operands[0], operands[3]);
       else
@@ -1525,10 +1521,9 @@
   else if (TARGET_SH5)
     {
       emit_move_insn (operands[3],
-		      gen_rtx_SYMBOL_REF (Pmode,
-					  (TARGET_FPU_ANY
-					   ? \"__sdivsi3_i4\"
-					   : \"__sdivsi3\")));
+		      function_symbol (TARGET_FPU_ANY
+				       ? \"__sdivsi3_i4\"
+				       : \"__sdivsi3\"));
 
       if (TARGET_SHMEDIA)
 	last = gen_divsi3_i1_media (operands[0],
@@ -1543,7 +1538,7 @@
     }
   else
     {
-      emit_move_insn (operands[3], gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3\"));
+      emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
       last = gen_divsi3_i1 (operands[0], operands[3]);
     }
   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
@@ -1697,7 +1692,7 @@
     {
       /* The address must be set outside the libcall,
 	 since it goes into a pseudo.  */
-      rtx sym = gen_rtx_SYMBOL_REF (SImode, \"__mulsi3\");
+      rtx sym = function_symbol (\"__mulsi3\");
       rtx addr = force_reg (SImode, sym);
       rtx insns = gen_mulsi3_call (operands[0], operands[1],
 				   operands[2], addr);
@@ -3554,7 +3549,7 @@
     }
   else if (TARGET_SHCOMPACT)
     {
-      operands[1] = gen_rtx_SYMBOL_REF (Pmode, \"__ic_invalidate\");
+      operands[1] = function_symbol (\"__ic_invalidate\");
       operands[1] = force_reg (Pmode, operands[1]);
       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
       DONE;
@@ -3609,7 +3604,7 @@
   rtx sfun, tramp;
 
   tramp = force_reg (Pmode, operands[0]);
-  sfun = force_reg (Pmode, gen_rtx_SYMBOL_REF (Pmode, \"__init_trampoline\"));
+  sfun = force_reg (Pmode, function_symbol (\"__init_trampoline\"));
   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
 
@@ -5806,8 +5801,7 @@
 	 run out of registers when adjusting fpscr for the call.  */
       emit_insn (gen_force_mode_for_call ());
 
-      operands[0] = gen_rtx_SYMBOL_REF (SImode,
-					\"__GCC_shcompact_call_trampoline\");
+      operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
       if (flag_pic)
 	{
 	  rtx reg = gen_reg_rtx (Pmode);
@@ -5926,8 +5920,7 @@
 	 run out of registers when adjusting fpscr for the call.  */
       emit_insn (gen_force_mode_for_call ());
 
-      operands[0] = gen_rtx_SYMBOL_REF (SImode,
-					\"__GCC_shcompact_call_trampoline\");
+      operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
       if (flag_pic)
 	{
 	  rtx reg = gen_reg_rtx (Pmode);
@@ -6031,8 +6024,7 @@
 	 run out of registers when adjusting fpscr for the call.  */
       emit_insn (gen_force_mode_for_call ());
 
-      operands[1] = gen_rtx_SYMBOL_REF (SImode,
-					\"__GCC_shcompact_call_trampoline\");
+      operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
       if (flag_pic)
 	{
 	  rtx reg = gen_reg_rtx (Pmode);
@@ -6250,8 +6242,7 @@
 	 run out of registers when adjusting fpscr for the call.  */
       emit_insn (gen_force_mode_for_call ());
 
-      operands[0] = gen_rtx_SYMBOL_REF (SImode,
-					\"__GCC_shcompact_call_trampoline\");
+      operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
       if (flag_pic)
 	{
 	  rtx reg = gen_reg_rtx (Pmode);
@@ -6391,8 +6382,7 @@
 	 run out of registers when adjusting fpscr for the call.  */
       emit_insn (gen_force_mode_for_call ());
 
-      operands[1] = gen_rtx_SYMBOL_REF (SImode,
-					\"__GCC_shcompact_call_trampoline\");
+      operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
       if (flag_pic)
 	{
 	  rtx reg = gen_reg_rtx (Pmode);
@@ -6620,7 +6610,7 @@
       emit_insn (gen_ptrel (tr, dipic, lab));
 
       if (GET_MODE (operands[0]) != GET_MODE (tr))
-	tr = gen_rtx_SUBREG (GET_MODE (operands[0]), tr, 0);
+	tr = gen_lowpart (GET_MODE (operands[0]), tr);
 
       insn = emit_move_insn (operands[0], tr);
 
@@ -7207,8 +7197,7 @@ mov.l\\t1f,r0\\n\\
   "
 {
   rtx reg = gen_rtx_REG (Pmode, R0_REG);
-  rtx sym = gen_rtx_SYMBOL_REF (Pmode,
-				\"__GCC_shcompact_return_trampoline\");
+  rtx sym = function_symbol (\"__GCC_shcompact_return_trampoline\");
 
   if (flag_pic)
     emit_insn (gen_symGOTPLT2reg (reg, sym));