diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a07710d455ee..09a4a365b811 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,68 @@
+2004-06-21  Kaz Kojima  <kkojima@gcc.gnu.org>
+
+	* config/sh/t-linux (MULTILIB_OPTIONS): Remove.
+
+2004-06-21  J"orn Rennecke <joern.rennecke@superh.com>
+
+	* sh.h (SUPPORT_SH1, SUPPORT_SH2E, SUPPORT_SH4): Conditionanlly define.
+	(SUPPORT_SH4_SINGLE): Likewise.
+	(TARGET_SWITCHES): Break out switches for cpu subtargets:
+	(TARGET_SWITCH_SH1, TARGET_SWITCH_SH2, TARGET_SWITCH_SH2E): Define.
+	(TARGET_SWITCH_SH3, TARGET_SWITCH_SH3E): Likewise.
+	(TARGET_SWITCH_SH4_SINGLE_ONLY, TARGET_SWITCH_SH4_SINGLE): Likewise.
+	(TARGET_SWITCH_SH4_NOFPU, TARGET_SWITCH_SH4): Likewise.
+	(TARGET_SWITCH_SH5_64MEDIA, TARGET_SWITCH_SH5_64MEDIA_NOFPU): Likewise.
+	(TARGET_SWITCHES_SH5_32MEDIA): Likewise.
+	(TARGET_SWITCHES_SH5_32MEDIA_NOFPU): Likewise.
+	(SELECT_SH5_64, SELECT_SH5_64_NOFPU): Rename to:
+	(SELECT_SH5_64MEDIA, SELECT_SH5_64MEDIA_NOFPU)
+	(SELECT_SH5_32, SELECT_SH5_32_NOFPU): Rename to:
+	(SELECT_SH5_32MEDIA, SELECT_SH5_32MEDIA_NOFPU).
+	(SH_MULTILIB_CPU_DEFAULT, MULTILIB_DEFAULTS): Define.
+	(ASM_ISA_SPEC_DEFAULT, ASM_ISA_DEFAULT_SPEC): Likewise.
+	* sh64.h (ASM_SPEC, LINK_DEFAULT_CPU_EMUL): Don't redefine.
+	(TARGET_DEFAULT): Likewise.
+	* config/sh/t-elf: Amend comment.
+	* config/sh/t-1e, config/sh/t-mlib-sh1: New files.
+	* config/sh/t-mlib-sh2, config/sh/t-mlib-sh2e: Likewise.
+	* config/sh/t-mlib-sh3, config/sh/t-mlib-sh3e: Likewise.
+	* config/sh/t-mlib-sh4, config/sh/t-mlib-sh4-nofpu: Likewise.
+	* config/sh/t-mlib-sh4-single: Likewise.
+	* config/sh/t-mlib-sh4-single-only: Likewise.
+	* config/sh/t-mlib-sh5-32media: Likewise.
+	* config/sh/t-mlib-sh5-32media-nofpu: Likewise.
+	* config/sh/t-mlib-sh5-64media: Likewise.
+	* config/sh/t-mlib-sh5-64media-nofpu: Likewise.
+	* config/sh/t-mlib-sh5-compact: Likewise.
+	* config/sh/t-mlib-sh5-compact-nofpu: Likewise.
+	* config/sh/t-sh: (MULTILIB_ENDIAN): Add mb.
+	(MULTILIB_CPUS): Define.
+	(MULTILIB_OPTIONS): Use MULTILIB_CPUS.
+	(MULTILIB_MATCHES): Use some shell code to calculate it.
+	(MULTILIB_EXCEPTIONS): Change to ml/m1.
+	* config/sh/elf.h (SUBTARGET_ASM_ISA_SPEC): Use ASM_ISA_DEFAULT_SPEC.
+	* config/sh/netbsd-elf.h: Update code which sets TARGET_VERSION_CPU.
+	(LINK_DEFAULT_CPU_EMUL): Don't redefine.
+	(NO_PROFILE_COUNTERS): Define to 1.
+	* config/sh/t-netbsd (MULTILIB_OPTIONS): Don't append to.
+	(MULTILIB_DIRNAMES, MULTILIB_MATCHES, MULTILIB_EXCEPTIONS): Don't zap.
+	* config/sh/t-netbsd-sh5-64 (MULTILIB_OPTIONS): Don't redefine.
+	(MULTILIB_MATCHES): Don't zap.
+	(MULTILIB_DIRNAMES): Use MULTILIB_RAW_DIRNAMES.
+	* config/sh/t-sh64 (MULTILIB_OPTIONS): Don't redefine.
+	(MULTILIB_MATCHES, MULTILIB_EXCEPTIONS): Don't zap.
+	(MULTILIB_RAW_DIRNAMES): Define.
+	(MULTILIB_DIRNAMES): Use it.
+	* config.gcc: Also set cpu_type / need_64bit_hwint for sh[be]*-*-*.
+	(sh*linux configurations): Merge into:
+	(sh*elf / sh*kaos configurations).  Support --with-endian, --with-cpu,
+	--with-multilib-list options.  Support sh-superh-elf configuration.
+	(sh*-netbsd*): Use SELECT_SH* macros.
+	(supported_defaults): sh[123456ble]-*-* | sh-*-* support "cpu".
+	Merge sh*-*-netbsd* configurations into sh-elf configurations.
+	* config/sh/t-netbsd-sh5, config/sh/t-le, config/sh/t-le: Delete.
+	* config/sh/t-monolib: Likewise.
+
 2004-06-21  Paul Brook  <paul@codesourcery.com>
 
 	* config/arm/arm.h (ARM_LEGITIMIZE_RELOAD_ADDRESS): Soft-float need
diff --git a/gcc/config.gcc b/gcc/config.gcc
index d9eb628355d8..fd226dc215b0 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -295,7 +295,7 @@ s390*-*-*)
 	need_64bit_hwint=yes
 	;;
 # Note the 'l'; we need to be able to match e.g. "shle" or "shl".
-sh[123456789l]*-*-*)
+sh[123456789lbe]*-*-*)
 	cpu_type=sh
 	need_64bit_hwint=yes
 	;;
@@ -1683,34 +1683,124 @@ s390x-ibm-tpf*)
 	out_file=s390/s390.c
 	tmake_file="t-slibgcc-elf-ver s390/t-crtstuff s390/t-tpf"
 	;;
-sh-*-elf* | sh[2346l]*-*-elf* | sh*-*-kaos*)
-	tmake_file="sh/t-sh sh/t-elf"
-	case ${target} in
-	shl* | sh[234]l* | sh64l*)
-		tm_file="sh/little.h ${tm_file}"
-		tmake_file="${tmake_file} sh/t-le"
-		;;
+sh-*-elf* | sh[12346l]*-*-elf* | sh*-*-kaos* | \
+  sh-*-linux* | sh[346lbe]*-*-linux* | \
+  sh-*-netbsdelf* | shl*-*-netbsdelf* | sh5-*-netbsd* | sh5l*-*-netbsd* | \
+   sh64-*-netbsd* | sh64l*-*-netbsd*)
+	tmake_file="${tmake_file} sh/t-sh sh/t-elf"
+	if test x${with_endian} = x; then
+		case ${target} in
+		sh[1234]*be-*-* | sh[1234]*eb-*-*) with_endian=big ;;
+		shbe-*-* | sheb-*-*)		   with_endian=big,little ;;
+		sh[1234]l* | sh[34]*-*-linux*)	   with_endian=little ;;
+		shl* | sh64l* | sh*-*-linux* | \
+		  sh5l* | sh-superh-elf)	   with_endian=little,big ;;
+		sh[1234]*-*-*)			   with_endian=big ;;
+		*)				   with_endian=big,little ;;
+		esac
+	fi
+	case ${with_endian} in
+	big|little)	tmake_file="${tmake_file} sh/t-1e" ;;
+	big,little|little,big) ;;
+	*)	echo "with_endian=${with_endian} not supported."; exit 1 ;;
 	esac
-	tm_file="${tm_file} dbxelf.h elfos.h svr4.h sh/elf.h sh/embed-elf.h"
+	case ${with_endian} in
+	little*)	tm_file="sh/little.h ${tm_file}" ;;
+	esac
+	tm_file="${tm_file} dbxelf.h elfos.h"
 	case ${target} in
+	sh*-*-netbsd*)	;;
+	*)		tm_file="${tm_file} svr4.h" ;;
+	esac
+	tm_file="${tm_file} sh/elf.h"
+	case ${target} in
+	sh*-*-linux*)	tmake_file="${tmake_file} sh/t-linux"
+			tm_file="${tm_file} sh/linux.h" ;;
+	sh*-*-kaos*)	tm_file="${tm_file} sh/embed-elf.h kaos.h sh/kaos-sh.h"
+			;;
+	sh*-*-netbsd*)	tm_file="${tm_file} netbsd.h netbsd-elf.h sh/netbsd-elf.h" ;;
+	*)		tm_file="${tm_file} sh/embed-elf.h" ;;
+	esac
+	case ${target} in
+	sh5*-*-netbsd*)
+		# SHmedia, 32-bit ABI
+		tmake_file="${tmake_file} sh/t-sh64 sh/t-netbsd"
+		;;
+	sh64*-netbsd*)
+		# SHmedia, 64-bit ABI
+		tmake_file="${tmake_file} sh/t-sh64 sh/t-netbsd sh/t-netbsd-sh5-64"
+		;;
+	*-*-netbsd)
+                tmake_file="${tmake_file} sh/t-netbsd"
+		;;
+	sh64*-*-linux*)
+		tmake_file="${tmake_file} sh/t-sh64 sh/t-linux64"
+		tm_file="${tm_file} sh/sh64.h"
+		extra_headers="shmedia.h ushmedia.h sshmedia.h"
+		;;
 	sh64*)
 		tmake_file="${tmake_file} sh/t-sh64"
 		tm_file="${tm_file} sh/sh64.h"
 		extra_headers="shmedia.h ushmedia.h sshmedia.h"
 		;;
-	sh4_single*)  target_cpu_default="SELECT_SH4_SINGLE" ;;
-	sh4*)  target_cpu_default="SELECT_SH4" ;;
-	sh3e*) target_cpu_default="SELECT_SH3E" ;;
-	sh3*)  target_cpu_default="SELECT_SH3" ;;
-	sh2e*) target_cpu_default="SELECT_SH2E" ;;
-	sh2*)  target_cpu_default="SELECT_SH2" ;;
 	esac
-	case ${target} in
-	sh[234]*) tmake_file="${tmake_file} sh/t-monolib" ;;
+	# sed el/eb endian suffixes away to avoid confusion with sh[23]e
+	case `echo ${target} | sed 's/e[lb]-/-/'` in
+	sh64*-*-netbsd*)	sh_cpu_target=sh5-64media ;;
+	sh64* | sh5*-*-netbsd*)	sh_cpu_target=sh5-32media ;;
+	sh4_single_only*)	sh_cpu_target=sh4-single-only ;;
+	sh4_single*)		sh_cpu_target=sh4-single ;;
+	sh4_nofpu*)		sh_cpu_target=sh4-nofpu ;;
+	sh4* | sh-superh-*)	sh_cpu_target=sh4 ;;
+	sh3e*)			sh_cpu_target=sh3e ;;
+	sh*-*-netbsd* | sh3*)	sh_cpu_target=sh3 ;;
+	sh2e*)			sh_cpu_target=sh2e ;;
+	sh2*)			sh_cpu_target=sh2 ;;
+	*)			sh_cpu_target=sh1 ;;
 	esac
-	case ${target} in
-	sh*-*-kaos*) tm_file="${tm_file} kaos.h sh/kaos-sh.h" ;;
+	sh_cpu_default="`echo $with_cpu|sed s/^m/sh/|tr A-Z_ a-z-`"
+	case $sh_cpu_default in
+	sh5-64media-nofpu | sh5-64media | \
+	  sh5-32media-nofpu | sh5-32media | sh5-compact-nofpu | sh5-compact | \
+	  sh4-single-only | sh4-single | sh4-nofpu | sh4 | \
+	  sh3e | sh3 | sh2e | sh2 | sh1)
+		sh_multilibs="${sh_cpu_default},${sh_multilibs}" ;;
+	"")	sh_cpu_default=${sh_cpu_target} ;;
+	*)	echo "with_cpu=$with_cpu not supported"; exit 1 ;;
 	esac
+	sh_multilibs=${with_multilib_list}
+	if test x${sh_multilibs} = x ; then
+		case ${target} in
+		sh[1234]*)	sh_multilibs=${sh_cpu_target} ;;
+		sh64* | sh5*)	sh_multilibs=m5-32media,m5-32media-nofpu,m5-compact,m5-compact-nofpu,m5-64media,m5-64media-nofpu ;;
+		sh-superh-*)	sh_multilibs=m4,m4-single,m4-single-only,m4-nofpu ;;
+		sh*-*-linux*)	sh_multilibs=m1,m3e,m4 ;;
+		sh*-*-netbsd*)	sh_multilibs=m3,m3e,m4 ;;
+		*) sh_multilibs=m1,m2,m2e,m4,m4-single,m4-single-only ;;
+		esac
+	fi
+	target_cpu_default=SELECT_`echo ${sh_cpu_default}|tr a-z- A-Z_`
+	tm_defines=${tm_defines}' SH_MULTILIB_CPU_DEFAULT=\"'`echo $sh_cpu_default|sed s/sh/m/`'\"'
+	sh_multilibs=`echo $sh_multilibs,$sh_cpu_default | sed -e 's/[ 	,/][ 	,]*/ /g' -e 's/ $//' -e s/^m/sh/ -e 's/ m/ sh/g' | tr A-Z_ a-z-`
+	for sh_multilib in ${sh_multilibs}; do
+		case ${sh_multilib} in
+		sh1 | sh2 | sh2e | sh3 | sh3e | \
+		sh4 | sh4-single | sh4-single-only | sh4-nofpu | \
+		sh5-64media | sh5-64media-nofpu | \
+		sh5-32media | sh5-32media-nofpu | \
+		sh5-compact | sh5-compact-nofpu)
+			tmake_file="${tmake_file} sh/t-mlib-${sh_multilib}"
+			tm_defines="$tm_defines SUPPORT_`echo $sh_multilib|tr a-z- A-Z_`"
+			;;
+		*)
+			echo "with_multilib_list=${sh_multilib} not supported."
+			exit 1
+			;;
+		esac
+	done
+	if test x${enable_incomplete_targets} == xyes ; then
+		tm_defines="$tm_defines SUPPORT_SH1 SUPPORT_SH2E SUPPORT_SH4 SUPPORT_SH4_SINGLE SUPPORT_SH5_32MEDIA SUPPORT_SH5_32MEDIA_NOFPU SUPPORT_SH5_64MEDIA SUPPORT_SH5_64MEDIA_NOFPU"
+	fi
 	use_fixproto=yes
 	;;
 sh-*-rtemscoff*)
@@ -1721,69 +1811,6 @@ sh-*-rtems*)
 	tmake_file="sh/t-sh sh/t-elf t-rtems"
 	tm_file="${tm_file} dbxelf.h elfos.h svr4.h sh/elf.h sh/embed-elf.h sh/rtemself.h rtems.h"
 	;;
-sh-*-linux* | sh[2346lbe]*-*-linux*)
-	tmake_file="sh/t-sh sh/t-elf ${tmake_file}"
-	case ${target} in
-	sh*be-*-* | sh*eb-*-*) ;;
-	*)
-		tm_file="sh/little.h ${tm_file}"
-		tmake_file="${tmake_file} sh/t-le"
-		;;
-	esac
-	tmake_file="${tmake_file} sh/t-linux"
-	tm_file="${tm_file} dbxelf.h elfos.h svr4.h sh/elf.h sh/linux.h"
-	case ${target} in
-	sh64*)
-		tmake_file="${tmake_file} sh/t-sh64 sh/t-linux64"
-		tm_file="${tm_file} sh/sh64.h"
-		extra_headers="shmedia.h ushmedia.h sshmedia.h"
-		;;
-	sh4_single*) target_cpu_default="SELECT_SH4_SINGLE" ;;
-	sh4*) target_cpu_default="SELECT_SH4" ;;
-	sh3e[lb]e*) target_cpu_default="SELECT_SH3E" ;;
-	sh3e[lb]*) target_cpu_default="SELECT_SH3" ;;
-	sh3e*) target_cpu_default="SELECT_SH3E" ;;
-	sh3*) target_cpu_default="SELECT_SH3" ;;
-	sh2e[lb]e*) target_cpu_default="SELECT_SH2E" ;;
-	sh2e[lb]*) target_cpu_default="SELECT_SH2" ;;
-	sh2e*) target_cpu_default="SELECT_SH2E" ;;
-	sh2*) target_cpu_default="SELECT_SH2" ;;
-	esac
-	case ${target} in
-	sh[234]*) tmake_file="${tmake_file} sh/t-monolib" ;;
-	esac
-	;;
-sh-*-netbsdelf* | shl*-*-netbsdelf* | sh5-*-netbsd* | sh5l*-*-netbsd* | \
-  sh64-*-netbsd* | sh64l*-*-netbsd*)
-	tm_file="${tm_file} dbxelf.h elfos.h sh/elf.h netbsd.h netbsd-elf.h sh/netbsd-elf.h"
-	tmake_file="${tmake_file} sh/t-sh sh/t-elf"
-	case ${target} in
-	sh*l*-*)
-		tm_file="sh/little.h ${tm_file}"
-		tmake_file="${tmake_file} sh/t-le"
-		;;
-	*)
-		tmake_file="${tmake_file} sh/t-be"
-		;;
-	esac
-	case ${target} in
-	sh5*-*)
-		# SHmedia, 32-bit ABI
-		target_cpu_default="SH5_BIT|SH4_BIT|SH3_BIT|SH_E_BIT"
-		tmake_file="${tmake_file} sh/t-sh64 sh/t-netbsd-sh5"
-		;;
-	sh64*-*)
-		# SHmedia, 64-bit ABI
-		target_cpu_default="SH5_BIT|SH4_BIT"
-		tmake_file="${tmake_file} sh/t-sh64 sh/t-netbsd-sh5 sh/t-netbsd-sh5-64"
-		;;
-	*)
-		# SH3, software floating point
-		target_cpu_default="SH1_BIT|SH2_BIT|SH3_BIT"
-		tmake_file="${tmake_file} sh/t-netbsd"
-		;;
-	esac
-	;;
 sh-wrs-vxworks)
 	tmake_file="$tmake_file sh/t-sh sh/t-elf sh/t-vxworks"
 	tm_file="${tm_file} dbxelf.h elfos.h svr4.h sh/embed-elf.h sh/vxworks.h"
@@ -2435,6 +2462,19 @@ fi
 		esac
 		;;
 
+	sh[123456ble]-*-* | sh-*-*)
+		supported_defaults="cpu"
+		case "`echo $with_cpu | tr A-Z_ a-z- | sed s/sh/m/`" in
+		"" | m1 | m2 | m2e | m3 | m3e | m4 | m4-single | m4-single-only | m4-nofpu )
+			# OK
+			;;
+		*)
+			echo "Unknown CPU used in --with-cpu=$with_cpu, known values:"  1>&2
+			echo "m1 m2 m2e m3 m3e m4 m4-single m4-single-only m4-nofpu" 1>&2
+			exit 1
+			;;
+		esac
+		;;
 	sparc*-*-*)
 		supported_defaults="cpu float tune"
 
diff --git a/gcc/config/sh/elf.h b/gcc/config/sh/elf.h
index f5cfcb667b03..04c0c987fc33 100644
--- a/gcc/config/sh/elf.h
+++ b/gcc/config/sh/elf.h
@@ -58,9 +58,8 @@ Boston, MA 02111-1307, USA.  */
 #define ASM_SPEC SH_ASM_SPEC
 #undef SUBTARGET_ASM_ISA_SPEC
 #define SUBTARGET_ASM_ISA_SPEC "\
-%{m5-compact:--isa=SHcompact} %{m5-compact-nofpu:--isa=SHcompact} \
-%{m5-32media:--isa=SHmedia --abi=32} %{m5-32media-nofpu:--isa=SHmedia --abi=32} \
-%{m5-64media:--isa=SHmedia --abi=64} %{m5-64media-nofpu:--isa=SHmedia --abi=64}"
+%{m5-compact*:--isa=SHcompact} %{m5-32media*:--isa=SHmedia --abi=32} \
+%{m5-64media*:--isa=SHmedia --abi=64}" ASM_ISA_DEFAULT_SPEC
 
 #undef LINK_SPEC
 #define LINK_SPEC SH_LINK_SPEC
diff --git a/gcc/config/sh/netbsd-elf.h b/gcc/config/sh/netbsd-elf.h
index bb8d0339837f..b50344bdf50f 100644
--- a/gcc/config/sh/netbsd-elf.h
+++ b/gcc/config/sh/netbsd-elf.h
@@ -27,11 +27,11 @@ Boston, MA 02111-1307, USA.  */
 #endif
 
 #if TARGET_CPU_DEFAULT & SH5_BIT
-#if TARGET_CPU_DEFAULT & SH3E_BIT
+#if TARGET_CPU_DEFAULT & SH_E_BIT
 #define TARGET_VERSION_CPU "sh5"
 #else
 #define TARGET_VERSION_CPU "sh64"
-#endif /* SH3E_BIT */
+#endif /* SH_E_BIT */
 #else
 #define TARGET_VERSION_CPU "sh"
 #endif /* SH5_BIT */
@@ -63,17 +63,6 @@ Boston, MA 02111-1307, USA.  */
 
 /* LINK_EMUL_PREFIX from sh/elf.h */
 
-#undef LINK_DEFAULT_CPU_EMUL
-#if TARGET_CPU_DEFAULT & SH5_BIT
-#if TARGET_CPU_DEFAULT & SH3E_BIT
-#define LINK_DEFAULT_CPU_EMUL "32"
-#else
-#define LINK_DEFAULT_CPU_EMUL "64"
-#endif /* SH3E_BIT */
-#else
-#define LINK_DEFAULT_CPU_EMUL ""
-#endif /* SH5_BIT */
-
 #undef SUBTARGET_LINK_EMUL_SUFFIX
 #define SUBTARGET_LINK_EMUL_SUFFIX "_nbsd"
 
@@ -94,7 +83,7 @@ Boston, MA 02111-1307, USA.  */
   (TARGET_CPU_DEFAULT | USERMODE_BIT | TARGET_ENDIAN_DEFAULT)
 
 /* Define because we use the label and we do not need them.  */
-#define NO_PROFILE_COUNTERS
+#define NO_PROFILE_COUNTERS 1
  
 #undef FUNCTION_PROFILER
 #define FUNCTION_PROFILER(STREAM,LABELNO)				\
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 9cec69ad0c6c..f6154a322000 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -263,6 +263,14 @@ extern int target_flags;
 
 #define TARGET_SAVE_ALL_TARGET_REGS (target_flags & SAVE_ALL_TR_BIT)
 
+#ifndef TARGET_CPU_DEFAULT
+#define TARGET_CPU_DEFAULT SELECT_SH1
+#define SUPPORT_SH1
+#define SUPPORT_SH2E
+#define SUPPORT_SH4
+#define SUPPORT_SH4_SINGLE
+#endif
+
 #define SELECT_SH1               (SH1_BIT)
 #define SELECT_SH2               (SH2_BIT | SELECT_SH1)
 #define SELECT_SH2E              (SH_E_BIT | SH2_BIT | SH1_BIT | FPU_SINGLE_BIT)
@@ -272,48 +280,149 @@ extern int target_flags;
 #define SELECT_SH4_SINGLE_ONLY   (HARD_SH4_BIT | SELECT_SH3E)
 #define SELECT_SH4               (SH4_BIT | SH_E_BIT | HARD_SH4_BIT | SELECT_SH3)
 #define SELECT_SH4_SINGLE        (FPU_SINGLE_BIT | SELECT_SH4)
-#define SELECT_SH5_64            (SH5_BIT | SH4_BIT)
-#define SELECT_SH5_64_NOFPU      (SH5_BIT)
-#define SELECT_SH5_32            (SH5_BIT | SH4_BIT | SH_E_BIT)
-#define SELECT_SH5_32_NOFPU      (SH5_BIT | SH_E_BIT)
+#define SELECT_SH5_64MEDIA       (SH5_BIT | SH4_BIT)
+#define SELECT_SH5_64MEDIA_NOFPU (SH5_BIT)
+#define SELECT_SH5_32MEDIA       (SH5_BIT | SH4_BIT | SH_E_BIT)
+#define SELECT_SH5_32MEDIA_NOFPU (SH5_BIT | SH_E_BIT)
 #define SELECT_SH5_COMPACT       (SH5_BIT | SH4_BIT | SELECT_SH3E)
 #define SELECT_SH5_COMPACT_NOFPU (SH5_BIT | SELECT_SH3)
 
+/* Disable processor switches for which we have no suitable multilibs.  */
+#ifndef SUPPORT_SH1
+#define TARGET_SWITCH_SH1
+#ifndef SUPPORT_SH2
+#define TARGET_SWITCH_SH2
+#ifndef SUPPORT_SH3
+#define TARGET_SWITCH_SH3
+#ifndef SUPPORT_SH4_NOFPU
+#define TARGET_SWITCH_SH4_NOFPU
+#endif
+#endif
+#endif
+#endif
+
+#ifndef SUPPORT_SH2E
+#define TARGET_SWITCH_SH2E
+#ifndef SUPPORT_SH3E
+#define TARGET_SWITCH_SH3E
+#ifndef SUPPORT_SH4_SINGLE_ONLY
+#define TARGET_SWITCH_SH4_SINGLE_ONLY
+#endif
+#endif
+#endif
+
+#ifndef SUPPORT_SH4
+#define TARGET_SWITCH_SH4
+#endif
+
+#ifndef SUPPORT_SH4_SINGLE
+#define TARGET_SWITCH_SH4_SINGLE
+#endif
+
+#ifndef SUPPORT_SH5_64MEDIA
+#define TARGET_SWITCH_SH5_64MEDIA
+#endif
+
+#ifndef SUPPORT_SH5_64MEDIA_NOFPU
+#define TARGET_SWITCH_SH5_64MEDIA_NOFPU
+#endif
+
+#if !defined(SUPPORT_SH5_32MEDIA) && !defined (SUPPORT_SH5_COMPACT)
+#define TARGET_SWITCHES_SH5_32MEDIA
+#endif
+
+#if !defined(SUPPORT_SH5_32MEDIA_NOFPU) && !defined (SUPPORT_SH5_COMPACT_NOFPU)
+#define TARGET_SWITCHES_SH5_32MEDIA_NOFPU
+#endif
+
 /* Reset all target-selection flags.  */
 #define TARGET_NONE -(SH1_BIT | SH2_BIT | SH3_BIT | SH_E_BIT | SH4_BIT \
 		      | HARD_SH4_BIT | FPU_SINGLE_BIT | SH5_BIT)
 
-#define TARGET_SWITCHES  			\
-{ {"1",	        TARGET_NONE, "" },		\
-  {"1",	        SELECT_SH1, "Generate SH1 code" },		\
-  {"2",	        TARGET_NONE, "" },		\
-  {"2",	        SELECT_SH2, "Generate SH2 code" },		\
-  {"2e",        TARGET_NONE, "" },		\
-  {"2e",        SELECT_SH2E, "Generate SH2e code" },		\
-  {"3",	        TARGET_NONE, "" },		\
-  {"3",	        SELECT_SH3, "Generate SH3 code" },		\
-  {"3e",	TARGET_NONE, "" },		\
-  {"3e",	SELECT_SH3E, "Generate SH3e code" },		\
-  {"4-single-only",	TARGET_NONE, "" },	\
-  {"4-single-only",	SELECT_SH4_SINGLE_ONLY, "Generate only single-precision SH4 code" },	\
-  {"4-single",	TARGET_NONE, "" },		\
-  {"4-single",	SELECT_SH4_SINGLE, "Generate default single-precision SH4 code" },	\
-  {"4-nofpu",	TARGET_NONE, "" },		\
-  {"4-nofpu",	SELECT_SH4_NOFPU, "Generate SH4 FPU-less code" },		\
-  {"4",	        TARGET_NONE, "" },		\
-  {"4",	        SELECT_SH4, "Generate SH4 code" }, 		\
+#ifndef TARGET_SWITCH_SH1
+#define TARGET_SWITCH_SH1 \
+  {"1",		TARGET_NONE, "" }, \
+  {"1",		SELECT_SH1, "Generate SH1 code" },
+#endif
+#ifndef TARGET_SWITCH_SH2
+#define TARGET_SWITCH_SH2 \
+  {"2",		TARGET_NONE, "" }, \
+  {"2",		SELECT_SH2, "Generate SH2 code" },
+#endif
+#ifndef TARGET_SWITCH_SH2E
+#define TARGET_SWITCH_SH2E \
+  {"2e",	TARGET_NONE, "" }, \
+  {"2e",	SELECT_SH2E, "Generate SH2e code" },
+#endif
+#ifndef TARGET_SWITCH_SH3
+#define TARGET_SWITCH_SH3 \
+  {"3",		TARGET_NONE, "" }, \
+  {"3",		SELECT_SH3, "Generate SH3 code" },
+#endif
+#ifndef TARGET_SWITCH_SH3E
+#define TARGET_SWITCH_SH3E \
+  {"3e",	TARGET_NONE, "" }, \
+  {"3e",	SELECT_SH3E, "Generate SH3e code" },
+#endif
+#ifndef TARGET_SWITCH_SH4_SINGLE_ONLY
+#define TARGET_SWITCH_SH4_SINGLE_ONLY \
+  {"4-single-only",	TARGET_NONE, "" }, \
+  {"4-single-only",	SELECT_SH4_SINGLE_ONLY, "Generate only single-precision SH4 code" },
+#endif
+#ifndef TARGET_SWITCH_SH4_SINGLE
+#define TARGET_SWITCH_SH4_SINGLE \
+  {"4-single",	TARGET_NONE, "" }, \
+  {"4-single",	SELECT_SH4_SINGLE, "Generate default single-precision SH4 code" },
+#endif
+#ifndef TARGET_SWITCH_SH4_NOFPU
+#define TARGET_SWITCH_SH4_NOFPU \
+  {"4-nofpu",	TARGET_NONE, "" }, \
+  {"4-nofpu",	SELECT_SH4_NOFPU, "Generate SH4 FPU-less code" },
+#endif
+#ifndef TARGET_SWITCH_SH4
+#define TARGET_SWITCH_SH4 \
+  {"4",		TARGET_NONE, "" }, \
+  {"4",		SELECT_SH4, "Generate SH4 code" },
+#endif
+#ifndef TARGET_SWITCH_SH5_64MEDIA
+#define TARGET_SWITCH_SH5_64MEDIA \
   {"5-64media",	TARGET_NONE, "" },		\
-  {"5-64media", SELECT_SH5_64, "Generate 64-bit SHmedia code" }, \
+  {"5-64media", SELECT_SH5_64MEDIA, "Generate 64-bit SHmedia code" },
+#endif
+#ifndef TARGET_SWITCH_SH5_64MEDIA_NOFPU
+#define TARGET_SWITCH_SH5_64MEDIA_NOFPU \
   {"5-64media-nofpu", TARGET_NONE, "" },	\
-  {"5-64media-nofpu", SELECT_SH5_64_NOFPU, "Generate 64-bit FPU-less SHmedia code" }, \
+  {"5-64media-nofpu", SELECT_SH5_64MEDIA_NOFPU, "Generate 64-bit FPU-less SHmedia code" },
+#endif
+#ifndef TARGET_SWITCHES_SH5_32MEDIA
+#define TARGET_SWITCHES_SH5_32MEDIA \
   {"5-32media",	TARGET_NONE, "" },		\
-  {"5-32media", SELECT_SH5_32, "Generate 32-bit SHmedia code" }, \
-  {"5-32media-nofpu", TARGET_NONE, "" },	\
-  {"5-32media-nofpu", SELECT_SH5_32_NOFPU, "Generate 32-bit FPU-less SHmedia code" }, \
+  {"5-32media", SELECT_SH5_32MEDIA, "Generate 32-bit SHmedia code" }, \
   {"5-compact",	TARGET_NONE, "" },		\
-  {"5-compact",	SELECT_SH5_COMPACT, "Generate SHcompact code" }, \
+  {"5-compact",	SELECT_SH5_COMPACT, "Generate SHcompact code" },
+#endif
+#ifndef TARGET_SWITCHES_SH5_32MEDIA_NOFPU
+#define TARGET_SWITCHES_SH5_32MEDIA_NOFPU \
+  {"5-32media-nofpu", TARGET_NONE, "" },	\
+  {"5-32media-nofpu", SELECT_SH5_32MEDIA_NOFPU, "Generate 32-bit FPU-less SHmedia code" }, \
   {"5-compact-nofpu", TARGET_NONE, "" },	\
-  {"5-compact-nofpu", SELECT_SH5_COMPACT_NOFPU, "Generate FPU-less SHcompact code" }, \
+  {"5-compact-nofpu", SELECT_SH5_COMPACT_NOFPU, "Generate FPU-less SHcompact code" },
+#endif
+
+#define TARGET_SWITCHES \
+{ TARGET_SWITCH_SH1 \
+  TARGET_SWITCH_SH2 \
+  TARGET_SWITCH_SH2E \
+  TARGET_SWITCH_SH3 \
+  TARGET_SWITCH_SH3E \
+  TARGET_SWITCH_SH4_SINGLE_ONLY \
+  TARGET_SWITCH_SH4_SINGLE \
+  TARGET_SWITCH_SH4_NOFPU \
+  TARGET_SWITCH_SH4 \
+  TARGET_SWITCH_SH5_64MEDIA \
+  TARGET_SWITCH_SH5_64MEDIA_NOFPU \
+  TARGET_SWITCHES_SH5_32MEDIA \
+  TARGET_SWITCHES_SH5_32MEDIA_NOFPU \
   {"b",		-LITTLE_ENDIAN_BIT, "Generate code in big endian mode" },  	\
   {"bigtable", 	BIGTABLE_BIT, "Generate 32-bit offsets in switch tables" },		\
   {"dalign",  	DALIGN_BIT, "Aligns doubles at 64-bit boundaries" },		\
@@ -342,11 +451,17 @@ extern int target_flags;
 #define TARGET_ENDIAN_DEFAULT 0
 #endif
 
-#ifndef TARGET_CPU_DEFAULT
-#define TARGET_CPU_DEFAULT SELECT_SH1
+#define TARGET_DEFAULT  (TARGET_CPU_DEFAULT|TARGET_ENDIAN_DEFAULT)
+
+#ifndef SH_MULTILIB_CPU_DEFAULT
+#define SH_MULTILIB_CPU_DEFAULT "m1"
 #endif
 
-#define TARGET_DEFAULT  (TARGET_CPU_DEFAULT|TARGET_ENDIAN_DEFAULT)
+#if TARGET_ENDIAN_DEFAULT
+#define MULTILIB_DEFAULTS { "ml", SH_MULTILIB_CPU_DEFAULT }
+#else
+#define MULTILIB_DEFAULTS { "mb", SH_MULTILIB_CPU_DEFAULT }
+#endif
 
 #define CPP_SPEC " %(subtarget_cpp_spec) "
 
@@ -396,11 +511,20 @@ extern int target_flags;
 #if TARGET_CPU_DEFAULT & SH5_BIT
 #if TARGET_CPU_DEFAULT & SH_E_BIT
 #define LINK_DEFAULT_CPU_EMUL "32"
+#if TARGET_CPU_DEFAULT & SH1_BIT
+#define ASM_ISA_SPEC_DEFAULT "--isa=SHcompact"
 #else
+#define ASM_ISA_SPEC_DEFAULT "--isa=SHmedia --abi=32"
+#endif /* SH1_BIT */
+#else /* !SH_E_BIT */
 #define LINK_DEFAULT_CPU_EMUL "64"
+#define ASM_ISA_SPEC_DEFAULT "--isa=SHmedia --abi=64"
 #endif /* SH_E_BIT */
-#else
+#define ASM_ISA_DEFAULT_SPEC \
+" %{!m1:%{!m2*:%{!m3*:%{!m4*:%{!m5*:" ASM_ISA_SPEC_DEFAULT "}}}}}"
+#else /* !SH5_BIT */
 #define LINK_DEFAULT_CPU_EMUL ""
+#define ASM_ISA_DEFAULT_SPEC ""
 #endif /* SH5_BIT */
 
 #define SUBTARGET_LINK_EMUL_SUFFIX ""
diff --git a/gcc/config/sh/sh64.h b/gcc/config/sh/sh64.h
index 1cc999ddcf85..522cbb803b22 100644
--- a/gcc/config/sh/sh64.h
+++ b/gcc/config/sh/sh64.h
@@ -23,19 +23,5 @@ Boston, MA 02111-1307, USA.  */
 #define TARGET_VERSION \
   fputs (" (SuperH SH)", stderr);
 
-#undef ASM_SPEC
-#define ASM_SPEC  "%(subtarget_asm_endian_spec) %{mrelax:-relax} \
-%{m5-compact*:--isa=SHcompact} \
-%{m5-32media*:--isa=SHmedia --abi=32} \
-%{m5-64media*:--isa=SHmedia --abi=64} \
-%{!m1:%{!m2:%{!m3*:%{!m4*:%{!m5*:--isa=SHmedia --abi=32}}}}} \
-"
-
-#undef LINK_DEFAULT_CPU_EMUL
-#define LINK_DEFAULT_CPU_EMUL "32"
-
-#undef TARGET_DEFAULT
-#define TARGET_DEFAULT  (SH5_BIT|SH4_BIT|SH_E_BIT|TARGET_ENDIAN_DEFAULT)
-
 #undef SH_ELF_WCHAR_TYPE
 #define SH_ELF_WCHAR_TYPE "int"
diff --git a/gcc/config/sh/t-1e b/gcc/config/sh/t-1e
new file mode 100644
index 000000000000..74b0f9a606a7
--- /dev/null
+++ b/gcc/config/sh/t-1e
@@ -0,0 +1 @@
+MULTILIB_ENDIAN =
diff --git a/gcc/config/sh/t-be b/gcc/config/sh/t-be
deleted file mode 100644
index 2e81cd97b618..000000000000
--- a/gcc/config/sh/t-be
+++ /dev/null
@@ -1,2 +0,0 @@
-MULTILIB_OPTIONS= ml
-MULTILIB_ENDIAN = ml
diff --git a/gcc/config/sh/t-elf b/gcc/config/sh/t-elf
index 29807d79c241..feccbb3490b0 100644
--- a/gcc/config/sh/t-elf
+++ b/gcc/config/sh/t-elf
@@ -6,4 +6,5 @@ CRTSTUFF_T_CFLAGS_S = -fPIC
 
 # Don't compile libgcc with -fpic for now.  It's unlikely that we'll
 # build shared libraries for embedded SH.
+# Linux / Netbsd will already have set TARGET_LIBGCC2_CFLAGS.
 # TARGET_LIBGCC2_CFLAGS = -fpic
diff --git a/gcc/config/sh/t-le b/gcc/config/sh/t-le
deleted file mode 100644
index 3c676f51b334..000000000000
--- a/gcc/config/sh/t-le
+++ /dev/null
@@ -1,2 +0,0 @@
-MULTILIB_OPTIONS= mb
-MULTILIB_ENDIAN = mb
diff --git a/gcc/config/sh/t-linux b/gcc/config/sh/t-linux
index 12969d2f8e61..cd810e8343dc 100644
--- a/gcc/config/sh/t-linux
+++ b/gcc/config/sh/t-linux
@@ -3,7 +3,6 @@ LIB1ASMFUNCS_CACHE = _ic_invalidate
 
 LIB2FUNCS_EXTRA=
 
-MULTILIB_OPTIONS= $(MULTILIB_ENDIAN) m3e/m4
 MULTILIB_DIRNAMES= 
 MULTILIB_MATCHES = 
 MULTILIB_EXCEPTIONS=
diff --git a/gcc/config/sh/t-mlib-sh1 b/gcc/config/sh/t-mlib-sh1
new file mode 100644
index 000000000000..9ba70541c6c1
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh1
@@ -0,0 +1 @@
+ML_sh1=m1/
diff --git a/gcc/config/sh/t-mlib-sh2 b/gcc/config/sh/t-mlib-sh2
new file mode 100644
index 000000000000..d8857bab66bd
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh2
@@ -0,0 +1 @@
+ML_sh2=m2/
diff --git a/gcc/config/sh/t-mlib-sh2e b/gcc/config/sh/t-mlib-sh2e
new file mode 100644
index 000000000000..58841327cfed
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh2e
@@ -0,0 +1 @@
+ML_sh2e=m2e/
diff --git a/gcc/config/sh/t-mlib-sh3 b/gcc/config/sh/t-mlib-sh3
new file mode 100644
index 000000000000..2c89d749a997
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh3
@@ -0,0 +1 @@
+ML_sh3=m3/
diff --git a/gcc/config/sh/t-mlib-sh3e b/gcc/config/sh/t-mlib-sh3e
new file mode 100644
index 000000000000..ca18b1bcf8b4
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh3e
@@ -0,0 +1 @@
+ML_sh3e=m3e/
diff --git a/gcc/config/sh/t-mlib-sh4 b/gcc/config/sh/t-mlib-sh4
new file mode 100644
index 000000000000..be7f5c4febdc
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh4
@@ -0,0 +1 @@
+ML_sh4=m4/
diff --git a/gcc/config/sh/t-mlib-sh4-nofpu b/gcc/config/sh/t-mlib-sh4-nofpu
new file mode 100644
index 000000000000..fa12433714be
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh4-nofpu
@@ -0,0 +1 @@
+ML_sh4_nofpu=m4-nofpu/
diff --git a/gcc/config/sh/t-mlib-sh4-single b/gcc/config/sh/t-mlib-sh4-single
new file mode 100644
index 000000000000..f81bddd1efe3
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh4-single
@@ -0,0 +1 @@
+ML_sh4_single=m4-single/
diff --git a/gcc/config/sh/t-mlib-sh4-single-only b/gcc/config/sh/t-mlib-sh4-single-only
new file mode 100644
index 000000000000..121d598d69fe
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh4-single-only
@@ -0,0 +1 @@
+ML_sh4_single_only=m4-single-only/
diff --git a/gcc/config/sh/t-mlib-sh5-32media b/gcc/config/sh/t-mlib-sh5-32media
new file mode 100644
index 000000000000..f03fd2911539
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh5-32media
@@ -0,0 +1 @@
+ML_sh5_32media=m5-32media/
diff --git a/gcc/config/sh/t-mlib-sh5-32media-nofpu b/gcc/config/sh/t-mlib-sh5-32media-nofpu
new file mode 100644
index 000000000000..0d84f0eed776
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh5-32media-nofpu
@@ -0,0 +1 @@
+ML_sh5_32media_nofpu=m5-32media-nofpu/
diff --git a/gcc/config/sh/t-mlib-sh5-64media b/gcc/config/sh/t-mlib-sh5-64media
new file mode 100644
index 000000000000..d324f62b5b82
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh5-64media
@@ -0,0 +1 @@
+ML_sh5_64media=m5-64media/
diff --git a/gcc/config/sh/t-mlib-sh5-64media-nofpu b/gcc/config/sh/t-mlib-sh5-64media-nofpu
new file mode 100644
index 000000000000..127bc47e45e8
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh5-64media-nofpu
@@ -0,0 +1 @@
+ML_sh5_64media_nofpu=m5-64media-nofpu/
diff --git a/gcc/config/sh/t-mlib-sh5-compact b/gcc/config/sh/t-mlib-sh5-compact
new file mode 100644
index 000000000000..e330c25e69e6
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh5-compact
@@ -0,0 +1 @@
+ML_sh5_compact=m5-compact/
diff --git a/gcc/config/sh/t-mlib-sh5-compact-nofpu b/gcc/config/sh/t-mlib-sh5-compact-nofpu
new file mode 100644
index 000000000000..cf6afdc4d3c0
--- /dev/null
+++ b/gcc/config/sh/t-mlib-sh5-compact-nofpu
@@ -0,0 +1 @@
+ML_sh5_compact_nofpu=m5-compact-nofpu/
diff --git a/gcc/config/sh/t-monolib b/gcc/config/sh/t-monolib
deleted file mode 100644
index 6150d59e0987..000000000000
--- a/gcc/config/sh/t-monolib
+++ /dev/null
@@ -1 +0,0 @@
-MULTILIB_OPTIONS=
diff --git a/gcc/config/sh/t-netbsd b/gcc/config/sh/t-netbsd
index bdb444289938..c19b71504464 100644
--- a/gcc/config/sh/t-netbsd
+++ b/gcc/config/sh/t-netbsd
@@ -11,8 +11,3 @@ EXTRA_MULTILIB_PARTS=
 # in libgcc.
 FPBIT =
 DPBIT =
-
-MULTILIB_OPTIONS += m3e/m4
-MULTILIB_DIRNAMES=
-MULTILIB_MATCHES = 
-MULTILIB_EXCEPTIONS=
diff --git a/gcc/config/sh/t-netbsd-sh5 b/gcc/config/sh/t-netbsd-sh5
deleted file mode 100644
index 61e6c53ce63a..000000000000
--- a/gcc/config/sh/t-netbsd-sh5
+++ /dev/null
@@ -1,12 +0,0 @@
-TARGET_LIBGCC2_CFLAGS = -fpic
-
-LIB2FUNCS_EXTRA=
-
-EXTRA_MULTILIB_PARTS=
-
-# NetBSD's C library includes a fast software FP library that
-# has support for setting/setting the rounding mode, exception
-# mask, etc.  Therefore, we don't want to include software FP
-# in libgcc.
-FPBIT =
-DPBIT =
diff --git a/gcc/config/sh/t-netbsd-sh5-64 b/gcc/config/sh/t-netbsd-sh5-64
index 3555042ca8b8..8fc6bd1ea182 100644
--- a/gcc/config/sh/t-netbsd-sh5-64
+++ b/gcc/config/sh/t-netbsd-sh5-64
@@ -1,3 +1 @@
-MULTILIB_OPTIONS = $(MULTILIB_ENDIAN) m5-64media-nofpu/m5-compact/m5-compact-nofpu/m5-32media/m5-32media-nofpu
-MULTILIB_DIRNAMES= $(MULTILIB_ENDIAN) nofpu compact nofpu/compact media32 nofpu/media32
-MULTILIB_MATCHES =
+MULTILIB_DIRNAMES= $(MULTILIB_RAW_DIRNAMES:/media64=)
diff --git a/gcc/config/sh/t-sh b/gcc/config/sh/t-sh
index 15aaba1ece68..11ab0c36bcda 100644
--- a/gcc/config/sh/t-sh
+++ b/gcc/config/sh/t-sh
@@ -21,11 +21,30 @@ fp-bit.c: $(srcdir)/config/fp-bit.c
 	echo '#endif' 		>> fp-bit.c
 	cat $(srcdir)/config/fp-bit.c >> fp-bit.c
 
-MULTILIB_ENDIAN = ml
-MULTILIB_OPTIONS= $(MULTILIB_ENDIAN) m2/m2e/m4-single-only/m4-single/m4
+MULTILIB_ENDIAN = ml/mb
+MULTILIB_CPUS= $(ML_sh1)$(ML_sh2e)$(ML_sh2)$(ML_sh3e)$(ML_sh3)$(ML_sh4_nofpu)$(ML_sh4_single_only)$(ML_sh4_single)$(ML_sh4)$(ML_m5_32media)$(ML_m5_32media_nofpu)$(ML_m5_compact)$(ML_m5_compact_nofpu)$(ML_m5_64media)$(ML_m5_64media_nofpu)
+
+MULTILIB_OPTIONS= $(MULTILIB_ENDIAN) $(MULTILIB_CPUS:/=)
 MULTILIB_DIRNAMES= 
-MULTILIB_MATCHES = m2=m3 m2e=m3e m2=m4-nofpu
-MULTILIB_EXCEPTIONS = ml
+#MULTILIB_MATCHES = m2=m3 m2e=m3e m2=m4-nofpu
+MULTILIB_MATCHES = $(shell \
+  multilibs="$(MULTILIB_OPTIONS)" ; \
+  for abi in m1,m2,m3,m4-nofpu \
+             m2e,m3e,m4-single-only \
+             m5-32media,m5-compact,m5-32media \
+             m5-32media-nofpu,m5-compact-nofpu,m5-32media-nofpu; do \
+    subst= ; \
+    for lib in `echo $$abi|tr , ' '` ; do \
+      if test "`echo $$multilibs|sed s/$$lib//`" != "$$multilibs"; then \
+        subst=$$lib ; \
+      elif test x$$subst != x ; then \
+        echo $$subst=$$lib ; \
+      fi \
+    done \
+  done)
+
+# SH1 only supports big endian.
+MULTILIB_EXCEPTIONS = ml/m1
 
 LIBGCC = stmp-multilib
 INSTALL_LIBGCC = install-multilib
diff --git a/gcc/config/sh/t-sh64 b/gcc/config/sh/t-sh64
index 7e6ac1a4b800..5ee83ba86329 100644
--- a/gcc/config/sh/t-sh64
+++ b/gcc/config/sh/t-sh64
@@ -7,7 +7,7 @@ LIB1ASMFUNCS = \
   _push_pop_shmedia_regs \
   _udivdi3 _divdi3 _umoddi3 _moddi3
 
-MULTILIB_OPTIONS = $(MULTILIB_ENDIAN) m5-32media-nofpu/m5-compact/m5-compact-nofpu/m5-64media/m5-64media-nofpu
-MULTILIB_DIRNAMES= $(MULTILIB_ENDIAN) nofpu compact nofpu/compact media64 nofpu/media64
-MULTILIB_MATCHES=
-MULTILIB_EXCEPTIONS=
+MULTILIB_CPU_DIRS= $(ML_sh1) $(ML_sh2e) $(ML_sh2) $(ML_sh3e) $(ML_sh3) $(ML_sh4_nofpu) $(ML_sh4_single_only) $(ML_sh4_single) $(ML_sh4) $(ML_m5_32media:m5_32media=media32) $(ML_m5_32media_nofpu:m5_32media_nofpu=nofpu/media32) $(ML_m5_compact:m5_compact=compact) $(ML_m5_compact_nofpu:m5_compact_nofpu=nofpu/compact) $(ML_m5_64media:m5_64media=media64) $(ML_m5_64media_nofpu:m5_64media_nofpu=nofpu/media64)
+
+MULTILIB_RAW_DIRNAMES= $(MULTILIB_ENDIAN:/mb= mb) $(MULTILIB_CPU_DIRS:/=)
+MULTILIB_DIRNAMES= $(MULTILIB_RAW_DIRNAMES:/media32=)