public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 0/4] LoongArch: target configuration interface update
@ 2023-08-30  1:58 Yang Yujie
  2023-08-30  1:58 ` [PATCH v2 1/4] LoongArch: improved target configuration interface Yang Yujie
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Yang Yujie @ 2023-08-30  1:58 UTC (permalink / raw)
  To: gcc-patches; +Cc: xuchenghua, chenglulu, panchenghui, xry111, Yang Yujie

This is an update of
https://gcc.gnu.org/pipermail/gcc-patches/2023-August/627275.html

Changes since the last patchset:

1. Add new configure option --with-strict-align-lib to control
   whether -mstrict-align should be used when building libraries.
   This facilitates building toolchains targeting both LA264
   (Loongson 2k1000la) and non-LA264 cores.

2. Define preprocessing macros  __loongarch_sx / __loongarch_asx
   / __loongarch_simd_width that indicates the enabled SIMD
   extensions.

3. Keep the current non-symmetric multidir layout, but do not build
   duplicate multilib variants with the same ABI option.  Make
   --with-abi= obsolete to ensure a consistent directory layout.
   (ABI type of the "toplevel" libraries can be inferred from the
    target triplet)

4. Using "-mno-lasx" do not cause a fallback to "-msimd=none" as
   long as the -march= architecture or the default --with-simd=
   setting has LSX support.

5. Other bug fixes.

Yang Yujie (4):
  LoongArch: improved target configuration interface
  LoongArch: define preprocessing macros "__loongarch_{arch,tune}"
  LoongArch: add new configure option --with-strict-align-lib
  LoongArch: support loongarch*-elf target

 config-ml.in                                  |  10 +
 gcc/config.gcc                                | 408 ++++++++++--------
 gcc/config/loongarch/elf.h                    |  52 +++
 .../loongarch/genopts/loongarch-strings       |   8 +-
 gcc/config/loongarch/genopts/loongarch.opt.in |  62 ++-
 gcc/config/loongarch/la464.md                 |  32 +-
 gcc/config/loongarch/loongarch-c.cc           |  22 +-
 gcc/config/loongarch/loongarch-cpu.cc         | 263 ++++++-----
 gcc/config/loongarch/loongarch-cpu.h          |   3 +-
 gcc/config/loongarch/loongarch-def.c          |  67 +--
 gcc/config/loongarch/loongarch-def.h          |  57 +--
 gcc/config/loongarch/loongarch-driver.cc      | 208 +++++----
 gcc/config/loongarch/loongarch-driver.h       |  40 +-
 gcc/config/loongarch/loongarch-opts.cc        | 372 +++++++++++-----
 gcc/config/loongarch/loongarch-opts.h         |  59 +--
 gcc/config/loongarch/loongarch-str.h          |   7 +-
 gcc/config/loongarch/loongarch.cc             |  87 ++--
 gcc/config/loongarch/loongarch.opt            |  60 ++-
 gcc/config/loongarch/t-linux                  |  32 +-
 gcc/doc/install.texi                          |  46 +-
 gcc/doc/invoke.texi                           |  32 +-
 libgcc/config.host                            |   9 +-
 22 files changed, 1254 insertions(+), 682 deletions(-)
 create mode 100644 gcc/config/loongarch/elf.h

-- 
2.36.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 1/4] LoongArch: improved target configuration interface
  2023-08-30  1:58 [PATCH 0/4] LoongArch: target configuration interface update Yang Yujie
@ 2023-08-30  1:58 ` Yang Yujie
  2023-08-30 21:36   ` Joseph Myers
  2023-08-30  1:58 ` [PATCH v2 2/4] LoongArch: define preprocessing macros "__loongarch_{arch,tune}" Yang Yujie
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 14+ messages in thread
From: Yang Yujie @ 2023-08-30  1:58 UTC (permalink / raw)
  To: gcc-patches; +Cc: xuchenghua, chenglulu, panchenghui, xry111, Yang Yujie

The configure script and the GCC driver are updated so that
it is easier to customize and control GCC builds for targeting
different LoongArch implementations.

* Make --with-abi obsolete, since it might cause different default ABI
  under the same target triplet, which is undesirable.  The default ABI
  is now purely decided by the target triplet.

* Support options for LoongArch SIMD extensions:
  new configure options --with-simd={none,lsx,lasx};
  new compiler option -msimd={none,lsx,lasx};
  new driver options -m[no]-l[a]sx.

* Enforce the priority of configuration paths (for <parm>={fpu,tune,simd}):
  -m<parm> > -march-implied > --with-<parm> > --with-arch-implied.

* Allow the user to control the compiler options used when building
  GCC libraries for each multilib variant via --with-multilib-list
  and --with-multilib-default.  This could become more useful when
  we have 32-bit support later.

  Example 1: the following configure option
    --with-multilib-list=lp64d/la464/mno-strict-align/msimd=lsx,lp64s/mfpu=32
                          |     |            |         |
                    -mabi=ABI  -march=ARCH  a list of other options
                  (mandatory)  (optional)     (optional)

       builds two sets of libraries:
          lp64d ABI (the default ABI if no --with-abi is given,
                     built with "-march=la464 -mno-strict-align")
          lp64s ABI (built with "-march=abi-default -mfpu=32")

  Example 2: the following 3 configure options

    --with-arch=loongarch64
    --with-multilib-list=lp64d,lp64f,lp64s/la464
    --with-multilib-default=fixed/mno-strict-align/mfpu=64
                             |            |           |
                        -march=ARCH   a list of other options
                         (optional)        (optional)

    is equivalent to (in terms of building libraries):

    --with-multilib-list=\
    lp64d/loongarch64/mno-strict-align/mfpu=64,\
    lp64f/loongarch64/mno-strict-align/mfpu=64,\
    lp64s/la464

  Note:
    1. the GCC driver and compiler proper does not support
       "-march=fixed". "fixed" that appear here acts as a placeholder for
       "use whatever ARCH in --with-arch=ARCH" (or the default value
       of --with-arch=ARCH if --with-arch is not explicitly configured).

    2. if the ARCH part is omitted, "-march=abi-default"
       is used for building all library variants, which
       practically means enabling the minimal ISA features
       that can support the given ABI.

ChangeLog:

	* config-ml.in: Do not build the multilib library variant
	that is duplicate with the toplevel one.

gcc/ChangeLog:

	* config.gcc: Make --with-abi= obsolete, decide the default ABI
	with target triplet.  Allow specifying multilib library build
	options with --with-multilib-list and --with-multilib-default.
	* config/loongarch/t-linux: Likewise.
	* config/loongarch/genopts/loongarch-strings: Likewise.
	* config/loongarch/loongarch-str.h: Likewise.
	* doc/install.texi: Likewise.
	* config/loongarch/genopts/loongarch.opt.in: Introduce
	-m[no-]l[a]sx options.  Only process -m*-float and
	-m[no-]l[a]sx in the GCC driver.
	* config/loongarch/loongarch.opt: Likewise.
	* config/loongarch/la464.md: Likewise.
	* config/loongarch/loongarch-c.cc: Likewise.
	* config/loongarch/loongarch-cpu.cc: Likewise.
	* config/loongarch/loongarch-cpu.h: Likewise.
	* config/loongarch/loongarch-def.c: Likewise.
	* config/loongarch/loongarch-def.h: Likewise.
	* config/loongarch/loongarch-driver.cc: Likewise.
	* config/loongarch/loongarch-driver.h: Likewise.
	* config/loongarch/loongarch-opts.cc: Likewise.
	* config/loongarch/loongarch-opts.h: Likewise.
	* config/loongarch/loongarch.cc: Likewise.
	* doc/invoke.texi: Likewise.
---
 config-ml.in                                  |  10 +
 gcc/config.gcc                                | 379 ++++++++++--------
 .../loongarch/genopts/loongarch-strings       |   8 +-
 gcc/config/loongarch/genopts/loongarch.opt.in |  62 +--
 gcc/config/loongarch/la464.md                 |  32 +-
 gcc/config/loongarch/loongarch-c.cc           |  19 +-
 gcc/config/loongarch/loongarch-cpu.cc         | 263 +++++++-----
 gcc/config/loongarch/loongarch-cpu.h          |   3 +-
 gcc/config/loongarch/loongarch-def.c          |  67 ++--
 gcc/config/loongarch/loongarch-def.h          |  57 +--
 gcc/config/loongarch/loongarch-driver.cc      | 208 +++++-----
 gcc/config/loongarch/loongarch-driver.h       |  40 +-
 gcc/config/loongarch/loongarch-opts.cc        | 372 ++++++++++++-----
 gcc/config/loongarch/loongarch-opts.h         |  59 +--
 gcc/config/loongarch/loongarch-str.h          |   7 +-
 gcc/config/loongarch/loongarch.cc             |  87 ++--
 gcc/config/loongarch/loongarch.opt            |  60 ++-
 gcc/config/loongarch/t-linux                  |  32 +-
 gcc/doc/install.texi                          |  46 ++-
 gcc/doc/invoke.texi                           |  32 +-
 20 files changed, 1164 insertions(+), 679 deletions(-)

diff --git a/config-ml.in b/config-ml.in
index 68854a4f16c..ad0db078171 100644
--- a/config-ml.in
+++ b/config-ml.in
@@ -301,6 +301,16 @@ arm-*-*)
 	  done
 	fi
 	;;
+loongarch*-*)
+	old_multidirs="${multidirs}"
+	multidirs=""
+	for x in ${old_multidirs}; do
+	case "$x" in
+	`${CC-gcc} --print-multi-directory`) : ;;
+	*) multidirs="${multidirs} ${x}" ;;
+	esac
+	done
+	;;
 m68*-*-*)
 	if [ x$enable_softfloat = xno ]
 	then
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 415e0e1ebc5..4fae672a3b7 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -4891,43 +4891,46 @@ case "${target}" in
 		esac
 		;;
 
-	loongarch*-*-*)
-		supported_defaults="abi arch tune fpu"
+	loongarch*-*)
+		supported_defaults="abi arch tune fpu simd multilib-default"
 
 		# Local variables
 		unset \
-			abi_pattern      abi_default    \
-			abiext_pattern   abiext_default \
-			arch_pattern     arch_default   \
-			fpu_pattern      fpu_default    \
-			tune_pattern     tune_default   \
-			triplet_os       triplet_abi
+			abi_base	abi_ext \
+			arch_pattern	arch_default \
+			fpu_pattern	fpu_default \
+			triplet_os	triplet_abi \
+			strict_align_opt
+
+		# --with-abi is now obsolete, emit a warning if given.
+		case ${with_abi} in
+		"") ;;
+		*)
+			echo "warning: --with-abi= is now obsolete," \
+			"the default ABI is derived from your target" \
+			"triplet ${target}" 1>&2
+			;;
+		esac
 
 		# Infer ABI from the triplet.
 		case ${target} in
-		loongarch64-*-*-*f64)
-			abi_pattern="lp64d"
-			;;
-		loongarch64-*-*-*f32)
-			abi_pattern="lp64f"
-			;;
-		loongarch64-*-*-*sf)
-			abi_pattern="lp64s"
-			;;
-		loongarch64-*-*-*)
-			abi_pattern="lp64[dfs]"
-			abi_default="lp64d"
-			;;
+		loongarch64-*f64) abi_base="lp64d"; abi_ext="base" ;;
+		loongarch64-*f32) abi_base="lp64f"; abi_ext="base" ;;
+		loongarch64-*sf)  abi_base="lp64s"; abi_ext="base" ;;
+		loongarch64-*)    abi_base="lp64d"; abi_ext="base" ;;
 		*)
 			echo "Unsupported target ${target}." 1>&2
 			exit 1
 			;;
 		esac
 
-		abiext_pattern="*"
-		abiext_default="base"
-
 		# Get the canonical triplet (multiarch specifier).
+		case ${abi_base},${abi_ext} in
+		lp64d,base) triplet_abi="";;
+		lp64f,base) triplet_abi="f32";;
+		lp64s,base) triplet_abi="sf";;
+		esac
+
 		case ${target} in
 		  *-linux-gnu*)  triplet_os="linux-gnu";;
 		  *-linux-musl*) triplet_os="linux-musl";;
@@ -4936,42 +4939,24 @@ case "${target}" in
 			  exit 1
 			  ;;
 		esac
+		la_canonical_triplet="loongarch64-${triplet_os}${triplet_abi}"
+
 
 		# Perform initial sanity checks on --with-* options.
 		case ${with_arch} in
-		"" | loongarch64 | la464) ;; # OK, append here.
+		"" | abi-default | loongarch64 | la464) ;; # OK, append here.
 		native)
 			if test x${host} != x${target}; then
 				echo "--with-arch=native is illegal for cross-compiler." 1>&2
 				exit 1
 			fi
 			;;
-		"")
-			echo "Please set a default value for \${with_arch}" \
-			     "according to your target triplet \"${target}\"." 1>&2
-			exit 1
-			;;
 		*)
 			echo "Unknown arch in --with-arch=$with_arch" 1>&2
 			exit 1
 			;;
 		esac
 
-		case ${with_abi} in
-		"" | lp64d | lp64f | lp64s) ;; # OK, append here.
-		*)
-			echo "Unsupported ABI given in --with-abi=$with_abi" 1>&2
-			exit 1
-			;;
-		esac
-
-		case ${with_abiext} in
-		"" | base) ;; # OK, append here.
-		*)
-			echo "Unsupported ABI extention type $with_abiext" 1>&2
-			exit 1
-			;;
-		esac
 
 		case ${with_fpu} in
 		"" | none | 32 | 64) ;; # OK, append here.
@@ -4985,73 +4970,41 @@ case "${target}" in
 			;;
 		esac
 
-
-		# Set default value for with_abi.
-		case ${with_abi} in
-		"")
-			if test x${abi_default} != x; then
-				with_abi=${abi_default}
-			else
-				with_abi=${abi_pattern}
-			fi
-			;;
-
-		*)
-			if echo "${with_abi}" | grep -E "^${abi_pattern}$" > /dev/null; then
-				: # OK
-			else
-				echo "Incompatible options:" \
-				"--with-abi=${with_abi} and --target=${target}." 1>&2
+		case ${with_simd} in
+		"" | none) ;;
+		lsx | lasx)  # OK, append here.
+			case ${with_fpu} in
+			64) ;;
+			"") with_fpu=64 ;;
+			*)
+				echo "--with-simd=${with_simd} conflicts with --with-fpu=${with_fpu}" 1>&2
 				exit 1
-			fi
-			;;
-		esac
-
-		case ${with_abi} in
-		  "lp64d") triplet_abi="";;
-		  "lp64f") triplet_abi="f32";;
-		  "lp64s") triplet_abi="sf";;
-		esac
-		la_canonical_triplet="loongarch64-${triplet_os}${triplet_abi}"
-
-		# Set default value for with_abiext (internal)
-		case ${with_abiext} in
-		"")
-			if test x${abiext_default} != x; then
-				with_abiext=${abiext_default}
-			else
-				with_abiext=${abiext_pattern}
-			fi
+				;;
+			esac
 			;;
 
 		*)
-			if echo "${with_abiext}" | grep -E "^${abiext_pattern}$" > /dev/null; then
-				: # OK
-			else
-				echo "The ABI extension type \"${with_abiext}\"" \
-				"is incompatible with --target=${target}." 1>&2
-				exit 1
-			fi
-
+			echo "Unknown SIMD extension in --with-simd=$with_simd" 1>&2
+			exit 1
 			;;
 		esac
 
 		# Infer ISA-related default options from the ABI: pass 1
-		case ${with_abi}/${with_abiext} in
+		case ${abi_base}/${abi_ext} in
 		lp64*/base)
 			# architectures that support lp64* ABI
-			arch_pattern="native|loongarch64|la464"
+			arch_pattern="native|abi-default|loongarch64|la464"
 			# default architecture for lp64* ABI
-			arch_default="loongarch64"
+			arch_default="abi-default"
 			;;
 		*)
-			echo "Unsupported ABI type ${with_abi}/${with_abiext}." 1>&2
+			echo "Unsupported ABI type ${abi_base}/${abi_ext}." 1>&2
 			exit 1
 			;;
 		esac
 
 		# Infer ISA-related default options from the ABI: pass 2
-		case ${with_abi}/${with_abiext} in
+		case ${abi_base}/${abi_ext} in
 		lp64d/base)
 			fpu_pattern="64"
 			;;
@@ -5064,7 +5017,7 @@ case "${target}" in
 			fpu_default="none"
 			;;
 		*)
-			echo "Unsupported ABI type ${with_abi}/${with_abiext}." 1>&2
+			echo "Unsupported ABI type ${abi_base}/${abi_ext}." 1>&2
 			exit 1
 			;;
 		esac
@@ -5083,7 +5036,7 @@ case "${target}" in
 			if echo "${with_arch}" | grep -E "^${arch_pattern}$" > /dev/null; then
 				: # OK
 			else
-				echo "${with_abi}/${with_abiext} ABI cannot be implemented with" \
+				echo "${abi_base}/${abi_ext} ABI cannot be implemented with" \
 				"--with-arch=${with_arch}." 1>&2
 				exit 1
 			fi
@@ -5104,7 +5057,7 @@ case "${target}" in
 			if echo "${with_fpu}" | grep -E "^${fpu_pattern}$" > /dev/null; then
 				: # OK
 			else
-				echo "${with_abi}/${with_abiext} ABI cannot be implemented with" \
+				echo "${abi_base}/${abi_ext} ABI cannot be implemented with" \
 				"--with-fpu=${with_fpu}." 1>&2
 				exit 1
 			fi
@@ -5112,32 +5065,19 @@ case "${target}" in
 		esac
 
 
-		# Infer default with_tune from with_arch: pass 1
+		# Check default with_tune configuration using with_arch.
 		case ${with_arch} in
-		native)
-			tune_pattern="*"
-			tune_default="native"
-			;;
 		loongarch64)
-			tune_pattern="loongarch64|la464"
-			tune_default="la464"
+			tune_pattern="native|abi-default|loongarch64|la464"
 			;;
 		*)
 			# By default, $with_tune == $with_arch
-			tune_pattern="$with_arch"
+			tune_pattern="*"
 			;;
 		esac
 
-		## Set default value for with_tune.
 		case ${with_tune} in
-		"")
-			if test x${tune_default} != x; then
-				with_tune=${tune_default}
-			else
-				with_tune=${tune_pattern}
-			fi
-			;;
-
+		"") ;; # OK
 		*)
 			if echo "${with_tune}" | grep -E "^${tune_pattern}$" > /dev/null; then
 				: # OK
@@ -5149,13 +5089,53 @@ case "${target}" in
 			;;
 		esac
 
+		# Handle --with-multilib-default
+		if echo "${with_multilib_default}" \
+		| grep -E -e '[[:space:]]' -e '//' -e '/$' -e '^/' > /dev/null 2>&1; then
+			echo "Invalid argument to --with-multilib-default." 1>&2
+			exit 1
+		fi
+
+		if test x${with_multilib_default} = x; then
+			# Use -march=abi-default by default when building libraries.
+			with_multilib_default="/march=abi-default"
+		else
+			unset parse_state component
+			parse_state=arch
+			for component in $(echo "${with_multilib_default}" | tr '/' ' '); do
+				case ${parse_state},${component} in
+				arch,|arch,abi-default)
+					# ABI-default: use the ABI's default ARCH configuration for
+					# multilib library builds, unless otherwise specified
+					# in --with-multilib-list.
+					with_multilib_default="/march=abi-default" ;;
+				arch,fixed)
+					# Fixed: use the default gcc configuration for all multilib
+					# builds by default.
+					with_multilib_default="" ;;
+				arch,native|arch,loongarch64|arch,la464) # OK, append here.
+					with_multilib_default="/march=${component}" ;;
+				arch,*)
+					with_multilib_default="/march=abi-default"
+					with_multilib_default="${with_multilib_default}/${component}" ;;
+				opts,*)
+					with_multilib_default="${with_multilib_default}/${component}" ;;
+				esac
+
+				if test x${parse_state} = xarch; then
+					parse_state=opt;
+				fi
+			done
+			unset parse_state component
+		fi
+
 		# Handle --with-multilib-list.
 		if test x"${with_multilib_list}" = x \
 		   || test x"${with_multilib_list}" = xno \
 		   || test x"${with_multilib_list}" = xdefault \
 		   || test x"${enable_multilib}" != xyes; then
 
-			with_multilib_list="${with_abi}/${with_abiext}"
+			with_multilib_list="${abi_base}/${abi_ext}"
 		fi
 
 		# Check if the configured default ABI combination is included in
@@ -5171,25 +5151,21 @@ case "${target}" in
 		# ${with_multilib_list} should not contain whitespaces,
 		# consecutive commas or slashes.
 		if echo "${with_multilib_list}" \
-		| grep -E -e "[[:space:]]" -e '[,/][,/]' -e '[,/]$' -e '^[,/]' > /dev/null; then
+		| grep -E -e "[[:space:]]" -e '[,/][,/]' -e '[,/]$' -e '^[,/]' > /dev/null 2>&1; then
 			echo "Invalid argument to --with-multilib-list." 1>&2
 			exit 1
 		fi
 
-		unset component idx elem_abi_base elem_abi_ext elem_tmp
+		unset component elem_abi_base elem_abi_ext elem_tmp parse_state all_abis
 		for elem in $(echo "${with_multilib_list}" | tr ',' ' '); do
-			idx=0
-			while true; do
-				idx=$((idx + 1))
-				component=$(echo "${elem}" | awk -F'/' '{print $'"${idx}"'}')
-
-				case ${idx} in
-				1)
-					# Component 1: Base ABI type
+			unset elem_abi_base elem_abi_ext
+			parse_state="abi-base"
+
+			for component in $(echo "${elem}" | tr '/' ' '); do
+				if test x${parse_state} = x"abi-base"; then
+					# Base ABI type
 					case ${component} in
-					lp64d) elem_tmp="ABI_BASE_LP64D,";;
-					lp64f) elem_tmp="ABI_BASE_LP64F,";;
-					lp64s) elem_tmp="ABI_BASE_LP64S,";;
+					lp64d | lp64f | lp64s) elem_tmp="ABI_BASE_$(tr a-z A-Z <<< ${component}),";;
 					*)
 						echo "Unknown base ABI \"${component}\" in --with-multilib-list." 1>&2
 						exit 1
@@ -5198,57 +5174,111 @@ case "${target}" in
 					loongarch_multilib_list_c="${loongarch_multilib_list_c}${elem_tmp}"
 					loongarch_multilib_list_make="${loongarch_multilib_list_make}mabi=${component}"
 					elem_abi_base="${component}"
-					;;
 
-				2)
-					# Component 2: ABI extension type
+					parse_state="abi-ext"
+					continue
+				fi
+
+				if test x${parse_state} = x"abi-ext"; then
+					# ABI extension type
 					case ${component} in
-					"" | base)
-						component="base"
-						elem_tmp="ABI_EXT_BASE,"
-						;;
-					*)
-						echo "Unknown ABI extension \"${component}\" in --with-multilib-list." 1>&2
-						exit 1
+					base)
+						elem_abi_ext="base"
+						loongarch_multilib_list_c="${loongarch_multilib_list_c}ABI_EXT_BASE,"
+						loongarch_multilib_list_make="${loongarch_multilib_list_make}" # Add nothing for now.
+						parse_state="arch"
+						continue;
 						;;
 					esac
-					loongarch_multilib_list_c="${loongarch_multilib_list_c}${elem_tmp}"
+
+					# The default ABI extension is "base" if unspecified.
+					elem_abi_ext="base"
+					loongarch_multilib_list_c="${loongarch_multilib_list_c}ABI_EXT_BASE,"
 					loongarch_multilib_list_make="${loongarch_multilib_list_make}" # Add nothing for now.
-					elem_abi_ext="${component}"
-					;;
+					parse_state="arch"
+				fi
 
-				*)
-					# Component 3 and on: optional stuff
+				if test x${parse_state} = x"arch"; then
+					# -march option
 					case ${component} in
-					"")
-						# End of component list.
-						break
+					native | abi-default | loongarch64 | la464) # OK, append here.
+						# Append -march spec for each multilib variant.
+						loongarch_multilib_list_make="${loongarch_multilib_list_make}/march=${component}"
+						parse_state="opts"
+						continue
+						;;
+
+					default)
+						# "/default" is equivalent to --with-multilib-default=fixed
+						parse_state="opts"
+						continue
 						;;
+					esac
+
+					# If ARCH is unspecified for this multilib variant, use ${with_multllib_default}.
+					loongarch_multilib_list_make="${loongarch_multilib_list_make}${with_multilib_default}"
+					parse_state="opts"
+				fi
+
+				if test x${parse_state} = x"opts"; then
+					# Other compiler options for building libraries.
+					# (no static sanity check performed)
+					case ${component} in
 					*)
-						echo "Unknown ABI \"${elem}\" in --with-multilib-list." 1>&2
-						exit 1
+						# Append other components as additional build options
+						# (without the prepending dash).
+						# Their validity should be examined by the compiler.
+						loongarch_multilib_list_make="${loongarch_multilib_list_make}/${component}"
 						;;
 					esac
-					;;
-				esac
+				fi
 			done
 
-			if test x${elem_abi_base} = x${with_abi} \
-			&& test x${elem_abi_ext} = x${with_abiext}; then
+			case ${parse_state} in
+			    "abi-ext")
+					elem_abi_ext="base"
+					loongarch_multilib_list_c="${loongarch_multilib_list_c}ABI_EXT_BASE,"
+					loongarch_multilib_list_make="${loongarch_multilib_list_make}" # Add nothing for now.
+					loongarch_multilib_list_make="${loongarch_multilib_list_make}${with_multilib_default}"
+					;;
+			    "arch")
+					# If ARCH is unspecified for this multilib variant, use ${with_multllib_default}.
+					loongarch_multilib_list_make="${loongarch_multilib_list_make}${with_multilib_default}"
+					;;
+			    "opts")
+					:
+					;;
+			esac
+
+			# Check for repeated configuration of the same multilib variant.
+			if echo "${elem_abi_base}/${elem_abi_ext}" \
+			 | grep -E "^(${all_abis%|})$" >/dev/null 2>&1; then
+				echo "Repeated multilib config of \"${elem_abi_base}/${elem_abi_ext}\" in --with-multilib-list."
+				exit 1
+			fi
+			all_abis="${all_abis}${elem_abi_base}/${elem_abi_ext}|"
+
+
+			# Check if the default ABI configuration of the GCC binary
+			# is included in the enabled multilib variants.
+			if test x${elem_abi_base} = x${abi_base} \
+			&& test x${elem_abi_ext} = x${abi_ext}; then
 				loongarch_multilib_list_sane=yes
 			fi
 			loongarch_multilib_list_make="${loongarch_multilib_list_make},"
 		done
+		unset component elem_abi_base elem_abi_ext elem_tmp parse_state all_abis
+
 
 		# Check if the default ABI combination is in the default list.
 		if test x${loongarch_multilib_list_sane} = xno; then
-			if test x${with_abiext} = xbase; then
-				with_abiext=""
+			if test x${abi_ext} = xbase; then
+				abi_ext=""
 			else
-				with_abiext="/${with_abiext}"
+				abi_ext="/${abi_ext}"
 			fi
 
-			echo "Default ABI combination (${with_abi}${with_abiext})" \
+			echo "Default ABI combination (${abi_base}${abi_ext})" \
 			"not found in --with-multilib-list." 1>&2
 			exit 1
 		fi
@@ -5739,34 +5769,37 @@ case ${target} in
 
 		# Let --with- flags initialize the enum variables from loongarch.opt.
 		# See macro definitions from loongarch-opts.h and loongarch-cpu.h.
-		case ${with_arch} in
-		native)		tm_defines="${tm_defines} DEFAULT_CPU_ARCH=CPU_NATIVE" ;;
-		la464)		tm_defines="${tm_defines} DEFAULT_CPU_ARCH=CPU_LA464" ;;
-		loongarch64)	tm_defines="${tm_defines} DEFAULT_CPU_ARCH=CPU_LOONGARCH64" ;;
-		esac
 
-		case ${with_tune} in
-		native)		tm_defines="${tm_defines} DEFAULT_CPU_TUNE=CPU_NATIVE" ;;
-		la464)		tm_defines="${tm_defines} DEFAULT_CPU_TUNE=CPU_LA464" ;;
-		loongarch64)	tm_defines="${tm_defines} DEFAULT_CPU_TUNE=CPU_LOONGARCH64" ;;
-		esac
+		# Architecture
+		tm_defines="${tm_defines} DEFAULT_CPU_ARCH=CPU_$(echo ${with_arch} | tr a-z- A-Z_)"
 
-		case ${with_abi} in
-		lp64d)     tm_defines="${tm_defines} DEFAULT_ABI_BASE=ABI_BASE_LP64D" ;;
-		lp64f)     tm_defines="${tm_defines} DEFAULT_ABI_BASE=ABI_BASE_LP64F" ;;
-		lp64s)     tm_defines="${tm_defines} DEFAULT_ABI_BASE=ABI_BASE_LP64S" ;;
-		esac
+		# Base ABI type
+		tm_defines="${tm_defines} DEFAULT_ABI_BASE=ABI_BASE_$(echo ${abi_base} | tr a-z- A-Z_)"
 
-		case ${with_abiext} in
+		# ABI Extension
+		case ${abi_ext} in
 		base)      tm_defines="${tm_defines} DEFAULT_ABI_EXT=ABI_EXT_BASE" ;;
 		esac
 
+		# Microarchitecture
+		if test x${with_tune} != x; then
+		  tm_defines="${tm_defines} DEFAULT_CPU_TUNE=CPU_$(echo ${with_tune} | tr a-z- A-Z_)"
+		fi
+
+		# FPU adjustment
 		case ${with_fpu} in
-		none)    tm_defines="$tm_defines DEFAULT_ISA_EXT_FPU=ISA_EXT_NOFPU" ;;
+		none)    tm_defines="$tm_defines DEFAULT_ISA_EXT_FPU=ISA_EXT_NONE" ;;
 		32)      tm_defines="$tm_defines DEFAULT_ISA_EXT_FPU=ISA_EXT_FPU32" ;;
 		64)      tm_defines="$tm_defines DEFAULT_ISA_EXT_FPU=ISA_EXT_FPU64" ;;
 		esac
 
+		# SIMD extensions
+		case ${with_simd} in
+		none)    tm_defines="$tm_defines DEFAULT_ISA_EXT_SIMD=ISA_EXT_NONE" ;;
+		lsx)     tm_defines="$tm_defines DEFAULT_ISA_EXT_SIMD=ISA_EXT_SIMD_LSX" ;;
+		lasx)    tm_defines="$tm_defines DEFAULT_ISA_EXT_SIMD=ISA_EXT_SIMD_LASX" ;;
+		esac
+
 		tmake_file="loongarch/t-loongarch $tmake_file"
 		;;
 
diff --git a/gcc/config/loongarch/genopts/loongarch-strings b/gcc/config/loongarch/genopts/loongarch-strings
index a40998ead97..adecaec3eda 100644
--- a/gcc/config/loongarch/genopts/loongarch-strings
+++ b/gcc/config/loongarch/genopts/loongarch-strings
@@ -23,6 +23,7 @@ OPTSTR_ARCH	      arch
 OPTSTR_TUNE	      tune
 
 STR_CPU_NATIVE	      native
+STR_CPU_ABI_DEFAULT   abi-default
 STR_CPU_LOONGARCH64   loongarch64
 STR_CPU_LA464	      la464
 
@@ -31,7 +32,7 @@ STR_ISA_BASE_LA64V100 la64
 
 # -mfpu
 OPTSTR_ISA_EXT_FPU    fpu
-STR_ISA_EXT_NOFPU     none
+STR_NONE	      none
 STR_ISA_EXT_FPU0      0
 STR_ISA_EXT_FPU32     32
 STR_ISA_EXT_FPU64     64
@@ -40,6 +41,11 @@ OPTSTR_SOFT_FLOAT     soft-float
 OPTSTR_SINGLE_FLOAT   single-float
 OPTSTR_DOUBLE_FLOAT   double-float
 
+# SIMD extensions
+OPTSTR_ISA_EXT_SIMD   simd
+STR_ISA_EXT_LSX       lsx
+STR_ISA_EXT_LASX      lasx
+
 # -mabi=
 OPTSTR_ABI_BASE	      abi
 STR_ABI_BASE_LP64D    lp64d
diff --git a/gcc/config/loongarch/genopts/loongarch.opt.in b/gcc/config/loongarch/genopts/loongarch.opt.in
index 4b9b4ac273e..f3567b27935 100644
--- a/gcc/config/loongarch/genopts/loongarch.opt.in
+++ b/gcc/config/loongarch/genopts/loongarch.opt.in
@@ -17,22 +17,12 @@
 ; <http://www.gnu.org/licenses/>.
 ;
 
-; Variables (macros) that should be exported by loongarch.opt:
-;   la_opt_switches,
-;   la_opt_abi_base, la_opt_abi_ext,
-;   la_opt_cpu_arch, la_opt_cpu_tune,
-;   la_opt_fpu,
-;   la_cmodel.
-
 HeaderInclude
 config/loongarch/loongarch-opts.h
 
 HeaderInclude
 config/loongarch/loongarch-str.h
 
-Variable
-HOST_WIDE_INT la_opt_switches = 0
-
 ; ISA related options
 ;; Base ISA
 Enum
@@ -42,14 +32,13 @@ Basic ISAs of LoongArch:
 EnumValue
 Enum(isa_base) String(@@STR_ISA_BASE_LA64V100@@) Value(ISA_BASE_LA64V100)
 
-
 ;; ISA extensions / adjustments
 Enum
 Name(isa_ext_fpu) Type(int)
 FPU types of LoongArch:
 
 EnumValue
-Enum(isa_ext_fpu) String(@@STR_ISA_EXT_NOFPU@@) Value(ISA_EXT_NOFPU)
+Enum(isa_ext_fpu) String(@@STR_NONE@@) Value(ISA_EXT_NONE)
 
 EnumValue
 Enum(isa_ext_fpu) String(@@STR_ISA_EXT_FPU32@@) Value(ISA_EXT_FPU32)
@@ -58,24 +47,48 @@ EnumValue
 Enum(isa_ext_fpu) String(@@STR_ISA_EXT_FPU64@@) Value(ISA_EXT_FPU64)
 
 m@@OPTSTR_ISA_EXT_FPU@@=
-Target RejectNegative Joined ToLower Enum(isa_ext_fpu) Var(la_opt_fpu) Init(M_OPTION_NOT_SEEN)
+Target RejectNegative Joined ToLower Enum(isa_ext_fpu) Var(la_opt_fpu) Init(M_OPT_UNSET)
 -m@@OPTSTR_ISA_EXT_FPU@@=FPU	Generate code for the given FPU.
 
 m@@OPTSTR_ISA_EXT_FPU@@=@@STR_ISA_EXT_FPU0@@
-Target RejectNegative Alias(m@@OPTSTR_ISA_EXT_FPU@@=,@@STR_ISA_EXT_NOFPU@@)
+Target RejectNegative Alias(m@@OPTSTR_ISA_EXT_FPU@@=,@@STR_NONE@@)
 
 m@@OPTSTR_SOFT_FLOAT@@
-Target Driver RejectNegative Var(la_opt_switches) Mask(FORCE_SOFTF) Negative(m@@OPTSTR_SINGLE_FLOAT@@)
+Target Driver Defer Var(la_deferred_options) RejectNegative Negative(m@@OPTSTR_SINGLE_FLOAT@@)
 Prevent the use of all hardware floating-point instructions.
 
 m@@OPTSTR_SINGLE_FLOAT@@
-Target Driver RejectNegative Var(la_opt_switches) Mask(FORCE_F32) Negative(m@@OPTSTR_DOUBLE_FLOAT@@)
+Target Driver Defer Var(la_deferred_options) RejectNegative Negative(m@@OPTSTR_DOUBLE_FLOAT@@)
 Restrict the use of hardware floating-point instructions to 32-bit operations.
 
 m@@OPTSTR_DOUBLE_FLOAT@@
-Target Driver RejectNegative Var(la_opt_switches) Mask(FORCE_F64) Negative(m@@OPTSTR_SOFT_FLOAT@@)
+Target Driver Defer Var(la_deferred_options) RejectNegative Negative(m@@OPTSTR_SOFT_FLOAT@@)
 Allow hardware floating-point instructions to cover both 32-bit and 64-bit operations.
 
+Enum
+Name(isa_ext_simd) Type(int)
+SIMD extension levels of LoongArch:
+
+EnumValue
+Enum(isa_ext_simd) String(@@STR_NONE@@) Value(ISA_EXT_NONE)
+
+EnumValue
+Enum(isa_ext_simd) String(@@STR_ISA_EXT_LSX@@) Value(ISA_EXT_SIMD_LSX)
+
+EnumValue
+Enum(isa_ext_simd) String(@@STR_ISA_EXT_LASX@@) Value(ISA_EXT_SIMD_LASX)
+
+m@@OPTSTR_ISA_EXT_SIMD@@=
+Target RejectNegative Joined ToLower Enum(isa_ext_simd) Var(la_opt_simd) Init(M_OPT_UNSET)
+-m@@OPTSTR_ISA_EXT_SIMD@@=SIMD	Generate code for the given SIMD extension.
+
+m@@STR_ISA_EXT_LSX@@
+Target Driver Defer Var(la_deferred_options)
+Enable LoongArch SIMD Extension (LSX, 128-bit).
+
+m@@STR_ISA_EXT_LASX@@
+Target Driver Defer Var(la_deferred_options)
+Enable LoongArch Advanced SIMD Extension (LASX, 256-bit).
 
 ;; Base target models (implies ISA & tune parameters)
 Enum
@@ -85,6 +98,9 @@ LoongArch CPU types:
 EnumValue
 Enum(cpu_type) String(@@STR_CPU_NATIVE@@) Value(CPU_NATIVE)
 
+EnumValue
+Enum(cpu_type) String(@@STR_CPU_ABI_DEFAULT@@) Value(CPU_ABI_DEFAULT)
+
 EnumValue
 Enum(cpu_type) String(@@STR_CPU_LOONGARCH64@@) Value(CPU_LOONGARCH64)
 
@@ -92,11 +108,11 @@ EnumValue
 Enum(cpu_type) String(@@STR_CPU_LA464@@) Value(CPU_LA464)
 
 m@@OPTSTR_ARCH@@=
-Target RejectNegative Joined Enum(cpu_type) Var(la_opt_cpu_arch) Init(M_OPTION_NOT_SEEN)
+Target RejectNegative Joined Enum(cpu_type) Var(la_opt_cpu_arch) Init(M_OPT_UNSET)
 -m@@OPTSTR_ARCH@@=PROCESSOR	Generate code for the given PROCESSOR ISA.
 
 m@@OPTSTR_TUNE@@=
-Target RejectNegative Joined Enum(cpu_type) Var(la_opt_cpu_tune) Init(M_OPTION_NOT_SEEN)
+Target RejectNegative Joined Enum(cpu_type) Var(la_opt_cpu_tune) Init(M_OPT_UNSET)
 -m@@OPTSTR_TUNE@@=PROCESSOR	Generate optimized code for PROCESSOR.
 
 
@@ -118,13 +134,13 @@ EnumValue
 Enum(abi_base) String(@@STR_ABI_BASE_LP64S@@) Value(ABI_BASE_LP64S)
 
 m@@OPTSTR_ABI_BASE@@=
-Target RejectNegative Joined ToLower Enum(abi_base) Var(la_opt_abi_base) Init(M_OPTION_NOT_SEEN)
+Target RejectNegative Joined ToLower Enum(abi_base) Var(la_opt_abi_base) Init(M_OPT_UNSET)
 -m@@OPTSTR_ABI_BASE@@=BASEABI	Generate code that conforms to the given BASEABI.
 
+
 ;; ABI Extension
 Variable
-int la_opt_abi_ext = M_OPTION_NOT_SEEN
-
+int la_opt_abi_ext = M_OPT_UNSET
 
 mbranch-cost=
 Target RejectNegative Joined UInteger Var(loongarch_branch_cost)
@@ -182,7 +198,7 @@ EnumValue
 Enum(cmodel) String(@@STR_CMODEL_EXTREME@@) Value(CMODEL_EXTREME)
 
 mcmodel=
-Target RejectNegative Joined Enum(cmodel) Var(la_opt_cmodel) Init(CMODEL_NORMAL)
+Target RejectNegative Joined Enum(cmodel) Var(la_opt_cmodel) Init(M_OPT_UNSET)
 Specify the code model.
 
 mdirect-extern-access
diff --git a/gcc/config/loongarch/la464.md b/gcc/config/loongarch/la464.md
index 541040fdfa8..3b4d14f0b3c 100644
--- a/gcc/config/loongarch/la464.md
+++ b/gcc/config/loongarch/la464.md
@@ -43,88 +43,88 @@ (define_cpu_unit "la464_falu2" "la464_a_falu")
 ;; Describe instruction reservations.
 
 (define_insn_reservation "la464_arith" 1
-  (and (match_test "TARGET_TUNE_LA464")
+  (and (match_test "TARGET_uARCH_LA464")
        (eq_attr "type" "arith,clz,const,logical,
 			move,nop,shift,signext,slt"))
   "la464_alu1 | la464_alu2")
 
 (define_insn_reservation "la464_branch" 1
-  (and (match_test "TARGET_TUNE_LA464")
+  (and (match_test "TARGET_uARCH_LA464")
        (eq_attr "type" "branch,jump,call,condmove,trap"))
   "la464_alu1 | la464_alu2")
 
 (define_insn_reservation "la464_imul" 7
-  (and (match_test "TARGET_TUNE_LA464")
+  (and (match_test "TARGET_uARCH_LA464")
        (eq_attr "type" "imul"))
   "la464_alu1 | la464_alu2")
 
 (define_insn_reservation "la464_idiv_si" 12
-  (and (match_test "TARGET_TUNE_LA464")
+  (and (match_test "TARGET_uARCH_LA464")
        (and (eq_attr "type" "idiv")
 	    (eq_attr "mode" "SI")))
   "la464_alu1 | la464_alu2")
 
 (define_insn_reservation "la464_idiv_di" 25
-  (and (match_test "TARGET_TUNE_LA464")
+  (and (match_test "TARGET_uARCH_LA464")
        (and (eq_attr "type" "idiv")
 	    (eq_attr "mode" "DI")))
   "la464_alu1 | la464_alu2")
 
 (define_insn_reservation "la464_load" 4
-  (and (match_test "TARGET_TUNE_LA464")
+  (and (match_test "TARGET_uARCH_LA464")
        (eq_attr "type" "load"))
   "la464_mem1 | la464_mem2")
 
 (define_insn_reservation "la464_gpr_fp" 16
-  (and (match_test "TARGET_TUNE_LA464")
+  (and (match_test "TARGET_uARCH_LA464")
        (eq_attr "type" "mftg,mgtf"))
   "la464_mem1")
 
 (define_insn_reservation "la464_fpload" 4
-  (and (match_test "TARGET_TUNE_LA464")
+  (and (match_test "TARGET_uARCH_LA464")
        (eq_attr "type" "fpload"))
   "la464_mem1 | la464_mem2")
 
 (define_insn_reservation "la464_prefetch" 0
-  (and (match_test "TARGET_TUNE_LA464")
+  (and (match_test "TARGET_uARCH_LA464")
        (eq_attr "type" "prefetch,prefetchx"))
   "la464_mem1 | la464_mem2")
 
 (define_insn_reservation "la464_store" 0
-  (and (match_test "TARGET_TUNE_LA464")
+  (and (match_test "TARGET_uARCH_LA464")
        (eq_attr "type" "store,fpstore,fpidxstore"))
   "la464_mem1 | la464_mem2")
 
 (define_insn_reservation "la464_fadd" 4
-  (and (match_test "TARGET_TUNE_LA464")
+  (and (match_test "TARGET_uARCH_LA464")
        (eq_attr "type" "fadd,fmul,fmadd"))
   "la464_falu1 | la464_falu2")
 
 (define_insn_reservation "la464_fcmp" 2
-  (and (match_test "TARGET_TUNE_LA464")
+  (and (match_test "TARGET_uARCH_LA464")
        (eq_attr "type" "fabs,fcmp,fmove,fneg"))
   "la464_falu1 | la464_falu2")
 
 (define_insn_reservation "la464_fcvt" 4
-  (and (match_test "TARGET_TUNE_LA464")
+  (and (match_test "TARGET_uARCH_LA464")
        (eq_attr "type" "fcvt"))
   "la464_falu1 | la464_falu2")
 
 (define_insn_reservation "la464_fdiv_sf" 12
-  (and (match_test "TARGET_TUNE_LA464")
+  (and (match_test "TARGET_uARCH_LA464")
        (and (eq_attr "type" "fdiv,frdiv,fsqrt,frsqrt")
 	    (eq_attr "mode" "SF")))
   "la464_falu1 | la464_falu2")
 
 (define_insn_reservation "la464_fdiv_df" 19
-  (and (match_test "TARGET_TUNE_LA464")
+  (and (match_test "TARGET_uARCH_LA464")
        (and (eq_attr "type" "fdiv,frdiv,fsqrt,frsqrt")
 	    (eq_attr "mode" "DF")))
   "la464_falu1 | la464_falu2")
 
 ;; Force single-dispatch for unknown or multi.
 (define_insn_reservation "la464_unknown" 1
-  (and (match_test "TARGET_TUNE_LA464")
+  (and (match_test "TARGET_uARCH_LA464")
        (eq_attr "type" "unknown,multi,atomic,syncloop"))
   "la464_alu1 + la464_alu2 + la464_falu1
    + la464_falu2 + la464_mem1 + la464_mem2")
diff --git a/gcc/config/loongarch/loongarch-c.cc b/gcc/config/loongarch/loongarch-c.cc
index 67911b78f28..7e3b57ff9b1 100644
--- a/gcc/config/loongarch/loongarch-c.cc
+++ b/gcc/config/loongarch/loongarch-c.cc
@@ -61,8 +61,8 @@ loongarch_cpu_cpp_builtins (cpp_reader *pfile)
   builtin_assert ("cpu=loongarch");
   builtin_define ("__loongarch__");
 
-  LARCH_CPP_SET_PROCESSOR ("_LOONGARCH_ARCH", LARCH_ACTUAL_ARCH);
-  LARCH_CPP_SET_PROCESSOR ("_LOONGARCH_TUNE", LARCH_ACTUAL_TUNE);
+  LARCH_CPP_SET_PROCESSOR ("_LOONGARCH_ARCH", la_target.cpu_arch);
+  LARCH_CPP_SET_PROCESSOR ("_LOONGARCH_TUNE", la_target.cpu_tune);
 
   /* Base architecture / ABI.  */
   if (TARGET_64BIT)
@@ -99,6 +99,21 @@ loongarch_cpu_cpp_builtins (cpp_reader *pfile)
   else
     builtin_define ("__loongarch_frlen=0");
 
+  if (ISA_HAS_LSX)
+    {
+      builtin_define ("__loongarch_simd");
+      builtin_define ("__loongarch_sx");
+
+      if (!ISA_HAS_LASX)
+	builtin_define ("__loongarch_simd_width=128");
+    }
+
+  if (ISA_HAS_LASX)
+    {
+      builtin_define ("__loongarch_asx");
+      builtin_define ("__loongarch_simd_width=256");
+    }
+
   /* Native Data Sizes.  */
   builtin_define_with_int_value ("_LOONGARCH_SZINT", INT_TYPE_SIZE);
   builtin_define_with_int_value ("_LOONGARCH_SZLONG", LONG_TYPE_SIZE);
diff --git a/gcc/config/loongarch/loongarch-cpu.cc b/gcc/config/loongarch/loongarch-cpu.cc
index 34905f3de30..7a2866f60f9 100644
--- a/gcc/config/loongarch/loongarch-cpu.cc
+++ b/gcc/config/loongarch/loongarch-cpu.cc
@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm.h"
 #include "diagnostic-core.h"
 
+#include "loongarch-def.h"
 #include "loongarch-opts.h"
 #include "loongarch-cpu.h"
 #include "loongarch-str.h"
@@ -80,127 +81,191 @@ get_native_prid_str (void)
 }
 
 /* Fill property tables for CPU_NATIVE.  */
-unsigned int
-fill_native_cpu_config (int p_arch_native, int p_tune_native)
+void
+fill_native_cpu_config (struct loongarch_target *tgt)
 {
-  int ret_cpu_type;
+  int arch_native_p = tgt->cpu_arch == CPU_NATIVE;
+  int tune_native_p = tgt->cpu_tune == CPU_NATIVE;
+  int native_cpu_type = CPU_NATIVE;
 
   /* Nothing needs to be done unless "-march/tune=native"
      is given or implied.  */
-  if (!(p_arch_native || p_tune_native))
-    return CPU_NATIVE;
+  if (!arch_native_p && !tune_native_p)
+    return;
 
   /* Fill cpucfg_cache with the "cpucfg" instruction.  */
   cache_cpucfg ();
 
-
-  /* Fill: loongarch_cpu_default_isa[CPU_NATIVE].base
-     With: base architecture (ARCH)
-     At:   cpucfg_words[1][1:0] */
-
-  #define NATIVE_BASE_ISA (loongarch_cpu_default_isa[CPU_NATIVE].base)
-  switch (cpucfg_cache[1] & 0x3)
-    {
-      case 0x02:
-	NATIVE_BASE_ISA = ISA_BASE_LA64V100;
-	break;
-
-      default:
-	if (p_arch_native)
-	  fatal_error (UNKNOWN_LOCATION,
-		       "unknown base architecture %<0x%x%>, %qs failed",
-		       (unsigned int) (cpucfg_cache[1] & 0x3),
-		       "-m" OPTSTR_ARCH "=" STR_CPU_NATIVE);
-    }
-
-  /* Fill: loongarch_cpu_default_isa[CPU_NATIVE].fpu
-     With: FPU type (FP, FP_SP, FP_DP)
-     At:   cpucfg_words[2][2:0] */
-
-  #define NATIVE_FPU (loongarch_cpu_default_isa[CPU_NATIVE].fpu)
-  switch (cpucfg_cache[2] & 0x7)
-    {
-      case 0x07:
-	NATIVE_FPU = ISA_EXT_FPU64;
-	break;
-
-      case 0x03:
-	NATIVE_FPU = ISA_EXT_FPU32;
-	break;
-
-      case 0x00:
-	NATIVE_FPU = ISA_EXT_NOFPU;
-	break;
-
-      default:
-	if (p_arch_native)
-	  fatal_error (UNKNOWN_LOCATION,
-		       "unknown FPU type %<0x%x%>, %qs failed",
-		       (unsigned int) (cpucfg_cache[2] & 0x7),
-		       "-m" OPTSTR_ARCH "=" STR_CPU_NATIVE);
-    }
-
-  /* Fill: loongarch_cpu_cache[CPU_NATIVE]
-     With: cache size info
-     At:   cpucfg_words[16:20][31:0] */
-
-  int l1d_present = 0, l1u_present = 0;
-  int l2d_present = 0;
-  uint32_t l1_szword, l2_szword;
-
-  l1u_present |= cpucfg_cache[16] & 3;	      /* bit[1:0]: unified l1 cache */
-  l1d_present |= cpucfg_cache[16] & 4;	      /* bit[2:2]: l1 dcache */
-  l1_szword = l1d_present ? 18 : (l1u_present ? 17 : 0);
-  l1_szword = l1_szword ? cpucfg_cache[l1_szword]: 0;
-
-  l2d_present |= cpucfg_cache[16] & 24;	      /* bit[4:3]: unified l2 cache */
-  l2d_present |= cpucfg_cache[16] & 128;      /* bit[7:7]: l2 dcache */
-  l2_szword = l2d_present ? cpucfg_cache[19]: 0;
-
-  loongarch_cpu_cache[CPU_NATIVE].l1d_line_size
-    = 1 << ((l1_szword & 0x7f000000) >> 24);  /* bit[30:24]: log2(linesize) */
-
-  loongarch_cpu_cache[CPU_NATIVE].l1d_size
-    = (1 << ((l1_szword & 0x00ff0000) >> 16)) /* bit[23:16]: log2(idx) */
-    * ((l1_szword & 0x0000ffff) + 1)	      /* bit[15:0]:  sets - 1 */
-    * (1 << ((l1_szword & 0x7f000000) >> 24)) /* bit[30:24]: log2(linesize) */
-    >> 10;				      /* in kilobytes */
-
-  loongarch_cpu_cache[CPU_NATIVE].l2d_size
-    = (1 << ((l2_szword & 0x00ff0000) >> 16)) /* bit[23:16]: log2(idx) */
-    * ((l2_szword & 0x0000ffff) + 1)	      /* bit[15:0]:  sets - 1 */
-    * (1 << ((l2_szword & 0x7f000000) >> 24)) /* bit[30:24]: log2(linesize) */
-    >> 10;				      /* in kilobytes */
-
-  /* Fill: ret_cpu_type
+  /* Fill: tgt->cpu_arch | tgt->cpu_tune
      With: processor ID (PRID)
      At:   cpucfg_words[0][31:0] */
 
   switch (cpucfg_cache[0] & 0x00ffff00)
   {
     case 0x0014c000:   /* LA464 */
-      ret_cpu_type = CPU_LA464;
+      native_cpu_type = CPU_LA464;
       break;
 
     default:
-      /* Unknown PRID.  This is generally harmless as long as
-	 the properties above can be obtained via "cpucfg".  */
-      if (p_tune_native)
+      /* Unknown PRID.  */
+      if (tune_native_p)
 	inform (UNKNOWN_LOCATION, "unknown processor ID %<0x%x%>, "
 		"some tuning parameters will fall back to default",
 		cpucfg_cache[0]);
       break;
   }
 
-  /* Properties that cannot be looked up directly using cpucfg.  */
-  loongarch_cpu_issue_rate[CPU_NATIVE]
-    = loongarch_cpu_issue_rate[ret_cpu_type];
-
-  loongarch_cpu_multipass_dfa_lookahead[CPU_NATIVE]
-    = loongarch_cpu_multipass_dfa_lookahead[ret_cpu_type];
-
-  loongarch_cpu_rtx_cost_data[CPU_NATIVE]
-    = loongarch_cpu_rtx_cost_data[ret_cpu_type];
+  /* if -march=native */
+  if (arch_native_p)
+    {
+      int tmp;
+      tgt->cpu_arch = native_cpu_type;
+
+      /* Fill: loongarch_cpu_default_isa[tgt->cpu_arch].base
+	 With: base architecture (ARCH)
+	 At:   cpucfg_words[1][1:0] */
+
+      #define PRESET_ARCH (loongarch_cpu_default_isa[tgt->cpu_arch].base)
+      switch (cpucfg_cache[1] & 0x3)
+	{
+	  case 0x02:
+	    tmp = ISA_BASE_LA64V100;
+	    break;
+
+	  default:
+	    fatal_error (UNKNOWN_LOCATION,
+			 "unknown native base architecture %<0x%x%>, "
+			 "%qs failed", (unsigned int) (cpucfg_cache[1] & 0x3),
+			 "-m" OPTSTR_ARCH "=" STR_CPU_NATIVE);
+	}
+
+      /* Check consistency with PRID presets.  */
+      if (native_cpu_type != CPU_NATIVE && tmp != PRESET_ARCH)
+	warning (0, "base architecture %qs differs from PRID preset %qs",
+		 loongarch_isa_base_strings[tmp],
+		 loongarch_isa_base_strings[PRESET_ARCH]);
+
+      /* Use the native value anyways.  */
+      PRESET_ARCH = tmp;
+
+      /* Fill: loongarch_cpu_default_isa[tgt->cpu_arch].fpu
+	 With: FPU type (FP, FP_SP, FP_DP)
+	 At:   cpucfg_words[2][2:0] */
+
+      #define PRESET_FPU (loongarch_cpu_default_isa[tgt->cpu_arch].fpu)
+      switch (cpucfg_cache[2] & 0x7)
+	{
+	  case 0x07:
+	    tmp = ISA_EXT_FPU64;
+	    break;
+
+	  case 0x03:
+	    tmp = ISA_EXT_FPU32;
+	    break;
+
+	  case 0x00:
+	    tmp = ISA_EXT_NONE;
+	    break;
+
+	  default:
+	    fatal_error (UNKNOWN_LOCATION,
+			 "unknown native FPU type %<0x%x%>, %qs failed",
+			 (unsigned int) (cpucfg_cache[2] & 0x7),
+			 "-m" OPTSTR_ARCH "=" STR_CPU_NATIVE);
+	}
+
+      /* Check consistency with PRID presets.  */
+      if (native_cpu_type != CPU_NATIVE && tmp != PRESET_FPU)
+	warning (0, "floating-point unit %qs differs from PRID preset %qs",
+		 loongarch_isa_ext_strings[tmp],
+		 loongarch_isa_ext_strings[PRESET_FPU]);
+
+      /* Use the native value anyways.  */
+      PRESET_FPU = tmp;
+
+
+      /* Fill: loongarch_cpu_default_isa[CPU_NATIVE].simd
+	 With: SIMD extension type (LSX, LASX)
+	 At:   cpucfg_words[2][7:6] */
+
+      #define PRESET_SIMD (loongarch_cpu_default_isa[tgt->cpu_arch].simd)
+      switch (cpucfg_cache[2] & 0xc0)
+	{
+	  case 0xc0:
+	    tmp = ISA_EXT_SIMD_LASX;
+	    break;
+
+	  case 0x40:
+	    tmp = ISA_EXT_SIMD_LSX;
+	    break;
+
+	  case 0x80:
+	    tmp = 0;
+	    warning (0, "unknown SIMD extension "
+			"(%qs disabled while %qs is enabled), disabling SIMD",
+			loongarch_isa_ext_strings[ISA_EXT_SIMD_LSX],
+			loongarch_isa_ext_strings[ISA_EXT_SIMD_LASX]);
+	    break;
+
+	  case 0x00:
+	    tmp = 0;
+	    break;
+	}
+
+      /* Check consistency with PRID presets.  */
+
+      /*
+      if (native_cpu_type != CPU_NATIVE && tmp != PRESET_SIMD)
+	warning (0, "SIMD extension %qs differs from PRID preset %qs",
+		 loongarch_isa_ext_strings[tmp],
+		 loongarch_isa_ext_strings[PRESET_SIMD]);
+      */
+
+      /* Use the native value anyways.  */
+      PRESET_SIMD = tmp;
+    }
 
-  return ret_cpu_type;
+  if (tune_native_p)
+    {
+      tgt->cpu_tune = native_cpu_type;
+
+      /* Fill: loongarch_cpu_cache[tgt->cpu_tune]
+	 With: cache size info
+	 At:   cpucfg_words[16:20][31:0] */
+
+      #define PRESET_CACHE (loongarch_cpu_cache[tgt->cpu_tune])
+      struct loongarch_cache native_cache;
+      int l1d_present = 0, l1u_present = 0;
+      int l2d_present = 0;
+      uint32_t l1_szword, l2_szword;
+
+      l1u_present |= cpucfg_cache[16] & 3;	  /* bit[1:0]: unified l1 */
+      l1d_present |= cpucfg_cache[16] & 4;	  /* bit[2:2]: l1d */
+      l1_szword = l1d_present ? 18 : (l1u_present ? 17 : 0);
+      l1_szword = l1_szword ? cpucfg_cache[l1_szword]: 0;
+
+      l2d_present |= cpucfg_cache[16] & 24;	  /* bit[4:3]: unified l2 */
+      l2d_present |= cpucfg_cache[16] & 128;	  /* bit[7:7]: l2d */
+      l2_szword = l2d_present ? cpucfg_cache[19]: 0;
+
+      native_cache.l1d_line_size
+	= 1 << ((l1_szword & 0x7f000000) >> 24);  /* bit[30:24]: log2(line) */
+
+      native_cache.l1d_size
+	= (1 << ((l1_szword & 0x00ff0000) >> 16)) /* bit[23:16]: log2(idx) */
+	* ((l1_szword & 0x0000ffff) + 1)	  /* bit[15:0]:  sets - 1 */
+	* (1 << ((l1_szword & 0x7f000000) >> 24)) /* bit[30:24]: log2(line) */
+	>> 10;					  /* in kibibytes */
+
+      native_cache.l2d_size
+	= (1 << ((l2_szword & 0x00ff0000) >> 16)) /* bit[23:16]: log2(idx) */
+	* ((l2_szword & 0x0000ffff) + 1)	  /* bit[15:0]:  sets - 1 */
+	* (1 << ((l2_szword & 0x7f000000) >> 24)) /* bit[30:24]: log2(linesz) */
+	>> 10;					  /* in kibibytes */
+
+      /* Use the native value anyways.  */
+      PRESET_CACHE.l1d_line_size = native_cache.l1d_line_size;
+      PRESET_CACHE.l1d_size = native_cache.l1d_size;
+      PRESET_CACHE.l2d_size = native_cache.l2d_size;
+    }
 }
diff --git a/gcc/config/loongarch/loongarch-cpu.h b/gcc/config/loongarch/loongarch-cpu.h
index 57ad8456ffa..28618f3cf6c 100644
--- a/gcc/config/loongarch/loongarch-cpu.h
+++ b/gcc/config/loongarch/loongarch-cpu.h
@@ -21,9 +21,10 @@ along with GCC; see the file COPYING3.  If not see
 #define LOONGARCH_CPU_H
 
 #include "system.h"
+#include "loongarch-def.h"
 
 void cache_cpucfg (void);
-unsigned int fill_native_cpu_config (int p_arch_native, int p_tune_native);
+void fill_native_cpu_config (struct loongarch_target *tgt);
 uint32_t get_native_prid (void);
 const char* get_native_prid_str (void);
 
diff --git a/gcc/config/loongarch/loongarch-def.c b/gcc/config/loongarch/loongarch-def.c
index 6729c857f7c..e744ee01d6d 100644
--- a/gcc/config/loongarch/loongarch-def.c
+++ b/gcc/config/loongarch/loongarch-def.c
@@ -21,25 +21,11 @@ along with GCC; see the file COPYING3.  If not see
 #include "loongarch-def.h"
 #include "loongarch-str.h"
 
-/* Default RTX cost initializer.  */
-#define COSTS_N_INSNS(N) ((N) * 4)
-#define DEFAULT_COSTS				\
-    .fp_add		= COSTS_N_INSNS (1),	\
-    .fp_mult_sf		= COSTS_N_INSNS (2),	\
-    .fp_mult_df		= COSTS_N_INSNS (4),	\
-    .fp_div_sf		= COSTS_N_INSNS (6),	\
-    .fp_div_df		= COSTS_N_INSNS (8),	\
-    .int_mult_si	= COSTS_N_INSNS (1),	\
-    .int_mult_di	= COSTS_N_INSNS (1),	\
-    .int_div_si		= COSTS_N_INSNS (4),	\
-    .int_div_di		= COSTS_N_INSNS (6),	\
-    .branch_cost	= 2,			\
-    .memory_latency	= 4
-
 /* CPU property tables.  */
 const char*
 loongarch_cpu_strings[N_TUNE_TYPES] = {
   [CPU_NATIVE]		  = STR_CPU_NATIVE,
+  [CPU_ABI_DEFAULT]	  = STR_CPU_ABI_DEFAULT,
   [CPU_LOONGARCH64]	  = STR_CPU_LOONGARCH64,
   [CPU_LA464]		  = STR_CPU_LA464,
 };
@@ -49,10 +35,12 @@ loongarch_cpu_default_isa[N_ARCH_TYPES] = {
   [CPU_LOONGARCH64] = {
       .base = ISA_BASE_LA64V100,
       .fpu = ISA_EXT_FPU64,
+      .simd = 0,
   },
   [CPU_LA464] = {
       .base = ISA_BASE_LA64V100,
       .fpu = ISA_EXT_FPU64,
+      .simd = ISA_EXT_SIMD_LASX,
   },
 };
 
@@ -84,6 +72,22 @@ loongarch_cpu_align[N_TUNE_TYPES] = {
   },
 };
 
+
+/* Default RTX cost initializer.  */
+#define COSTS_N_INSNS(N) ((N) * 4)
+#define DEFAULT_COSTS				\
+    .fp_add		= COSTS_N_INSNS (1),	\
+    .fp_mult_sf		= COSTS_N_INSNS (2),	\
+    .fp_mult_df		= COSTS_N_INSNS (4),	\
+    .fp_div_sf		= COSTS_N_INSNS (6),	\
+    .fp_div_df		= COSTS_N_INSNS (8),	\
+    .int_mult_si	= COSTS_N_INSNS (1),	\
+    .int_mult_di	= COSTS_N_INSNS (1),	\
+    .int_div_si		= COSTS_N_INSNS (4),	\
+    .int_div_di		= COSTS_N_INSNS (6),	\
+    .branch_cost	= 2,			\
+    .memory_latency	= 4
+
 /* The following properties cannot be looked up directly using "cpucfg".
  So it is necessary to provide a default value for "unknown native"
  tune targets (i.e. -mtune=native while PRID does not correspond to
@@ -103,7 +107,7 @@ loongarch_cpu_rtx_cost_data[N_TUNE_TYPES] = {
 };
 
 /* RTX costs to use when optimizing for size.  */
-extern const struct loongarch_rtx_cost_data
+const struct loongarch_rtx_cost_data
 loongarch_rtx_cost_optimize_size = {
     .fp_add	      = 4,
     .fp_mult_sf	      = 4,
@@ -144,9 +148,11 @@ loongarch_isa_base_strings[N_ISA_BASE_TYPES] = {
 
 const char*
 loongarch_isa_ext_strings[N_ISA_EXT_TYPES] = {
-  [ISA_EXT_FPU64] = STR_ISA_EXT_FPU64,
+  [ISA_EXT_NONE] = STR_NONE,
   [ISA_EXT_FPU32] = STR_ISA_EXT_FPU32,
-  [ISA_EXT_NOFPU] = STR_ISA_EXT_NOFPU,
+  [ISA_EXT_FPU64] = STR_ISA_EXT_FPU64,
+  [ISA_EXT_SIMD_LSX] = STR_ISA_EXT_LSX,
+  [ISA_EXT_SIMD_LASX] = STR_ISA_EXT_LASX,
 };
 
 const char*
@@ -171,24 +177,29 @@ loongarch_cmodel_strings[] = {
   [CMODEL_EXTREME]	  = STR_CMODEL_EXTREME,
 };
 
-const char*
-loongarch_switch_strings[] = {
-  [SW_SOFT_FLOAT]	  = OPTSTR_SOFT_FLOAT,
-  [SW_SINGLE_FLOAT]	  = OPTSTR_SINGLE_FLOAT,
-  [SW_DOUBLE_FLOAT]	  = OPTSTR_DOUBLE_FLOAT,
-};
-
 
 /* ABI-related definitions.  */
 const struct loongarch_isa
 abi_minimal_isa[N_ABI_BASE_TYPES][N_ABI_EXT_TYPES] = {
   [ABI_BASE_LP64D] = {
-      [ABI_EXT_BASE] = {.base = ISA_BASE_LA64V100, .fpu = ISA_EXT_FPU64},
+      [ABI_EXT_BASE] = {
+	  .base = ISA_BASE_LA64V100,
+	  .fpu = ISA_EXT_FPU64,
+	  .simd = 0
+      },
   },
   [ABI_BASE_LP64F] = {
-      [ABI_EXT_BASE] = {.base = ISA_BASE_LA64V100, .fpu = ISA_EXT_FPU32},
+      [ABI_EXT_BASE] = {
+	  .base = ISA_BASE_LA64V100,
+	  .fpu = ISA_EXT_FPU32,
+	  .simd = 0
+      },
   },
   [ABI_BASE_LP64S] = {
-      [ABI_EXT_BASE] = {.base = ISA_BASE_LA64V100, .fpu = ISA_EXT_NOFPU},
+      [ABI_EXT_BASE] = {
+	  .base = ISA_BASE_LA64V100,
+	  .fpu = ISA_EXT_NONE,
+	  .simd = 0
+      },
   },
 };
diff --git a/gcc/config/loongarch/loongarch-def.h b/gcc/config/loongarch/loongarch-def.h
index fb8bb88eb52..769efcb70fb 100644
--- a/gcc/config/loongarch/loongarch-def.h
+++ b/gcc/config/loongarch/loongarch-def.h
@@ -59,11 +59,13 @@ extern const char* loongarch_isa_base_strings[];
 
 /* enum isa_ext_* */
 extern const char* loongarch_isa_ext_strings[];
-#define ISA_EXT_NOFPU	      0
+#define ISA_EXT_NONE	      0
 #define ISA_EXT_FPU32	      1
 #define ISA_EXT_FPU64	      2
 #define N_ISA_EXT_FPU_TYPES   3
-#define N_ISA_EXT_TYPES	      3
+#define ISA_EXT_SIMD_LSX      3
+#define ISA_EXT_SIMD_LASX     4
+#define N_ISA_EXT_TYPES	      5
 
 /* enum abi_base */
 extern const char* loongarch_abi_base_strings[];
@@ -72,6 +74,16 @@ extern const char* loongarch_abi_base_strings[];
 #define ABI_BASE_LP64S	      2
 #define N_ABI_BASE_TYPES      3
 
+#define TO_LP64_ABI_BASE(C) (C)
+
+#define ABI_FPU_64(abi_base) \
+  (abi_base == ABI_BASE_LP64D)
+#define ABI_FPU_32(abi_base) \
+  (abi_base == ABI_BASE_LP64F)
+#define ABI_FPU_NONE(abi_base) \
+  (abi_base == ABI_BASE_LP64S)
+
+
 /* enum abi_ext */
 extern const char* loongarch_abi_ext_strings[];
 #define ABI_EXT_BASE	      0
@@ -87,55 +99,44 @@ extern const char* loongarch_cmodel_strings[];
 #define CMODEL_EXTREME	      5
 #define N_CMODEL_TYPES	      6
 
-/* enum switches */
-/* The "SW_" codes represent command-line switches (options that
-   accept no parameters). Definition for other switches that affects
-   the target ISA / ABI configuration will also be appended here
-   in the future.  */
-
-extern const char* loongarch_switch_strings[];
-#define SW_SOFT_FLOAT	      0
-#define SW_SINGLE_FLOAT	      1
-#define SW_DOUBLE_FLOAT	      2
-#define N_SWITCH_TYPES	      3
-
 /* The common default value for variables whose assignments
    are triggered by command-line options.  */
 
-#define M_OPTION_NOT_SEEN -1
-#define M_OPT_ABSENT(opt_enum)  ((opt_enum) == M_OPTION_NOT_SEEN)
+#define M_OPT_UNSET -1
+#define M_OPT_ABSENT(opt_enum)  ((opt_enum) == M_OPT_UNSET)
 
 
 /* Internal representation of the target.  */
 struct loongarch_isa
 {
-  unsigned char base;	    /* ISA_BASE_ */
-  unsigned char fpu;	    /* ISA_EXT_FPU_ */
+  int base;	    /* ISA_BASE_ */
+  int fpu;	    /* ISA_EXT_FPU_ */
+  int simd;	    /* ISA_EXT_SIMD_ */
 };
 
 struct loongarch_abi
 {
-  unsigned char base;	    /* ABI_BASE_ */
-  unsigned char ext;	    /* ABI_EXT_ */
+  int base;	    /* ABI_BASE_ */
+  int ext;	    /* ABI_EXT_ */
 };
 
 struct loongarch_target
 {
   struct loongarch_isa isa;
   struct loongarch_abi abi;
-  unsigned char cpu_arch;   /* CPU_ */
-  unsigned char cpu_tune;   /* same */
-  unsigned char cpu_native; /* same */
-  unsigned char cmodel;	    /* CMODEL_ */
+  int cpu_arch;	    /* CPU_ */
+  int cpu_tune;	    /* same */
+  int cmodel;	    /* CMODEL_ */
 };
 
 /* CPU properties.  */
 /* index */
 #define CPU_NATIVE	  0
-#define CPU_LOONGARCH64	  1
-#define CPU_LA464	  2
-#define N_ARCH_TYPES	  3
-#define N_TUNE_TYPES	  3
+#define CPU_ABI_DEFAULT   1
+#define CPU_LOONGARCH64	  2
+#define CPU_LA464	  3
+#define N_ARCH_TYPES	  4
+#define N_TUNE_TYPES	  4
 
 /* parallel tables.  */
 extern const char* loongarch_cpu_strings[];
diff --git a/gcc/config/loongarch/loongarch-driver.cc b/gcc/config/loongarch/loongarch-driver.cc
index 11ce082417f..bafd27e67a5 100644
--- a/gcc/config/loongarch/loongarch-driver.cc
+++ b/gcc/config/loongarch/loongarch-driver.cc
@@ -26,122 +26,137 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm.h"
 #include "obstack.h"
 #include "diagnostic-core.h"
+#include "opts.h"
 
 #include "loongarch-opts.h"
 #include "loongarch-driver.h"
 
-static int
-  opt_arch_driver = M_OPTION_NOT_SEEN,
-  opt_tune_driver = M_OPTION_NOT_SEEN,
-  opt_fpu_driver = M_OPTION_NOT_SEEN,
-  opt_abi_base_driver = M_OPTION_NOT_SEEN,
-  opt_abi_ext_driver = M_OPTION_NOT_SEEN,
-  opt_cmodel_driver = M_OPTION_NOT_SEEN;
-
-int opt_switches = 0;
-
 /* This flag is set to 1 if we believe that the user might be avoiding
    linking (implicitly) against something from the startfile search paths.  */
 static int no_link = 0;
 
-#define LARCH_DRIVER_SET_M_FLAG(OPTS_ARRAY, N_OPTS, FLAG, STR)	\
-  for (int i = 0; i < (N_OPTS); i++)				\
-  {								\
-    if ((OPTS_ARRAY)[i] != 0)					\
-      if (strcmp ((STR), (OPTS_ARRAY)[i]) == 0)			\
-	(FLAG) = i;						\
-  }
-
 /* Use the public obstack from the gcc driver (defined in gcc.c).
    This is for allocating space for the returned string.  */
 extern struct obstack opts_obstack;
 
-#define APPEND_LTR(S)				      \
-  obstack_grow (&opts_obstack, (const void*) (S),     \
-		sizeof ((S)) / sizeof (char) -1)
-
-#define APPEND_VAL(S) \
-  obstack_grow (&opts_obstack, (const void*) (S), strlen ((S)))
+const char*
+la_driver_init (int argc ATTRIBUTE_UNUSED, const char **argv ATTRIBUTE_UNUSED)
+{
+  /* Initialize all fields of la_target to -1 */
+  loongarch_init_target (&la_target, M_OPT_UNSET, M_OPT_UNSET, M_OPT_UNSET,
+			 M_OPT_UNSET, M_OPT_UNSET, M_OPT_UNSET, M_OPT_UNSET);
+  return "";
+}
 
+const char*
+driver_set_no_link (int argc ATTRIBUTE_UNUSED,
+		    const char **argv ATTRIBUTE_UNUSED)
+{
+  no_link = 1;
+  return "";
+}
 
 const char*
-driver_set_m_flag (int argc, const char **argv)
+driver_set_m_parm (int argc, const char **argv)
 {
-  int parm_off = 0;
+  gcc_assert (argc == 2);
+
+#define LARCH_DRIVER_PARSE_PARM(OPT_IDX, NAME, OPTSTR_LIST, \
+				OPT_IDX_LO, OPT_IDX_HI)	    \
+  if (strcmp (argv[0], OPTSTR_##NAME) == 0)		    \
+    for (int i = (OPT_IDX_LO); i < (OPT_IDX_HI); i++)	    \
+    {							    \
+      if ((OPTSTR_LIST)[i] != 0)			    \
+	if (strcmp (argv[1], (OPTSTR_LIST)[i]) == 0)	    \
+	  {						    \
+	    (OPT_IDX) = i;				    \
+	    return 0;					    \
+	  }						    \
+    }
 
-  if (argc != 1)
-    return "%eset_m_flag requires exactly 1 argument.";
+  LARCH_DRIVER_PARSE_PARM (la_target.abi.base, ABI_BASE, \
+			   loongarch_abi_base_strings, 0, N_ABI_BASE_TYPES)
 
-#undef PARM
-#define PARM (argv[0] + parm_off)
+  LARCH_DRIVER_PARSE_PARM (la_target.isa.fpu, ISA_EXT_FPU, \
+			   loongarch_isa_ext_strings, 0, N_ISA_EXT_FPU_TYPES)
 
-/* Note: sizeof (OPTSTR_##NAME) equals the length of "<option>=".  */
-#undef MATCH_OPT
-#define MATCH_OPT(NAME) \
-  (strncmp (argv[0], OPTSTR_##NAME "=", \
-	    (parm_off = sizeof (OPTSTR_##NAME))) == 0)
+  LARCH_DRIVER_PARSE_PARM (la_target.isa.simd, ISA_EXT_SIMD, \
+			   loongarch_isa_ext_strings, 0, N_ISA_EXT_TYPES)
 
-  if (strcmp (argv[0], "no_link") == 0)
-    {
-      no_link = 1;
-    }
-  else if (MATCH_OPT (ABI_BASE))
-    {
-      LARCH_DRIVER_SET_M_FLAG (
-	loongarch_abi_base_strings, N_ABI_BASE_TYPES,
-	opt_abi_base_driver, PARM)
-    }
-  else if (MATCH_OPT (ISA_EXT_FPU))
-    {
-      LARCH_DRIVER_SET_M_FLAG (loongarch_isa_ext_strings, N_ISA_EXT_FPU_TYPES,
-			       opt_fpu_driver, PARM)
-    }
-  else if (MATCH_OPT (ARCH))
-    {
-      LARCH_DRIVER_SET_M_FLAG (loongarch_cpu_strings, N_ARCH_TYPES,
-			       opt_arch_driver, PARM)
-    }
-  else if (MATCH_OPT (TUNE))
-    {
-      LARCH_DRIVER_SET_M_FLAG (loongarch_cpu_strings, N_TUNE_TYPES,
-			       opt_tune_driver, PARM)
-    }
-  else if (MATCH_OPT (CMODEL))
-    {
-      LARCH_DRIVER_SET_M_FLAG (loongarch_cmodel_strings, N_CMODEL_TYPES,
-			       opt_cmodel_driver, PARM)
-    }
-  else /* switches */
-    {
-      int switch_idx = M_OPTION_NOT_SEEN;
+  LARCH_DRIVER_PARSE_PARM (la_target.cpu_arch, ARCH, \
+			   loongarch_cpu_strings, 0, N_ARCH_TYPES)
 
-      LARCH_DRIVER_SET_M_FLAG (loongarch_switch_strings, N_SWITCH_TYPES,
-			       switch_idx, argv[0])
+  LARCH_DRIVER_PARSE_PARM (la_target.cpu_tune, TUNE, \
+			   loongarch_cpu_strings, 0, N_TUNE_TYPES)
 
-      if (switch_idx != M_OPTION_NOT_SEEN)
-	opt_switches |= loongarch_switch_mask[switch_idx];
-    }
-  return "";
+  LARCH_DRIVER_PARSE_PARM (la_target.cmodel, CMODEL, \
+			   loongarch_cmodel_strings, 0, N_CMODEL_TYPES)
+
+  gcc_unreachable ();
+}
+
+static void
+driver_record_deferred_opts (struct loongarch_flags *flags)
+{
+  unsigned int i;
+  cl_deferred_option *opt;
+  vec<cl_deferred_option> *v = (vec<cl_deferred_option> *) la_deferred_options;
+
+  gcc_assert (flags);
+
+  /* Initialize flags */
+  flags->flt = M_OPT_UNSET;
+  flags->flt_str = NULL;
+  flags->sx[0] = flags->sx[1] = 0;
+
+  int sx_flag_idx = 0;
+
+  if (v)
+    FOR_EACH_VEC_ELT (*v, i, opt)
+      {
+	switch (opt->opt_index)
+	  {
+	  case OPT_mlsx:
+	    flags->sx[sx_flag_idx++] = ISA_EXT_SIMD_LSX
+	      * (opt->value ? 1 : -1);
+	    break;
+
+	  case OPT_mlasx:
+	    flags->sx[sx_flag_idx++] = ISA_EXT_SIMD_LASX
+	      * (opt->value ? 1 : -1);
+	    break;
+
+	  case OPT_msoft_float:
+	    flags->flt = ISA_EXT_NONE;
+	    flags->flt_str = OPTSTR_SOFT_FLOAT;
+	    break;
+
+	  case OPT_msingle_float:
+	    flags->flt = ISA_EXT_FPU32;
+	    flags->flt_str = OPTSTR_SINGLE_FLOAT;
+	    break;
+
+	  case OPT_mdouble_float:
+	    flags->flt = ISA_EXT_FPU64;
+	    flags->flt_str = OPTSTR_DOUBLE_FLOAT;
+	    break;
+
+	  default:
+	    gcc_unreachable ();
+	  }
+	gcc_assert (sx_flag_idx <= 2);
+      }
 }
 
 const char*
-driver_get_normalized_m_opts (int argc, const char **argv)
+driver_get_normalized_m_opts (int argc, const char **argv ATTRIBUTE_UNUSED)
 {
   if (argc != 0)
-    {
-      (void) argv;  /* To make compiler shut up about unused argument.  */
-      return " %eget_normalized_m_opts requires no argument.\n";
-    }
+    return " %eget_normalized_m_opts requires no argument.\n";
 
-  loongarch_config_target (& la_target,
-			   opt_switches,
-			   opt_arch_driver,
-			   opt_tune_driver,
-			   opt_fpu_driver,
-			   opt_abi_base_driver,
-			   opt_abi_ext_driver,
-			   opt_cmodel_driver,
-			   !no_link /* follow_multilib_list */);
+  struct loongarch_flags flags;
+  driver_record_deferred_opts (&flags);
+  loongarch_config_target (&la_target, &flags, !no_link);
 
   /* Output normalized option strings.  */
   obstack_blank (&opts_obstack, 0);
@@ -160,11 +175,15 @@ driver_get_normalized_m_opts (int argc, const char **argv)
    APPEND_LTR (" %<m" OPTSTR_##NAME "=* " \
 	       " -m" OPTSTR_##NAME "=")
 
-  for (int i = 0; i < N_SWITCH_TYPES; i++)
-    {
-      APPEND_LTR (" %<m");
-      APPEND_VAL (loongarch_switch_strings[i]);
-    }
+#undef CLEAR_FLAG
+#define CLEAR_FLAG(NAME) \
+  APPEND_LTR (" %<m" NAME " %<mno-" NAME)
+
+  CLEAR_FLAG (STR_ISA_EXT_LSX);
+  CLEAR_FLAG (STR_ISA_EXT_LASX);
+  CLEAR_FLAG (OPTSTR_SOFT_FLOAT);
+  CLEAR_FLAG (OPTSTR_SINGLE_FLOAT);
+  CLEAR_FLAG (OPTSTR_DOUBLE_FLOAT);
 
   APPEND_OPT (ABI_BASE);
   APPEND_VAL (loongarch_abi_base_strings[la_target.abi.base]);
@@ -175,6 +194,9 @@ driver_get_normalized_m_opts (int argc, const char **argv)
   APPEND_OPT (ISA_EXT_FPU);
   APPEND_VAL (loongarch_isa_ext_strings[la_target.isa.fpu]);
 
+  APPEND_OPT (ISA_EXT_SIMD);
+  APPEND_VAL (loongarch_isa_ext_strings[la_target.isa.simd]);
+
   APPEND_OPT (CMODEL);
   APPEND_VAL (loongarch_cmodel_strings[la_target.cmodel]);
 
diff --git a/gcc/config/loongarch/loongarch-driver.h b/gcc/config/loongarch/loongarch-driver.h
index ba8817a4621..b39b96dec36 100644
--- a/gcc/config/loongarch/loongarch-driver.h
+++ b/gcc/config/loongarch/loongarch-driver.h
@@ -24,33 +24,37 @@ along with GCC; see the file COPYING3.  If not see
 #include "loongarch-str.h"
 
 extern const char*
-driver_set_m_flag (int argc, const char **argv);
+la_driver_init (int argc, const char **argv);
+
+extern const char*
+driver_set_m_parm (int argc, const char **argv);
+
+extern const char*
+driver_set_no_link (int argc, const char **argv);
 
 extern const char*
 driver_get_normalized_m_opts (int argc, const char **argv);
 
 #define EXTRA_SPEC_FUNCTIONS \
-  { "set_m_flag", driver_set_m_flag  }, \
+  { "driver_init", la_driver_init }, \
+  { "set_m_parm", driver_set_m_parm  }, \
+  { "set_no_link", driver_set_no_link }, \
   { "get_normalized_m_opts", driver_get_normalized_m_opts  },
 
 /* Pre-process ABI-related options.  */
 #define LA_SET_PARM_SPEC(NAME) \
-  " %{m" OPTSTR_##NAME  "=*: %:set_m_flag(" OPTSTR_##NAME "=%*)}" \
-
-#define LA_SET_FLAG_SPEC(NAME) \
-  " %{m" OPTSTR_##NAME  ": %:set_m_flag(" OPTSTR_##NAME ")}" \
-
-#define DRIVER_HANDLE_MACHINE_OPTIONS			      \
-  " %{c|S|E|nostdlib: %:set_m_flag(no_link)}"		      \
-  " %{nostartfiles: %{nodefaultlibs: %:set_m_flag(no_link)}}" \
-  LA_SET_PARM_SPEC (ABI_BASE)				      \
-  LA_SET_PARM_SPEC (ARCH)				      \
-  LA_SET_PARM_SPEC (TUNE)				      \
-  LA_SET_PARM_SPEC (ISA_EXT_FPU)			      \
-  LA_SET_PARM_SPEC (CMODEL)				      \
-  LA_SET_FLAG_SPEC (SOFT_FLOAT)				      \
-  LA_SET_FLAG_SPEC (SINGLE_FLOAT)			      \
-  LA_SET_FLAG_SPEC (DOUBLE_FLOAT)			      \
+  " %{m" OPTSTR_##NAME  "=*: %:set_m_parm(" OPTSTR_##NAME " %*)}" \
+
+#define DRIVER_HANDLE_MACHINE_OPTIONS \
+  " %:driver_init()" \
+  " %{c|S|E|nostdlib: %:set_no_link()}" \
+  " %{nostartfiles: %{nodefaultlibs: %:set_no_link()}}" \
+  LA_SET_PARM_SPEC (ABI_BASE) \
+  LA_SET_PARM_SPEC (ARCH) \
+  LA_SET_PARM_SPEC (TUNE) \
+  LA_SET_PARM_SPEC (ISA_EXT_FPU) \
+  LA_SET_PARM_SPEC (ISA_EXT_SIMD) \
+  LA_SET_PARM_SPEC (CMODEL) \
   " %:get_normalized_m_opts()"
 
 #define DRIVER_SELF_SPECS \
diff --git a/gcc/config/loongarch/loongarch-opts.cc b/gcc/config/loongarch/loongarch-opts.cc
index a52e25236ea..e5921189a06 100644
--- a/gcc/config/loongarch/loongarch-opts.cc
+++ b/gcc/config/loongarch/loongarch-opts.cc
@@ -26,9 +26,11 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm.h"
 #include "obstack.h"
 #include "diagnostic-core.h"
+
 #include "loongarch-cpu.h"
 #include "loongarch-opts.h"
 #include "loongarch-str.h"
+#include "loongarch-def.h"
 
 struct loongarch_target la_target;
 
@@ -76,16 +78,6 @@ init_enabled_abi_types ()
 #endif
 }
 
-/* Switch masks.  */
-#undef M
-#define M(NAME) OPTION_MASK_##NAME
-const int loongarch_switch_mask[N_SWITCH_TYPES] = {
-  /* SW_SOFT_FLOAT */    M(FORCE_SOFTF),
-  /* SW_SINGLE_FLOAT */  M(FORCE_F32),
-  /* SW_DOUBLE_FLOAT */  M(FORCE_F64),
-};
-#undef M
-
 /* String processing.  */
 static struct obstack msg_obstack;
 #define APPEND_STRING(STR) obstack_grow (&msg_obstack, STR, strlen(STR));
@@ -104,9 +96,10 @@ static int isa_fpu_compat_p (const struct loongarch_isa *set1,
 			     const struct loongarch_isa *set2);
 static int abi_compat_p (const struct loongarch_isa *isa,
 			 struct loongarch_abi abi);
-static int abi_default_cpu_arch (struct loongarch_abi abi);
+static int abi_default_cpu_arch (struct loongarch_abi abi,
+				 struct loongarch_isa *isa);
 
-/* Checking configure-time defaults.  */
+/* Mandatory configure-time defaults.  */
 #ifndef DEFAULT_ABI_BASE
 #error missing definition of DEFAULT_ABI_BASE in ${tm_defines}.
 #endif
@@ -119,21 +112,57 @@ static int abi_default_cpu_arch (struct loongarch_abi abi);
 #error missing definition of DEFAULT_CPU_ARCH in ${tm_defines}.
 #endif
 
-#ifndef DEFAULT_ISA_EXT_FPU
-#error missing definition of DEFAULT_ISA_EXT_FPU in ${tm_defines}.
+/* Optional configure-time defaults.  */
+#ifdef DEFAULT_CPU_TUNE
+static int with_default_tune = 1;
+#else
+#define DEFAULT_CPU_TUNE -1
+static int with_default_tune = 0;
+#endif
+
+#ifdef DEFAULT_ISA_EXT_FPU
+static int with_default_fpu = 1;
+#else
+#define DEFAULT_ISA_EXT_FPU -1
+static int with_default_fpu = 0;
+#endif
+
+#ifdef DEFAULT_ISA_EXT_SIMD
+static int with_default_simd = 1;
+#else
+#define DEFAULT_ISA_EXT_SIMD -1
+static int with_default_simd = 0;
 #endif
 
-/* Handle combinations of -m machine option values
+
+/* Initialize loongarch_target from separate option variables.  */
+
+void
+loongarch_init_target (struct loongarch_target *target,
+		       int cpu_arch, int cpu_tune, int fpu, int simd,
+		       int abi_base, int abi_ext, int cmodel)
+{
+  if (!target)
+    return;
+  target->cpu_arch = cpu_arch;
+  target->cpu_tune = cpu_tune;
+  target->isa.fpu = fpu;
+  target->isa.simd = simd;
+  target->abi.base = abi_base;
+  target->abi.ext = abi_ext;
+  target->cmodel = cmodel;
+}
+
+
+/* Handle combinations of -m parameters
    (see loongarch.opt and loongarch-opts.h).  */
+
 void
 loongarch_config_target (struct loongarch_target *target,
-			 HOST_WIDE_INT opt_switches,
-			 int opt_arch, int opt_tune, int opt_fpu,
-			 int opt_abi_base, int opt_abi_ext,
-			 int opt_cmodel, int follow_multilib_list)
+			 struct loongarch_flags *flags,
+			 int follow_multilib_list_p)
 {
   struct loongarch_target t;
-
   if (!target)
     return;
 
@@ -142,67 +171,63 @@ loongarch_config_target (struct loongarch_target *target,
   obstack_init (&msg_obstack);
 
   struct {
-    int arch, tune, fpu, abi_base, abi_ext, cmodel;
+    int arch, tune, fpu, simd, abi_base, abi_ext, cmodel, abi_flt;
   } constrained = {
-      M_OPT_ABSENT(opt_arch)     ? 0 : 1,
-      M_OPT_ABSENT(opt_tune)     ? 0 : 1,
-      M_OPT_ABSENT(opt_fpu)      ? 0 : 1,
-      M_OPT_ABSENT(opt_abi_base) ? 0 : 1,
-      M_OPT_ABSENT(opt_abi_ext)  ? 0 : 1,
-      M_OPT_ABSENT(opt_cmodel)   ? 0 : 1,
+      M_OPT_ABSENT (target->cpu_arch)	  ? 0 : 1,
+      M_OPT_ABSENT (target->cpu_tune)	  ? 0 : 1,
+      M_OPT_ABSENT (target->isa.fpu)	  ? 0 : 1,
+      M_OPT_ABSENT (target->isa.simd)	  ? 0 : 1,
+      M_OPT_ABSENT (target->abi.base)	  ? 0 : 1,
+      M_OPT_ABSENT (target->abi.ext)	  ? 0 : 1,
+      M_OPT_ABSENT (target->cmodel)	  ? 0 : 1,
+      M_OPT_ABSENT (target->abi.base)	  ? 0 : 1,
   };
 
-#define on(NAME) ((loongarch_switch_mask[(SW_##NAME)] & opt_switches) \
-		  && (on_switch = (SW_##NAME), 1))
-  int on_switch;
-
   /* 1.  Target ABI */
-  t.abi.base = constrained.abi_base ? opt_abi_base : DEFAULT_ABI_BASE;
+  if (constrained.abi_base)
+    t.abi.base = target->abi.base;
+  else
+    t.abi.base = DEFAULT_ABI_BASE;
 
-  t.abi.ext = constrained.abi_ext ? opt_abi_ext : DEFAULT_ABI_EXT;
+  t.abi.ext = constrained.abi_ext ? target->abi.ext : DEFAULT_ABI_EXT;
 
-  /* Extra switch handling.  */
-  if (on (SOFT_FLOAT) || on (SINGLE_FLOAT) || on (DOUBLE_FLOAT))
+  /* Process -m*-float flags */
+  if (flags && !M_OPT_ABSENT (flags->flt))
     {
-      switch (on_switch)
-	{
-	  case SW_SOFT_FLOAT:
-	    opt_fpu = ISA_EXT_NOFPU;
-	    break;
-
-	  case SW_SINGLE_FLOAT:
-	    opt_fpu = ISA_EXT_FPU32;
-	    break;
-
-	  case SW_DOUBLE_FLOAT:
-	    opt_fpu = ISA_EXT_FPU64;
-	    break;
+      /* Modifying the original "target" here makes it easier to write the
+	 t.isa.fpu assignment below, because otherwise there would be three
+	 levels of precedence (-m*-float / -mfpu / -march) to be handled
+	 (now the first two are merged). */
 
-	  default:
-	    gcc_unreachable();
-	}
+      target->isa.fpu = flags->flt;
       constrained.fpu = 1;
 
       /* The target ISA is not ready yet, but (isa_required (t.abi)
 	 + forced fpu) is enough for computing the forced base ABI.  */
-      struct loongarch_isa default_isa = isa_required (t.abi);
-      struct loongarch_isa force_isa = default_isa;
-      struct loongarch_abi force_abi = t.abi;
-      force_isa.fpu = opt_fpu;
+
+      struct loongarch_isa force_isa = isa_required (t.abi);
+      force_isa.fpu = flags->flt;
+
+      struct loongarch_abi force_abi;
       force_abi.base = isa_default_abi (&force_isa).base;
 
-      if (constrained.abi_base && (t.abi.base != force_abi.base))
-	inform (UNKNOWN_LOCATION,
-		"%<-m%s%> overrides %<-m%s=%s%>, adjusting ABI to %qs",
-		loongarch_switch_strings[on_switch],
-		OPTSTR_ABI_BASE, loongarch_abi_base_strings[t.abi.base],
-		abi_str (force_abi));
+      if (constrained.abi_base && constrained.abi_flt
+	  && (t.abi.base != force_abi.base))
+	{
+	  force_abi.ext = t.abi.ext;
+	  inform (UNKNOWN_LOCATION,
+		  "%<-m%s%> overrides %<-m%s=%s%>, adjusting ABI to %qs",
+		  flags->flt_str, OPTSTR_ABI_BASE,
+		  loongarch_abi_base_strings[t.abi.base],
+		  abi_str (force_abi));
+	}
 
       t.abi.base = force_abi.base;
+      constrained.abi_flt = 1;
     }
 
 #ifdef LA_DISABLE_MULTILIB
-  if (follow_multilib_list)
+  if (follow_multilib_list_p)
     if (t.abi.base != DEFAULT_ABI_BASE || t.abi.ext != DEFAULT_ABI_EXT)
       {
 	static const struct loongarch_abi default_abi
@@ -214,18 +239,22 @@ loongarch_config_target (struct loongarch_target *target,
 #endif
 
   /* 2.  Target CPU */
-  t.cpu_arch = constrained.arch ? opt_arch : DEFAULT_CPU_ARCH;
+  t.cpu_arch = constrained.arch ? target->cpu_arch : DEFAULT_CPU_ARCH;
+
+  /* If cpu_tune is not set using neither -mtune nor --with-tune,
+     the current cpu_arch is used as its default.  */
+  t.cpu_tune = constrained.tune ? target->cpu_tune
+    : (constrained.arch ? target->cpu_arch :
+       (with_default_tune ? DEFAULT_CPU_TUNE : DEFAULT_CPU_ARCH));
 
-  t.cpu_tune = constrained.tune ? opt_tune
-    : (constrained.arch ? DEFAULT_CPU_ARCH : DEFAULT_CPU_TUNE);
 
+  /* Handle -march/tune=native */
 #ifdef __loongarch__
   /* For native compilers, gather local CPU information
      and fill the "CPU_NATIVE" index of arrays defined in
      loongarch-cpu.c.  */
 
-  t.cpu_native = fill_native_cpu_config (t.cpu_arch == CPU_NATIVE,
-					 t.cpu_tune == CPU_NATIVE);
+  fill_native_cpu_config (&t);
 
 #else
   if (t.cpu_arch == CPU_NATIVE)
@@ -239,17 +268,130 @@ loongarch_config_target (struct loongarch_target *target,
 		 "-m" OPTSTR_TUNE "=" STR_CPU_NATIVE);
 #endif
 
-  /* 3.  Target ISA */
+  /* Handle -march/tune=abi-default */
+  if (t.cpu_tune == CPU_ABI_DEFAULT)
+    t.cpu_tune = abi_default_cpu_arch (t.abi, NULL);
+
+  if (t.cpu_arch == CPU_ABI_DEFAULT)
+    {
+      t.cpu_arch = abi_default_cpu_arch (t.abi, &(t.isa));
+      loongarch_cpu_default_isa[t.cpu_arch] = t.isa;
+    }
+
+  /* 3.  Target base ISA */
 config_target_isa:
 
   /* Get default ISA from "-march" or its default value.  */
-  t.isa = loongarch_cpu_default_isa[LARCH_ACTUAL_ARCH];
+  t.isa = loongarch_cpu_default_isa[t.cpu_arch];
 
   /* Apply incremental changes.  */
   /* "-march=native" overrides the default FPU type.  */
-  t.isa.fpu = constrained.fpu ? opt_fpu :
-    ((t.cpu_arch == CPU_NATIVE && constrained.arch) ?
-     t.isa.fpu : DEFAULT_ISA_EXT_FPU);
+
+  t.isa.fpu = constrained.fpu ? target->isa.fpu :
+    (constrained.arch ? t.isa.fpu :
+    (with_default_fpu ? DEFAULT_ISA_EXT_FPU : t.isa.fpu));
+
+  int simd_base = (constrained.arch ? t.isa.simd :
+    (with_default_simd ? DEFAULT_ISA_EXT_SIMD : t.isa.simd));
+
+  t.isa.simd = constrained.simd ? target->isa.simd : simd_base;
+
+  /* If fallback_lsx is set, using -mno-lasx would cause
+     a fall-back to -msimd=lsx instead of -msimd=none.  */
+
+  int fallback_lsx = 0;
+  if (t.isa.simd == ISA_EXT_SIMD_LSX || simd_base != ISA_EXT_NONE)
+    fallback_lsx = 1;
+
+  /* apply -m[no-]lsx and -m[no-]lasx flags */
+  if (flags)
+    for (int i = 0; i < 2; i++)
+      {
+	switch (SX_FLAG_TYPE (flags->sx[i]))
+	  {
+	  case ISA_EXT_SIMD_LSX:
+	    constrained.simd = 1;
+
+	    if (flags->sx[i] > 0)
+	      fallback_lsx = 1;
+
+	    if (flags->sx[i] > 0 && t.isa.simd != ISA_EXT_SIMD_LASX)
+	      t.isa.simd = ISA_EXT_SIMD_LSX;
+	    else if (flags->sx[i] < 0)
+	      t.isa.simd = ISA_EXT_NONE;
+	    break;
+
+	  case ISA_EXT_SIMD_LASX:
+	    constrained.simd = 1;
+	    /* If -mlsx or simd=lsx (msimd or march-default) was not
+	       involved, do not fall back to simd=lsx.  */
+	    if (flags->sx[i] < 0 && t.isa.simd == ISA_EXT_SIMD_LASX)
+	      t.isa.simd = fallback_lsx ? ISA_EXT_SIMD_LSX : ISA_EXT_NONE;
+	    else if (flags->sx[i] > 0)
+	      t.isa.simd = ISA_EXT_SIMD_LASX;
+	    break;
+
+	  case 0:
+	    break;
+
+	  default:
+	    gcc_unreachable ();
+	  }
+      }
+
+  /* All SIMD extensions imply a 64-bit FPU:
+     - silently adjust t.isa.fpu to "fpu64" if it is unconstrained.
+     - warn if -msingle-float / -msoft-float is on,
+       then disable SIMD extensions (done in driver)
+     - abort if -mfpu=0 / -mfpu=32 is forced.  */
+
+  if (t.isa.simd != ISA_EXT_NONE && t.isa.fpu != ISA_EXT_FPU64)
+    {
+      if (!constrained.fpu)
+	{
+	  /* As long as the arch-default "t.isa.simd" is set to non-zero
+	     for an element "t" in loongarch_cpu_default_isa, "t.isa.fpu"
+	     should be set to "ISA_EXT_FPU64" accordingly.  Thus reaching
+	     here must be the result of forcing -mlsx/-mlasx explicitly.  */
+	  gcc_assert (constrained.simd);
+
+	  inform (UNKNOWN_LOCATION,
+		  "enabing %qs promotes %<%s%s%> to %<%s%s%>",
+		  loongarch_isa_ext_strings[t.isa.simd],
+		  OPTSTR_ISA_EXT_FPU, loongarch_isa_ext_strings[t.isa.fpu],
+		  OPTSTR_ISA_EXT_FPU, loongarch_isa_ext_strings[ISA_EXT_FPU64]);
+
+	  t.isa.fpu = ISA_EXT_FPU64;
+	}
+      else if (flags && (flags->flt == ISA_EXT_NONE
+			 || flags->flt == ISA_EXT_FPU32))
+	{
+	  if (constrained.simd)
+	    inform (UNKNOWN_LOCATION,
+		    "%qs is disabled by %<-m%s%>, because it requires %<%s%s%>",
+		    loongarch_isa_ext_strings[t.isa.simd], flags->flt_str,
+		    OPTSTR_ISA_EXT_FPU,
+		    loongarch_isa_ext_strings[ISA_EXT_FPU64]);
+
+	  t.isa.simd = ISA_EXT_NONE;
+	}
+      else
+	{
+	  /* -mfpu=0 / -mfpu=32 is set.  */
+	  if (constrained.simd)
+	    fatal_error (UNKNOWN_LOCATION,
+			 "%<-m%s=%s%> conflicts with %qs, "
+			 "which requires %<%s%s%>",
+			 OPTSTR_ISA_EXT_FPU,
+			 loongarch_isa_ext_strings[t.isa.fpu],
+			 loongarch_isa_ext_strings[t.isa.simd],
+			 OPTSTR_ISA_EXT_FPU,
+			 loongarch_isa_ext_strings[ISA_EXT_FPU64]);
+
+	  /* Same as above.  */
+	  t.isa.simd = ISA_EXT_NONE;
+	}
+    }
 
 
   /* 4.  ABI-ISA compatibility */
@@ -272,7 +414,7 @@ config_target_isa:
     {
       /* Base architecture can only be implied by -march,
 	 so we adjust that first if it is not constrained.  */
-      int fallback_arch = abi_default_cpu_arch (t.abi);
+      int fallback_arch = abi_default_cpu_arch (t.abi, NULL);
 
       if (t.cpu_arch == CPU_NATIVE)
 	warning (0, "your native CPU architecture (%qs) "
@@ -319,7 +461,7 @@ fatal:
   if (abi_tmp.base != t.abi.base || abi_tmp.ext != t.abi.ext)
     {
       /* This flag is only set in the GCC driver.  */
-      if (follow_multilib_list)
+      if (follow_multilib_list_p)
 	{
 
 	  /* Continue falling back until we find a feasible ABI type
@@ -360,7 +502,7 @@ fatal:
 fallback:
       t.abi = abi_tmp;
     }
-  else if (follow_multilib_list)
+  else if (follow_multilib_list_p)
     {
       if (!is_multilib_enabled (t.abi))
 	{
@@ -375,7 +517,7 @@ fallback:
 
 
   /* 5.  Target code model */
-  t.cmodel = constrained.cmodel ? opt_cmodel : CMODEL_NORMAL;
+  t.cmodel = constrained.cmodel ? target->cmodel : CMODEL_NORMAL;
 
   switch (t.cmodel)
     {
@@ -419,7 +561,7 @@ isa_default_abi (const struct loongarch_isa *isa)
 	  abi.base = ABI_BASE_LP64F;
 	break;
 
-      case ISA_EXT_NOFPU:
+      case ISA_EXT_NONE:
 	if (isa->base == ISA_BASE_LA64V100)
 	  abi.base = ABI_BASE_LP64S;
 	break;
@@ -459,7 +601,7 @@ isa_fpu_compat_p (const struct loongarch_isa *set1,
       case ISA_EXT_FPU32:
 	return set1->fpu == ISA_EXT_FPU32 || set1->fpu == ISA_EXT_FPU64;
 
-      case ISA_EXT_NOFPU:
+      case ISA_EXT_NONE:
 	return 1;
 
       default:
@@ -483,16 +625,22 @@ abi_compat_p (const struct loongarch_isa *isa, struct loongarch_abi abi)
 /* The behavior of this function should be consistent
    with config.gcc.  */
 static inline int
-abi_default_cpu_arch (struct loongarch_abi abi)
+abi_default_cpu_arch (struct loongarch_abi abi,
+		      struct loongarch_isa *isa)
 {
-  switch (abi.base)
-    {
-      case ABI_BASE_LP64D:
-      case ABI_BASE_LP64F:
-      case ABI_BASE_LP64S:
-	if (abi.ext == ABI_EXT_BASE)
+  static struct loongarch_isa tmp;
+  if (!isa)
+    isa = &tmp;
+
+  if (abi.ext == ABI_EXT_BASE)
+    switch (abi.base)
+      {
+	case ABI_BASE_LP64D:
+	case ABI_BASE_LP64F:
+	case ABI_BASE_LP64S:
+	  *isa = isa_required (abi);
 	  return CPU_LOONGARCH64;
-    }
+      }
   gcc_unreachable ();
 }
 
@@ -521,7 +669,7 @@ isa_str (const struct loongarch_isa *isa, char separator)
   APPEND_STRING (loongarch_isa_base_strings[isa->base])
   APPEND1 (separator)
 
-  if (isa->fpu == ISA_EXT_NOFPU)
+  if (isa->fpu == ISA_EXT_NONE)
     {
       APPEND_STRING ("no" OPTSTR_ISA_EXT_FPU)
     }
@@ -530,6 +678,18 @@ isa_str (const struct loongarch_isa *isa, char separator)
       APPEND_STRING (OPTSTR_ISA_EXT_FPU)
       APPEND_STRING (loongarch_isa_ext_strings[isa->fpu])
     }
+
+  switch (isa->simd)
+    {
+      case ISA_EXT_SIMD_LSX:
+      case ISA_EXT_SIMD_LASX:
+	APPEND1 (separator);
+	APPEND_STRING (loongarch_isa_ext_strings[isa->simd]);
+	break;
+
+      default:
+	gcc_assert (isa->simd == 0);
+    }
   APPEND1 ('\0')
 
   /* Add more here.  */
@@ -542,18 +702,12 @@ arch_str (const struct loongarch_target *target)
 {
   if (target->cpu_arch == CPU_NATIVE)
     {
-      if (target->cpu_native == CPU_NATIVE)
-	{
-	  /* Describe a native CPU with unknown PRID.  */
-	  const char* isa_string = isa_str (&target->isa, ',');
-	  APPEND_STRING ("PRID: 0x")
-	  APPEND_STRING (get_native_prid_str ())
-	  APPEND_STRING (", ISA features: ")
-	  APPEND_STRING (isa_string)
-	  APPEND1 ('\0')
-	}
-      else
-	APPEND_STRING (loongarch_cpu_strings[target->cpu_native]);
+      /* Describe a native CPU with unknown PRID.  */
+      const char* isa_string = isa_str (&target->isa, ',');
+      APPEND_STRING ("PRID: 0x")
+      APPEND_STRING (get_native_prid_str ())
+      APPEND_STRING (", ISA features: ")
+      APPEND_STRING (isa_string)
     }
   else
     APPEND_STRING (loongarch_cpu_strings[target->cpu_arch]);
@@ -594,3 +748,23 @@ multilib_enabled_abi_list ()
 
   return XOBFINISH (&msg_obstack, const char *);
 }
+
+/* option status feedback for "gcc --help=target -Q" */
+void
+loongarch_update_gcc_opt_status (struct loongarch_target *target,
+				 struct gcc_options *opts,
+				 struct gcc_options *opts_set)
+{
+  (void) opts_set;
+
+  /* status of -mabi */
+  opts->x_la_opt_abi_base = target->abi.base;
+
+  /* status of -march and -mtune */
+  opts->x_la_opt_cpu_arch = target->cpu_arch;
+  opts->x_la_opt_cpu_tune = target->cpu_tune;
+
+  /* status of -mfpu */
+  opts->x_la_opt_fpu = target->isa.fpu;
+  opts->x_la_opt_simd = target->isa.simd;
+}
diff --git a/gcc/config/loongarch/loongarch-opts.h b/gcc/config/loongarch/loongarch-opts.h
index b1ff54426e4..7a58dabdea8 100644
--- a/gcc/config/loongarch/loongarch-opts.h
+++ b/gcc/config/loongarch/loongarch-opts.h
@@ -21,24 +21,39 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef LOONGARCH_OPTS_H
 #define LOONGARCH_OPTS_H
 
+#include "loongarch-def.h"
 
 /* Target configuration */
 extern struct loongarch_target la_target;
 
-/* Switch masks */
-extern const int loongarch_switch_mask[];
-
-#include "loongarch-def.h"
+/* Flag status */
+struct loongarch_flags {
+    int flt; const char* flt_str;
+#define SX_FLAG_TYPE(x) ((x) < 0 ? -(x) : (x))
+    int sx[2];
+};
 
 #if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS) && !defined(IN_RTS)
+
+/* Initialize loongarch_target from separate option variables.  */
+void
+loongarch_init_target (struct loongarch_target *target,
+		       int cpu_arch, int cpu_tune, int fpu, int simd,
+		       int abi_base, int abi_ext, int cmodel);
+
+
 /* Handler for "-m" option combinations,
    shared by the driver and the compiler proper.  */
 void
 loongarch_config_target (struct loongarch_target *target,
-			 HOST_WIDE_INT opt_switches,
-			 int opt_arch, int opt_tune, int opt_fpu,
-			 int opt_abi_base, int opt_abi_ext,
-			 int opt_cmodel, int follow_multilib_list);
+			 struct loongarch_flags *flags,
+			 int follow_multilib_list_p);
+
+/* option status feedback for "gcc --help=target -Q" */
+void
+loongarch_update_gcc_opt_status (struct loongarch_target *target,
+				 struct gcc_options *opts,
+				 struct gcc_options *opts_set);
 #endif
 
 
@@ -50,11 +65,11 @@ loongarch_config_target (struct loongarch_target *target,
 #define TARGET_CMODEL_LARGE	    (la_target.cmodel == CMODEL_LARGE)
 #define TARGET_CMODEL_EXTREME	    (la_target.cmodel == CMODEL_EXTREME)
 
-#define TARGET_HARD_FLOAT	    (la_target.isa.fpu != ISA_EXT_NOFPU)
+#define TARGET_HARD_FLOAT	    (la_target.isa.fpu != ISA_EXT_NONE)
 #define TARGET_HARD_FLOAT_ABI	    (la_target.abi.base == ABI_BASE_LP64D \
 				     || la_target.abi.base == ABI_BASE_LP64F)
 
-#define TARGET_SOFT_FLOAT	  (la_target.isa.fpu == ISA_EXT_NOFPU)
+#define TARGET_SOFT_FLOAT	  (la_target.isa.fpu == ISA_EXT_NONE)
 #define TARGET_SOFT_FLOAT_ABI	  (la_target.abi.base == ABI_BASE_LP64S)
 #define TARGET_SINGLE_FLOAT	  (la_target.isa.fpu == ISA_EXT_FPU32)
 #define TARGET_SINGLE_FLOAT_ABI	  (la_target.abi.base == ABI_BASE_LP64F)
@@ -66,30 +81,16 @@ loongarch_config_target (struct loongarch_target *target,
 				   || la_target.abi.base == ABI_BASE_LP64F \
 				   || la_target.abi.base == ABI_BASE_LP64S)
 
-#define TARGET_ARCH_NATIVE	  (la_target.cpu_arch == CPU_NATIVE)
-#define LARCH_ACTUAL_ARCH	  (TARGET_ARCH_NATIVE \
-				   ? (la_target.cpu_native < N_ARCH_TYPES \
-				      ? (la_target.cpu_native) : (CPU_NATIVE)) \
-				      : (la_target.cpu_arch))
+#define ISA_HAS_LSX		  (la_target.isa.simd == ISA_EXT_SIMD_LSX \
+				   || la_target.isa.simd == ISA_EXT_SIMD_LASX)
+#define ISA_HAS_LASX		  (la_target.isa.simd == ISA_EXT_SIMD_LASX)
 
-#define TARGET_TUNE_NATIVE	(la_target.cpu_tune == CPU_NATIVE)
-#define LARCH_ACTUAL_TUNE		(TARGET_TUNE_NATIVE \
-				 ? (la_target.cpu_native < N_TUNE_TYPES \
-				    ? (la_target.cpu_native) : (CPU_NATIVE)) \
-				    : (la_target.cpu_tune))
 
-#define TARGET_ARCH_LOONGARCH64	  (LARCH_ACTUAL_ARCH == CPU_LOONGARCH64)
-#define TARGET_ARCH_LA464	  (LARCH_ACTUAL_ARCH == CPU_LA464)
-
-#define TARGET_TUNE_LOONGARCH64	  (LARCH_ACTUAL_TUNE == CPU_LOONGARCH64)
-#define TARGET_TUNE_LA464	  (LARCH_ACTUAL_TUNE == CPU_LA464)
+/* TARGET_ macros for use in *.md template conditionals */
+#define TARGET_uARCH_LA464	  (la_target.cpu_tune == CPU_LA464)
 
 /* Note: optimize_size may vary across functions,
    while -m[no]-memcpy imposes a global constraint.  */
 #define TARGET_DO_OPTIMIZE_BLOCK_MOVE_P  loongarch_do_optimize_block_move_p()
 
-#ifndef HAVE_AS_EXPLICIT_RELOCS
-#define HAVE_AS_EXPLICIT_RELOCS 0
-#endif
-
 #endif /* LOONGARCH_OPTS_H */
diff --git a/gcc/config/loongarch/loongarch-str.h b/gcc/config/loongarch/loongarch-str.h
index af2e82a321f..a3e0510493b 100644
--- a/gcc/config/loongarch/loongarch-str.h
+++ b/gcc/config/loongarch/loongarch-str.h
@@ -27,13 +27,14 @@ along with GCC; see the file COPYING3.  If not see
 #define OPTSTR_TUNE "tune"
 
 #define STR_CPU_NATIVE "native"
+#define STR_CPU_ABI_DEFAULT "abi-default"
 #define STR_CPU_LOONGARCH64 "loongarch64"
 #define STR_CPU_LA464 "la464"
 
 #define STR_ISA_BASE_LA64V100 "la64"
 
 #define OPTSTR_ISA_EXT_FPU "fpu"
-#define STR_ISA_EXT_NOFPU "none"
+#define STR_NONE "none"
 #define STR_ISA_EXT_FPU0 "0"
 #define STR_ISA_EXT_FPU32 "32"
 #define STR_ISA_EXT_FPU64 "64"
@@ -42,6 +43,10 @@ along with GCC; see the file COPYING3.  If not see
 #define OPTSTR_SINGLE_FLOAT "single-float"
 #define OPTSTR_DOUBLE_FLOAT "double-float"
 
+#define OPTSTR_ISA_EXT_SIMD "simd"
+#define STR_ISA_EXT_LSX "lsx"
+#define STR_ISA_EXT_LASX "lasx"
+
 #define OPTSTR_ABI_BASE "abi"
 #define STR_ABI_BASE_LP64D "lp64d"
 #define STR_ABI_BASE_LP64F "lp64f"
diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
index 86d58784113..4fefa2d8b15 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -2553,7 +2553,7 @@ loongarch_call_tls_get_addr (rtx sym, enum loongarch_symbol_type type, rtx v0)
 
   if (flag_plt)
     {
-      switch (la_opt_cmodel)
+      switch (la_target.cmodel)
 	{
 	case CMODEL_NORMAL:
 	  insn = emit_call_insn (gen_call_value_internal (v0,
@@ -2595,7 +2595,7 @@ loongarch_call_tls_get_addr (rtx sym, enum loongarch_symbol_type type, rtx v0)
     {
       rtx dest = gen_reg_rtx (Pmode);
 
-      switch (la_opt_cmodel)
+      switch (la_target.cmodel)
 	{
 	case CMODEL_NORMAL:
 	case CMODEL_MEDIUM:
@@ -6007,8 +6007,8 @@ loongarch_adjust_cost (rtx_insn *, int dep_type, rtx_insn *, int cost,
 static int
 loongarch_issue_rate (void)
 {
-  if ((unsigned long) LARCH_ACTUAL_TUNE < N_TUNE_TYPES)
-    return loongarch_cpu_issue_rate[LARCH_ACTUAL_TUNE];
+  if ((unsigned long) la_target.cpu_tune < N_TUNE_TYPES)
+    return loongarch_cpu_issue_rate[la_target.cpu_tune];
   else
     return 1;
 }
@@ -6019,8 +6019,8 @@ loongarch_issue_rate (void)
 static int
 loongarch_multipass_dfa_lookahead (void)
 {
-  if ((unsigned long) LARCH_ACTUAL_TUNE < N_ARCH_TYPES)
-    return loongarch_cpu_multipass_dfa_lookahead[LARCH_ACTUAL_TUNE];
+  if ((unsigned long) la_target.cpu_tune < N_ARCH_TYPES)
+    return loongarch_cpu_multipass_dfa_lookahead[la_target.cpu_tune];
   else
     return 0;
 }
@@ -6197,17 +6197,54 @@ loongarch_init_machine_status (void)
 }
 
 static void
-loongarch_option_override_internal (struct gcc_options *opts)
+loongarch_cpu_option_override (struct loongarch_target *target,
+			       struct gcc_options *opts,
+			       struct gcc_options *opts_set)
+{
+  /* alignments */
+  if (opts->x_flag_align_functions && !opts->x_str_align_functions)
+    opts->x_str_align_functions
+      = loongarch_cpu_align[target->cpu_tune].function;
+
+  if (opts->x_flag_align_labels && !opts->x_str_align_labels)
+    opts->x_str_align_labels = loongarch_cpu_align[target->cpu_tune].label;
+
+  /* Set up parameters to be used in prefetching algorithm.  */
+  int simultaneous_prefetches
+    = loongarch_cpu_cache[target->cpu_tune].simultaneous_prefetches;
+
+  SET_OPTION_IF_UNSET (opts, opts_set, param_simultaneous_prefetches,
+		       simultaneous_prefetches);
+
+  SET_OPTION_IF_UNSET (opts, opts_set, param_l1_cache_line_size,
+		       loongarch_cpu_cache[target->cpu_tune].l1d_line_size);
+
+  SET_OPTION_IF_UNSET (opts, opts_set, param_l1_cache_size,
+		       loongarch_cpu_cache[target->cpu_tune].l1d_size);
+
+  SET_OPTION_IF_UNSET (opts, opts_set, param_l2_cache_size,
+		       loongarch_cpu_cache[target->cpu_tune].l2d_size);
+}
+
+static void
+loongarch_option_override_internal (struct gcc_options *opts,
+				    struct gcc_options *opts_set)
 {
   int i, regno, mode;
 
   if (flag_pic)
     g_switch_value = 0;
 
+  loongarch_init_target (&la_target,
+			 la_opt_cpu_arch, la_opt_cpu_tune, la_opt_fpu,
+			 la_opt_simd, la_opt_abi_base, la_opt_abi_ext,
+			 la_opt_cmodel);
+
   /* Handle target-specific options: compute defaults/conflicts etc.  */
-  loongarch_config_target (&la_target, la_opt_switches,
-			   la_opt_cpu_arch, la_opt_cpu_tune, la_opt_fpu,
-			   la_opt_abi_base, la_opt_abi_ext, la_opt_cmodel, 0);
+  loongarch_config_target (&la_target, NULL, 0);
+
+  loongarch_update_gcc_opt_status (&la_target, opts, opts_set);
+  loongarch_cpu_option_override (&la_target, opts, opts_set);
 
   if (TARGET_ABI_LP64)
     flag_pcc_struct_return = 0;
@@ -6216,33 +6253,13 @@ loongarch_option_override_internal (struct gcc_options *opts)
   if (optimize_size)
     loongarch_cost = &loongarch_rtx_cost_optimize_size;
   else
-    loongarch_cost = &loongarch_cpu_rtx_cost_data[LARCH_ACTUAL_TUNE];
+    loongarch_cost = &loongarch_cpu_rtx_cost_data[la_target.cpu_tune];
 
   /* If the user hasn't specified a branch cost, use the processor's
      default.  */
   if (loongarch_branch_cost == 0)
     loongarch_branch_cost = loongarch_cost->branch_cost;
 
-  /* Set up parameters to be used in prefetching algorithm.  */
-  int simultaneous_prefetches
-    = loongarch_cpu_cache[LARCH_ACTUAL_TUNE].simultaneous_prefetches;
-
-  SET_OPTION_IF_UNSET (opts, &global_options_set,
-		       param_simultaneous_prefetches,
-		       simultaneous_prefetches);
-
-  SET_OPTION_IF_UNSET (opts, &global_options_set,
-		       param_l1_cache_line_size,
-		       loongarch_cpu_cache[LARCH_ACTUAL_TUNE].l1d_line_size);
-
-  SET_OPTION_IF_UNSET (opts, &global_options_set,
-		       param_l1_cache_size,
-		       loongarch_cpu_cache[LARCH_ACTUAL_TUNE].l1d_size);
-
-  SET_OPTION_IF_UNSET (opts, &global_options_set,
-		       param_l2_cache_size,
-		       loongarch_cpu_cache[LARCH_ACTUAL_TUNE].l2d_size);
-
 
   /* Enable sw prefetching at -O3 and higher.  */
   if (opts->x_flag_prefetch_loop_arrays < 0
@@ -6250,12 +6267,6 @@ loongarch_option_override_internal (struct gcc_options *opts)
       && !opts->x_optimize_size)
     opts->x_flag_prefetch_loop_arrays = 1;
 
-  if (opts->x_flag_align_functions && !opts->x_str_align_functions)
-    opts->x_str_align_functions = loongarch_cpu_align[LARCH_ACTUAL_TUNE].function;
-
-  if (opts->x_flag_align_labels && !opts->x_str_align_labels)
-    opts->x_str_align_labels = loongarch_cpu_align[LARCH_ACTUAL_TUNE].label;
-
   if (TARGET_DIRECT_EXTERN_ACCESS && flag_shlib)
     error ("%qs cannot be used for compiling a shared library",
 	   "-mdirect-extern-access");
@@ -6325,7 +6336,7 @@ loongarch_option_override_internal (struct gcc_options *opts)
 static void
 loongarch_option_override (void)
 {
-  loongarch_option_override_internal (&global_options);
+  loongarch_option_override_internal (&global_options, &global_options_set);
 }
 
 /* Implement TARGET_CONDITIONAL_REGISTER_USAGE.  */
diff --git a/gcc/config/loongarch/loongarch.opt b/gcc/config/loongarch/loongarch.opt
index 68018ade73f..8be2b0bcb4f 100644
--- a/gcc/config/loongarch/loongarch.opt
+++ b/gcc/config/loongarch/loongarch.opt
@@ -24,22 +24,12 @@
 ; <http://www.gnu.org/licenses/>.
 ;
 
-; Variables (macros) that should be exported by loongarch.opt:
-;   la_opt_switches,
-;   la_opt_abi_base, la_opt_abi_ext,
-;   la_opt_cpu_arch, la_opt_cpu_tune,
-;   la_opt_fpu,
-;   la_cmodel.
-
 HeaderInclude
 config/loongarch/loongarch-opts.h
 
 HeaderInclude
 config/loongarch/loongarch-str.h
 
-Variable
-HOST_WIDE_INT la_opt_switches = 0
-
 ; ISA related options
 ;; Base ISA
 Enum
@@ -49,14 +39,13 @@ Basic ISAs of LoongArch:
 EnumValue
 Enum(isa_base) String(la64) Value(ISA_BASE_LA64V100)
 
-
 ;; ISA extensions / adjustments
 Enum
 Name(isa_ext_fpu) Type(int)
 FPU types of LoongArch:
 
 EnumValue
-Enum(isa_ext_fpu) String(none) Value(ISA_EXT_NOFPU)
+Enum(isa_ext_fpu) String(none) Value(ISA_EXT_NONE)
 
 EnumValue
 Enum(isa_ext_fpu) String(32) Value(ISA_EXT_FPU32)
@@ -65,24 +54,48 @@ EnumValue
 Enum(isa_ext_fpu) String(64) Value(ISA_EXT_FPU64)
 
 mfpu=
-Target RejectNegative Joined ToLower Enum(isa_ext_fpu) Var(la_opt_fpu) Init(M_OPTION_NOT_SEEN)
+Target RejectNegative Joined ToLower Enum(isa_ext_fpu) Var(la_opt_fpu) Init(M_OPT_UNSET)
 -mfpu=FPU	Generate code for the given FPU.
 
 mfpu=0
 Target RejectNegative Alias(mfpu=,none)
 
 msoft-float
-Target Driver RejectNegative Var(la_opt_switches) Mask(FORCE_SOFTF) Negative(msingle-float)
+Target Driver Defer Var(la_deferred_options) RejectNegative Negative(msingle-float)
 Prevent the use of all hardware floating-point instructions.
 
 msingle-float
-Target Driver RejectNegative Var(la_opt_switches) Mask(FORCE_F32) Negative(mdouble-float)
+Target Driver Defer Var(la_deferred_options) RejectNegative Negative(mdouble-float)
 Restrict the use of hardware floating-point instructions to 32-bit operations.
 
 mdouble-float
-Target Driver RejectNegative Var(la_opt_switches) Mask(FORCE_F64) Negative(msoft-float)
+Target Driver Defer Var(la_deferred_options) RejectNegative Negative(msoft-float)
 Allow hardware floating-point instructions to cover both 32-bit and 64-bit operations.
 
+Enum
+Name(isa_ext_simd) Type(int)
+SIMD extension levels of LoongArch:
+
+EnumValue
+Enum(isa_ext_simd) String(none) Value(ISA_EXT_NONE)
+
+EnumValue
+Enum(isa_ext_simd) String(lsx) Value(ISA_EXT_SIMD_LSX)
+
+EnumValue
+Enum(isa_ext_simd) String(lasx) Value(ISA_EXT_SIMD_LASX)
+
+msimd=
+Target RejectNegative Joined ToLower Enum(isa_ext_simd) Var(la_opt_simd) Init(M_OPT_UNSET)
+-msimd=SIMD	Generate code for the given SIMD extension.
+
+mlsx
+Target Driver Defer Var(la_deferred_options)
+Enable LoongArch SIMD Extension (LSX, 128-bit).
+
+mlasx
+Target Driver Defer Var(la_deferred_options)
+Enable LoongArch Advanced SIMD Extension (LASX, 256-bit).
 
 ;; Base target models (implies ISA & tune parameters)
 Enum
@@ -92,6 +105,9 @@ LoongArch CPU types:
 EnumValue
 Enum(cpu_type) String(native) Value(CPU_NATIVE)
 
+EnumValue
+Enum(cpu_type) String(abi-default) Value(CPU_ABI_DEFAULT)
+
 EnumValue
 Enum(cpu_type) String(loongarch64) Value(CPU_LOONGARCH64)
 
@@ -99,11 +115,11 @@ EnumValue
 Enum(cpu_type) String(la464) Value(CPU_LA464)
 
 march=
-Target RejectNegative Joined Enum(cpu_type) Var(la_opt_cpu_arch) Init(M_OPTION_NOT_SEEN)
+Target RejectNegative Joined Enum(cpu_type) Var(la_opt_cpu_arch) Init(M_OPT_UNSET)
 -march=PROCESSOR	Generate code for the given PROCESSOR ISA.
 
 mtune=
-Target RejectNegative Joined Enum(cpu_type) Var(la_opt_cpu_tune) Init(M_OPTION_NOT_SEEN)
+Target RejectNegative Joined Enum(cpu_type) Var(la_opt_cpu_tune) Init(M_OPT_UNSET)
 -mtune=PROCESSOR	Generate optimized code for PROCESSOR.
 
 
@@ -125,13 +141,13 @@ EnumValue
 Enum(abi_base) String(lp64s) Value(ABI_BASE_LP64S)
 
 mabi=
-Target RejectNegative Joined ToLower Enum(abi_base) Var(la_opt_abi_base) Init(M_OPTION_NOT_SEEN)
+Target RejectNegative Joined ToLower Enum(abi_base) Var(la_opt_abi_base) Init(M_OPT_UNSET)
 -mabi=BASEABI	Generate code that conforms to the given BASEABI.
 
+
 ;; ABI Extension
 Variable
-int la_opt_abi_ext = M_OPTION_NOT_SEEN
-
+int la_opt_abi_ext = M_OPT_UNSET
 
 mbranch-cost=
 Target RejectNegative Joined UInteger Var(loongarch_branch_cost)
@@ -189,7 +205,7 @@ EnumValue
 Enum(cmodel) String(extreme) Value(CMODEL_EXTREME)
 
 mcmodel=
-Target RejectNegative Joined Enum(cmodel) Var(la_opt_cmodel) Init(CMODEL_NORMAL)
+Target RejectNegative Joined Enum(cmodel) Var(la_opt_cmodel) Init(M_OPT_UNSET)
 Specify the code model.
 
 mdirect-extern-access
diff --git a/gcc/config/loongarch/t-linux b/gcc/config/loongarch/t-linux
index e40da179203..9997596d722 100644
--- a/gcc/config/loongarch/t-linux
+++ b/gcc/config/loongarch/t-linux
@@ -23,7 +23,37 @@ MULTILIB_DIRNAMES = base/lp64d base/lp64f base/lp64s
 # The GCC driver always gets all abi-related options on the command line.
 # (see loongarch-driver.c:driver_get_normalized_m_opts)
 comma=,
-MULTILIB_REQUIRED = $(subst $(comma), ,$(TM_MULTILIB_CONFIG))
+MULTILIB_REQUIRED = $(foreach mlib,$(subst $(comma), ,$(TM_MULTILIB_CONFIG)),\
+	$(firstword $(subst /, ,$(mlib))))
+
+SPECS = specs.install
+
+# temporary self_spec when building libraries (e.g. libgcc)
+gen_mlib_spec = $(if $(word 2,$1),\
+	%{$(firstword $1):$(patsubst %,-%,$(wordlist 2,$(words $1),$1))})
+
+# clean up the result of DRIVER_SELF_SPEC to avoid conflict
+lib_build_self_spec  = %<march=* %<mtune=* %<mcmodel=* %<mfpu=* %<msimd=*
+
+# append user-specified build options from --with-multilib-list
+lib_build_self_spec += $(foreach mlib,\
+	$(subst $(comma), ,$(TM_MULTILIB_CONFIG)),\
+	$(call gen_mlib_spec,$(subst /, ,$(mlib))))
+
+specs: specs.install
+	sed '/^*self_spec:$$/{ n;s/^$$/$(lib_build_self_spec)/g; }' $< > $@
+
+# Do some preparation before regression tests:
+# remove lib-build-specs / make symlinks for the toplevel multilib variant
+
+LA_DEFAULT_MULTISUBDIR = $(shell $(GCC_FOR_TARGET) --print-multi-dir)
+.PHONY: remove-lib-specs
+check check-host check-target $(CHECK_TARGETS) $(lang_checks): remove-lib-specs
+remove-lib-specs:
+	-mv -f specs.install specs 2>/dev/null
+	-mv $(LA_DEFAULT_MULTISUBDIR)/* ./
+	-mkdir -p ../$(target_noncanonical)/`dirname $(LA_DEFAULT_MULTISUBDIR)`
+	-$(LN_S) .. ../$(target_noncanonical)/$(LA_DEFAULT_MULTISUBDIR)
 
 # Multiarch
 ifneq ($(call if_multiarch,yes),yes)
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index e099cd0b568..05a626280b7 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -1326,12 +1326,32 @@ profile.  The union of these options is considered when specifying both
 @end multitable
 
 @item loongarch*-*-*
-@var{list} is a comma-separated list of the following ABI identifiers:
-@code{lp64d[/base]} @code{lp64f[/base]} @code{lp64d[/base]}, where the
-@code{/base} suffix may be omitted, to enable their respective run-time
-libraries.  If @var{list} is empty or @code{default},
-or if @option{--with-multilib-list} is not specified, then the default ABI
-as specified by @option{--with-abi} or implied by @option{--target} is selected.
+@var{list} is a comma-separated list, with each of the element starting with
+the following ABI identifiers: @code{lp64d[/base]} @code{lp64f[/base]}
+@code{lp64d[/base]} (the @code{/base} suffix may be omitted)
+to enable their respective run-time libraries.
+
+A suffix @code{[/ARCH][/OPTION]...]} may follow immediately after the ABI
+identifier to customize the compiler options for building the given set of
+libraries.  @code{ARCH} denotes the architecture name recognized by the
+@code{-march=ARCH} compiler option, which acts as a basic target ISA
+configuration that can be adjusted using the subsequent @code{OPTION}
+suffixes, where each @code{OPTION} is a compiler option itself.
+
+If none of such suffix is present, the configured value of
+@option{--with-multilib-default} can be used as a common default suffix
+for all library ABI variants.  Otherwise, the default build option
+@code{-march=abi-default} is applied when building the variants without
+a suffix.
+
+As a special case, @code{fixed} may be used in the position of @code{ARCH},
+which means use the architecture configured with @option{--with-arch=ARCH},
+or its default value (e.g. @code{loongarch64} for @code{loongarch64-*}
+targets).
+
+If @var{list} is empty or @code{default}, or if @option{--with-multilib-list}
+is not specified, then the default ABI as specified by @option{--with-abi} or
+implied by @option{--target}.
 
 @item riscv*-*-*
 @var{list} is a single ABI name.  The target architecture must be either
@@ -1382,6 +1402,19 @@ If @option{--with-multilib-list} is not given, then only 32-bit and
 64-bit run-time libraries will be enabled.
 @end table
 
+@item --with-multilib-default
+On LoongArch targets, set the default build options for enabled multilibs
+without build options appended to their corresponding
+@option{--with-multilib-list} items.  The format of this value is
+@code{[/ARCH][/OPTION]...}, where @code{ARCH} is an architecture name
+recognized by @code{-march=ARCH} compiler option, and @code{OPTION}
+can be filled with a compiler option itself.
+
+Multiple @code{OPTION}s may appear consecutively while @code{ARCH} may only
+appear in the beginning or be omitted (which means @code{-march=abi-default}
+is applied when building the libraries).
+
+
 @item --with-multilib-generator=@var{config}
 Specify what multilibs to build.  @var{config} is a semicolon separated list of
 values, possibly consisting of a single value.  Currently only implemented
@@ -1531,6 +1564,7 @@ x86-64, PowerPC, and SPARC@.
 @itemx --with-abi=@var{abi}
 @itemx --with-fpu=@var{type}
 @itemx --with-float=@var{type}
+@itemx --with-simd=@var{type}
 These configure options provide default values for the @option{-mschedule=},
 @option{-march=}, @option{-mtune=}, @option{-mabi=}, and @option{-mfpu=}
 options and for @option{-mhard-float} or @option{-msoft-float}.  As with
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 10f3466052f..2f01baff3e7 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1028,7 +1028,8 @@ Objective-C and Objective-C++ Dialects}.
 
 @emph{LoongArch Options}
 @gccoptlist{-march=@var{cpu-type}  -mtune=@var{cpu-type} -mabi=@var{base-abi-type}
--mfpu=@var{fpu-type} -msoft-float -msingle-float -mdouble-float
+-mfpu=@var{fpu-type} -msimd=@var{simd-type}
+-msoft-float -msingle-float -mdouble-float -mlsx -mno-lsx -mlasx -mno-lasx
 -mbranch-cost=@var{n}  -mcheck-zero-division -mno-check-zero-division
 -mcond-move-int  -mno-cond-move-int
 -mcond-move-float  -mno-cond-move-float
@@ -25970,6 +25971,21 @@ operations.
 Prevent the use of hardware floating-point instructions.
 @end table
 
+@opindex msimd
+@item -msimd=@var{simd-type}
+Enable generation of LoongArch SIMD instructions for vectorization
+and via builtin functions.  The value can be one of:
+@table @samp
+@item lasx
+Enable generating instructions from the 256-bit LoongArch Advanced
+SIMD Extension (LASX) and the 128-bit LoongArch SIMD Extension (LSX).
+@item lsx
+Enable generating instructions from the 128-bit LoongArch SIMD
+Extension (LSX).
+@item none
+No LoongArch SIMD instruction may be generated.
+@end table
+
 @opindex msoft-float
 @item -msoft-float
 Force @option{-mfpu=none} and prevents the use of floating-point
@@ -25988,6 +26004,19 @@ Force @option{-mfpu=64} and allow the use of 32/64-bit floating-point
 registers for parameter passing.  This option may change the target
 ABI.
 
+@opindex ml[a]sx
+@item -mlasx
+@itemx -mno-lasx
+@item -mlsx
+@itemx -mno-lsx
+Incrementally adjust the scope of the SIMD extensions (none / LSX / LASX)
+that can be used by the compiler for code generation.  Enabling LASX with
+@option{mlasx} automatically enables LSX, and diabling LSX with @option{mno-lsx}
+automatically disables LASX.  These driver-only options act upon the final
+@option{msimd} configuration state and make incremental chagnes in the order
+they appear on the GCC driver's command line, deriving the final / canonicalized
+@option{msimd} option that is passed to the compiler proper.
+
 @opindex mbranch-cost
 @item -mbranch-cost=@var{n}
 Set the cost of branches to roughly @var{n} instructions.
@@ -26088,6 +26117,7 @@ kernels, executables linked with @option{-static} or @option{-static-pie}.
 @option{-fpic}.
 @end table
 
+
 @node M32C Options
 @subsection M32C Options
 @cindex M32C options
-- 
2.36.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 2/4] LoongArch: define preprocessing macros "__loongarch_{arch,tune}"
  2023-08-30  1:58 [PATCH 0/4] LoongArch: target configuration interface update Yang Yujie
  2023-08-30  1:58 ` [PATCH v2 1/4] LoongArch: improved target configuration interface Yang Yujie
@ 2023-08-30  1:58 ` Yang Yujie
  2023-08-30  1:58 ` [PATCH v2 3/4] LoongArch: add new configure option --with-strict-align-lib Yang Yujie
  2023-08-30  1:58 ` [PATCH v2 4/4] LoongArch: support loongarch*-elf target Yang Yujie
  3 siblings, 0 replies; 14+ messages in thread
From: Yang Yujie @ 2023-08-30  1:58 UTC (permalink / raw)
  To: gcc-patches; +Cc: xuchenghua, chenglulu, panchenghui, xry111, Yang Yujie

These are exported according to the LoongArch Toolchain Conventions[1]
as a replacement of the obsolete "_LOONGARCH_{ARCH,TUNE}" macros,
which are expanded to strings representing the actual architecture
and microarchitecture of the target.

[1] currently relased at https://github.com/loongson/LoongArch-Documentation
    /blob/main/docs/LoongArch-toolchain-conventions-EN.adoc

gcc/ChangeLog:

	* config/loongarch/loongarch-c.cc: Export macros
	"__loongarch_{arch,tune}" in the preprocessor.
---
 gcc/config/loongarch/loongarch-c.cc | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gcc/config/loongarch/loongarch-c.cc b/gcc/config/loongarch/loongarch-c.cc
index 7e3b57ff9b1..ec047e3822a 100644
--- a/gcc/config/loongarch/loongarch-c.cc
+++ b/gcc/config/loongarch/loongarch-c.cc
@@ -64,6 +64,9 @@ loongarch_cpu_cpp_builtins (cpp_reader *pfile)
   LARCH_CPP_SET_PROCESSOR ("_LOONGARCH_ARCH", la_target.cpu_arch);
   LARCH_CPP_SET_PROCESSOR ("_LOONGARCH_TUNE", la_target.cpu_tune);
 
+  LARCH_CPP_SET_PROCESSOR ("__loongarch_arch", la_target.cpu_arch);
+  LARCH_CPP_SET_PROCESSOR ("__loongarch_tune", la_target.cpu_tune);
+
   /* Base architecture / ABI.  */
   if (TARGET_64BIT)
     {
-- 
2.36.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 3/4] LoongArch: add new configure option --with-strict-align-lib
  2023-08-30  1:58 [PATCH 0/4] LoongArch: target configuration interface update Yang Yujie
  2023-08-30  1:58 ` [PATCH v2 1/4] LoongArch: improved target configuration interface Yang Yujie
  2023-08-30  1:58 ` [PATCH v2 2/4] LoongArch: define preprocessing macros "__loongarch_{arch,tune}" Yang Yujie
@ 2023-08-30  1:58 ` Yang Yujie
  2023-08-30  5:25   ` Xi Ruoyao
  2023-08-30  1:58 ` [PATCH v2 4/4] LoongArch: support loongarch*-elf target Yang Yujie
  3 siblings, 1 reply; 14+ messages in thread
From: Yang Yujie @ 2023-08-30  1:58 UTC (permalink / raw)
  To: gcc-patches; +Cc: xuchenghua, chenglulu, panchenghui, xry111, Yang Yujie

LoongArch processors may not support memory accesses without natural
alignments.  Building libraries with -mstrict-align may help with
toolchain binary compatiblity and performance on these implementations
(e.g. Loongson 2K1000LA).

No significant performance degredation is observed on current mainstream
LoongArch processors when the option is enabled.

gcc/ChangeLog:

	* config.gcc: use -mstrict-align for building libraries
	if --with-strict-align-lib is given.
---
 gcc/config.gcc | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 4fae672a3b7..ed70fa63268 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -4892,7 +4892,7 @@ case "${target}" in
 		;;
 
 	loongarch*-*)
-		supported_defaults="abi arch tune fpu simd multilib-default"
+		supported_defaults="abi arch tune fpu simd multilib-default strict-align-lib"
 
 		# Local variables
 		unset \
@@ -5089,6 +5089,17 @@ case "${target}" in
 			;;
 		esac
 
+		# Build libraries with -mstrict-align if --with-strict-align-lib is given.
+		case ${with_strict_align_lib} in
+		yes) strict_align_opt="/mstrict-align" ;;
+		""|no)  ;;
+		*)
+			echo "Unknown option: --with-strict-align-lib=${with_strict_align_lib}" 1>&2
+			exit 1
+			;;
+		esac
+
+
 		# Handle --with-multilib-default
 		if echo "${with_multilib_default}" \
 		| grep -E -e '[[:space:]]' -e '//' -e '/$' -e '^/' > /dev/null 2>&1; then
@@ -5250,6 +5261,9 @@ case "${target}" in
 					;;
 			esac
 
+			# Use mstrict-align for building libraries if --with-strict-align-lib is given.
+			loongarch_multilib_list_make="${loongarch_multilib_list_make}${strict_align_opt}"
+
 			# Check for repeated configuration of the same multilib variant.
 			if echo "${elem_abi_base}/${elem_abi_ext}" \
 			 | grep -E "^(${all_abis%|})$" >/dev/null 2>&1; then
-- 
2.36.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2 4/4] LoongArch: support loongarch*-elf target
  2023-08-30  1:58 [PATCH 0/4] LoongArch: target configuration interface update Yang Yujie
                   ` (2 preceding siblings ...)
  2023-08-30  1:58 ` [PATCH v2 3/4] LoongArch: add new configure option --with-strict-align-lib Yang Yujie
@ 2023-08-30  1:58 ` Yang Yujie
  3 siblings, 0 replies; 14+ messages in thread
From: Yang Yujie @ 2023-08-30  1:58 UTC (permalink / raw)
  To: gcc-patches; +Cc: xuchenghua, chenglulu, panchenghui, xry111, Yang Yujie

gcc/ChangeLog:

	* config.gcc: add loongarch*-elf target.
	* config/loongarch/elf.h: New file.
	Link against newlib by default.

libgcc/ChangeLog:

	* config.host: add loongarch*-elf target.
---
 gcc/config.gcc             | 15 ++++++++++-
 gcc/config/loongarch/elf.h | 52 ++++++++++++++++++++++++++++++++++++++
 libgcc/config.host         |  9 +++++--
 3 files changed, 73 insertions(+), 3 deletions(-)
 create mode 100644 gcc/config/loongarch/elf.h

diff --git a/gcc/config.gcc b/gcc/config.gcc
index ed70fa63268..b77e1fd5278 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -2491,6 +2491,18 @@ loongarch*-*-linux*)
 	gcc_cv_initfini_array=yes
 	;;
 
+loongarch*-*-elf*)
+	tm_file="elfos.h newlib-stdint.h ${tm_file}"
+	tm_file="${tm_file} loongarch/elf.h loongarch/linux.h"
+	tmake_file="${tmake_file} loongarch/t-linux"
+	gnu_ld=yes
+	gas=yes
+
+	# For .init_array support.  The configure script cannot always
+	# automatically detect that GAS supports it, yet we require it.
+	gcc_cv_initfini_array=yes
+	;;
+
 mips*-*-netbsd*)			# NetBSD/mips, either endian.
 	target_cpu_default="MASK_ABICALLS"
 	tm_file="elfos.h ${tm_file} mips/elf.h ${nbsd_tm_file} mips/netbsd.h"
@@ -4932,8 +4944,9 @@ case "${target}" in
 		esac
 
 		case ${target} in
-		  *-linux-gnu*)  triplet_os="linux-gnu";;
+		  *-linux-gnu*) triplet_os="linux-gnu";;
 		  *-linux-musl*) triplet_os="linux-musl";;
+		  *-elf*) triplet_os="elf";;
 		  *)
 			  echo "Unsupported target ${target}." 1>&2
 			  exit 1
diff --git a/gcc/config/loongarch/elf.h b/gcc/config/loongarch/elf.h
new file mode 100644
index 00000000000..6f84222e4e1
--- /dev/null
+++ b/gcc/config/loongarch/elf.h
@@ -0,0 +1,52 @@
+/* Definitions for LoongArch ELF-based systems.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+/* Define the size of the wide character type.  */
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "int"
+
+#undef WCHAR_TYPE_SIZE
+#define WCHAR_TYPE_SIZE 32
+
+
+/* GNU-specific SPEC definitions.  */
+#define GNU_USER_LINK_EMULATION "elf" ABI_GRLEN_SPEC "loongarch"
+
+#undef GNU_USER_TARGET_LINK_SPEC
+#define GNU_USER_TARGET_LINK_SPEC \
+  "%{shared} -m " GNU_USER_LINK_EMULATION
+
+
+/* Link against Newlib libraries, because the ELF backend assumes Newlib.
+   Handle the circular dependence between libc and libgloss.  */
+#undef  LIB_SPEC
+#define LIB_SPEC "--start-group -lc %{!specs=nosys.specs:-lgloss} --end-group"
+
+#undef LINK_SPEC
+#define LINK_SPEC GNU_USER_TARGET_LINK_SPEC
+
+#undef  STARTFILE_SPEC
+#define STARTFILE_SPEC "crt0%O%s crtbegin%O%s"
+
+#undef  ENDFILE_SPEC
+#define ENDFILE_SPEC "crtend%O%s"
+
+#undef SUBTARGET_CC1_SPEC
+#define SUBTARGET_CC1_SPEC "%{profile:-p}"
+
diff --git a/libgcc/config.host b/libgcc/config.host
index c94d69d84b7..6a112a07b14 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -136,7 +136,7 @@ hppa*-*-*)
 lm32*-*-*)
 	cpu_type=lm32
 	;;
-loongarch*-*-*)
+loongarch*-*)
 	cpu_type=loongarch
 	tmake_file="loongarch/t-loongarch"
 	if test "${libgcc_cv_loongarch_hard_float}" = yes; then
@@ -944,7 +944,7 @@ lm32-*-uclinux*)
         extra_parts="$extra_parts crtbegin.o crtendS.o crtbeginT.o"
         tmake_file="lm32/t-lm32 lm32/t-uclinux t-libgcc-pic t-softfp-sfdf t-softfp"
 	;;
-loongarch*-*-linux*)
+loongarch*-linux*)
 	extra_parts="$extra_parts crtfastmath.o"
 	tmake_file="${tmake_file} t-crtfm loongarch/t-crtstuff"
 	case ${host} in
@@ -954,6 +954,11 @@ loongarch*-*-linux*)
 	esac
 	md_unwind_header=loongarch/linux-unwind.h
 	;;
+loongarch*-elf*)
+	extra_parts="$extra_parts crtfastmath.o"
+	tmake_file="${tmake_file} t-crtfm loongarch/t-crtstuff"
+	tmake_file="${tmake_file} t-slibgcc-libgcc"
+	;;
 m32r-*-elf*)
 	tmake_file="$tmake_file m32r/t-m32r t-fdpbit"
 	extra_parts="$extra_parts crtinit.o crtfini.o"
-- 
2.36.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 3/4] LoongArch: add new configure option --with-strict-align-lib
  2023-08-30  1:58 ` [PATCH v2 3/4] LoongArch: add new configure option --with-strict-align-lib Yang Yujie
@ 2023-08-30  5:25   ` Xi Ruoyao
  2023-08-30  6:51     ` Yujie Yang
  0 siblings, 1 reply; 14+ messages in thread
From: Xi Ruoyao @ 2023-08-30  5:25 UTC (permalink / raw)
  To: Yang Yujie, gcc-patches; +Cc: xuchenghua, chenglulu, panchenghui

On Wed, 2023-08-30 at 09:58 +0800, Yang Yujie wrote:
> LoongArch processors may not support memory accesses without natural
> alignments.  Building libraries with -mstrict-align may help with
> toolchain binary compatiblity and performance on these implementations
> (e.g. Loongson 2K1000LA).
> 
> No significant performance degredation is observed on current mainstream
> LoongArch processors when the option is enabled.
> 
> gcc/ChangeLog:
> 
>         * config.gcc: use -mstrict-align for building libraries
>         if --with-strict-align-lib is given.

Isn't this equivalent to --with-default-multilib=mno-strict-align now?

And I still believe the easiest way for 2K1000LA is adding -march=la264
support so the user can simply configure with --with-arch=la264.

> ---
>  gcc/config.gcc | 16 +++++++++++++++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/gcc/config.gcc b/gcc/config.gcc
> index 4fae672a3b7..ed70fa63268 100644
> --- a/gcc/config.gcc
> +++ b/gcc/config.gcc
> @@ -4892,7 +4892,7 @@ case "${target}" in
>                 ;;
>  
>         loongarch*-*)
> -               supported_defaults="abi arch tune fpu simd multilib-
> default"
> +               supported_defaults="abi arch tune fpu simd multilib-
> default strict-align-lib"
>  
>                 # Local variables
>                 unset \
> @@ -5089,6 +5089,17 @@ case "${target}" in
>                         ;;
>                 esac
>  
> +               # Build libraries with -mstrict-align if --with-
> strict-align-lib is given.
> +               case ${with_strict_align_lib} in
> +               yes) strict_align_opt="/mstrict-align" ;;
> +               ""|no)  ;;
> +               *)
> +                       echo "Unknown option: --with-strict-align-
> lib=${with_strict_align_lib}" 1>&2
> +                       exit 1
> +                       ;;
> +               esac
> +
> +
>                 # Handle --with-multilib-default
>                 if echo "${with_multilib_default}" \
>                 | grep -E -e '[[:space:]]' -e '//' -e '/$' -e '^/' >
> /dev/null 2>&1; then
> @@ -5250,6 +5261,9 @@ case "${target}" in
>                                         ;;
>                         esac
>  
> +                       # Use mstrict-align for building libraries if
> --with-strict-align-lib is given.
> +                       loongarch_multilib_list_make="${loongarch_mult
> ilib_list_make}${strict_align_opt}"
> +
>                         # Check for repeated configuration of the same
> multilib variant.
>                         if echo "${elem_abi_base}/${elem_abi_ext}" \
>                          | grep -E "^(${all_abis%|})$" >/dev/null
> 2>&1; then

-- 
Xi Ruoyao <xry111@xry111.site>
School of Aerospace Science and Technology, Xidian University

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 3/4] LoongArch: add new configure option --with-strict-align-lib
  2023-08-30  5:25   ` Xi Ruoyao
@ 2023-08-30  6:51     ` Yujie Yang
  2023-08-30  8:22       ` Xi Ruoyao
  0 siblings, 1 reply; 14+ messages in thread
From: Yujie Yang @ 2023-08-30  6:51 UTC (permalink / raw)
  To: Xi Ruoyao; +Cc: Yang Yujie, gcc-patches, xuchenghua, chenglulu, panchenghui

> > LoongArch processors may not support memory accesses without natural
> > alignments.  Building libraries with -mstrict-align may help with
> > toolchain binary compatiblity and performance on these implementations
> > (e.g. Loongson 2K1000LA).
> > 
> > No significant performance degredation is observed on current mainstream
> > LoongArch processors when the option is enabled.
> > 
> > gcc/ChangeLog:
> > 
> >         * config.gcc: use -mstrict-align for building libraries
> >         if --with-strict-align-lib is given.
> 
> Isn't this equivalent to --with-default-multilib=mno-strict-align now?
> 
> And I still believe the easiest way for 2K1000LA is adding -march=la264
> support so the user can simply configure with --with-arch=la264.

Not exactly -- Options given in --with-multilib-default= will not be applied
to multilib variants that have build options specified in --with-multilib-list,
but --with-strict-align-lib is always effective.

e.g. for the following configuration:

  --with-multilib-default=mstrict-align
  --with-multilib-list=lp64d/la464,lp64s

The library build options would be:

  base/lp64d variant: -mabi=lp64d -march=la464 (no -mstrict-align appended)
  base/lp64s variant: -mabi=lp64s -march=abi-default -mstrict-align

Sure, you can do it with --with-arch=la264. It's just a convenient
switch that we can use for building generic toolchains.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 3/4] LoongArch: add new configure option --with-strict-align-lib
  2023-08-30  6:51     ` Yujie Yang
@ 2023-08-30  8:22       ` Xi Ruoyao
  2023-08-30 10:01         ` Yujie Yang
  0 siblings, 1 reply; 14+ messages in thread
From: Xi Ruoyao @ 2023-08-30  8:22 UTC (permalink / raw)
  To: Yujie Yang; +Cc: gcc-patches, xuchenghua, chenglulu, panchenghui

On Wed, 2023-08-30 at 14:51 +0800, Yujie Yang wrote:
> > > LoongArch processors may not support memory accesses without natural
> > > alignments.  Building libraries with -mstrict-align may help with
> > > toolchain binary compatiblity and performance on these implementations
> > > (e.g. Loongson 2K1000LA).
> > > 
> > > No significant performance degredation is observed on current mainstream
> > > LoongArch processors when the option is enabled.
> > > 
> > > gcc/ChangeLog:
> > > 
> > >         * config.gcc: use -mstrict-align for building libraries
> > >         if --with-strict-align-lib is given.
> > 
> > Isn't this equivalent to --with-default-multilib=mno-strict-align now?
> > 
> > And I still believe the easiest way for 2K1000LA is adding -march=la264
> > support so the user can simply configure with --with-arch=la264.
> 
> Not exactly -- Options given in --with-multilib-default= will not be applied
> to multilib variants that have build options specified in --with-multilib-list,
> but --with-strict-align-lib is always effective.
> 
> e.g. for the following configuration:
> 
>   --with-multilib-default=mstrict-align
>   --with-multilib-list=lp64d/la464,lp64s
> 
> The library build options would be:
> 
>   base/lp64d variant: -mabi=lp64d -march=la464 (no -mstrict-align appended)
>   base/lp64s variant: -mabi=lp64s -march=abi-default -mstrict-align
> 
> Sure, you can do it with --with-arch=la264. It's just a convenient
> switch that we can use for building generic toolchains.

If you want a generic toolchain, it should default to -mstrict-align as
well.  Or it will still do unexpected thing for cases like:

struct foo { char x; int y; } __attribute__ ((packed));

int get (struct foo *foo) { return foo->y; }

So it should be --with-strict-align (it should make the *compiler*
default to -mstrict-align).  But them it seems --with-arch=la264 is just
easier...

Or maybe we should add -march=la64-baseline (or another name?) as the
"bottom line" of a LA64 CPU.  Currently the definition of -
march=loongarch64 includes unaligned access and 64-bit FP support, so
IMO we should have a baseline definition if we need to support something
"below" loongarch64.

-- 
Xi Ruoyao <xry111@xry111.site>
School of Aerospace Science and Technology, Xidian University

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 3/4] LoongArch: add new configure option --with-strict-align-lib
  2023-08-30  8:22       ` Xi Ruoyao
@ 2023-08-30 10:01         ` Yujie Yang
  0 siblings, 0 replies; 14+ messages in thread
From: Yujie Yang @ 2023-08-30 10:01 UTC (permalink / raw)
  To: Xi Ruoyao; +Cc: Yujie Yang, gcc-patches, xuchenghua, chenglulu, panchenghui

On Wed, Aug 30, 2023 at 04:22:13PM +0800, Xi Ruoyao wrote:
> On Wed, 2023-08-30 at 14:51 +0800, Yujie Yang wrote:
> > > > LoongArch processors may not support memory accesses without natural
> > > > alignments.  Building libraries with -mstrict-align may help with
> > > > toolchain binary compatiblity and performance on these implementations
> > > > (e.g. Loongson 2K1000LA).
> > > > 
> > > > No significant performance degredation is observed on current mainstream
> > > > LoongArch processors when the option is enabled.
> > > > 
> > > > gcc/ChangeLog:
> > > > 
> > > >         * config.gcc: use -mstrict-align for building libraries
> > > >         if --with-strict-align-lib is given.
> > > 
> > > Isn't this equivalent to --with-default-multilib=mno-strict-align now?
> > > 
> > > And I still believe the easiest way for 2K1000LA is adding -march=la264
> > > support so the user can simply configure with --with-arch=la264.
> > 
> > Not exactly -- Options given in --with-multilib-default= will not be applied
> > to multilib variants that have build options specified in --with-multilib-list,
> > but --with-strict-align-lib is always effective.
> > 
> > e.g. for the following configuration:
> > 
> >   --with-multilib-default=mstrict-align
> >   --with-multilib-list=lp64d/la464,lp64s
> > 
> > The library build options would be:
> > 
> >   base/lp64d variant: -mabi=lp64d -march=la464 (no -mstrict-align appended)
> >   base/lp64s variant: -mabi=lp64s -march=abi-default -mstrict-align
> > 
> > Sure, you can do it with --with-arch=la264. It's just a convenient
> > switch that we can use for building generic toolchains.
> 
> If you want a generic toolchain, it should default to -mstrict-align as
> well.  Or it will still do unexpected thing for cases like:
> 
> struct foo { char x; int y; } __attribute__ ((packed));
> 
> int get (struct foo *foo) { return foo->y; }
> 
> So it should be --with-strict-align (it should make the *compiler*
> default to -mstrict-align).  But them it seems --with-arch=la264 is just
> easier...

By "generic" I mean: when you enable "-march=la264"/"-march=la464"
and link statically, you get a binary that's good for running on
LA264/LA464 cores, respectively.  It's more of a cross-toolchain case.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 1/4] LoongArch: improved target configuration interface
  2023-08-30  1:58 ` [PATCH v2 1/4] LoongArch: improved target configuration interface Yang Yujie
@ 2023-08-30 21:36   ` Joseph Myers
  2023-08-31  3:14     ` Yujie Yang
  0 siblings, 1 reply; 14+ messages in thread
From: Joseph Myers @ 2023-08-30 21:36 UTC (permalink / raw)
  To: Yang Yujie; +Cc: gcc-patches, xuchenghua, panchenghui, chenglulu

On Wed, 30 Aug 2023, Yang Yujie wrote:

> +A suffix @code{[/ARCH][/OPTION]...]} may follow immediately after the ABI
> +identifier to customize the compiler options for building the given set of
> +libraries.  @code{ARCH} denotes the architecture name recognized by the
> +@code{-march=ARCH} compiler option, which acts as a basic target ISA
> +configuration that can be adjusted using the subsequent @code{OPTION}
> +suffixes, where each @code{OPTION} is a compiler option itself.

Since ARCH and OPTION are not literal strings of program source code, you 
should actually be using @var{arch} and @var{option} for them (and @dots{} 
instead of ..., since the ... isn't literal source code either).

This patch series also adds a new configure option --with-strict-align-lib 
that needs documenting in the corresponding patch.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 1/4] LoongArch: improved target configuration interface
  2023-08-30 21:36   ` Joseph Myers
@ 2023-08-31  3:14     ` Yujie Yang
  2023-08-31  7:36       ` Yujie Yang
  2023-08-31 17:56       ` Joseph Myers
  0 siblings, 2 replies; 14+ messages in thread
From: Yujie Yang @ 2023-08-31  3:14 UTC (permalink / raw)
  To: Joseph Myers; +Cc: Yang Yujie, gcc-patches, xuchenghua, panchenghui, chenglulu

On Wed, Aug 30, 2023 at 09:36:22PM +0000, Joseph Myers wrote:
> On Wed, 30 Aug 2023, Yang Yujie wrote:
> 
> > +A suffix @code{[/ARCH][/OPTION]...]} may follow immediately after the ABI
> > +identifier to customize the compiler options for building the given set of
> > +libraries.  @code{ARCH} denotes the architecture name recognized by the
> > +@code{-march=ARCH} compiler option, which acts as a basic target ISA
> > +configuration that can be adjusted using the subsequent @code{OPTION}
> > +suffixes, where each @code{OPTION} is a compiler option itself.
> 
> Since ARCH and OPTION are not literal strings of program source code, you 
> should actually be using @var{arch} and @var{option} for them (and @dots{} 
> instead of ..., since the ... isn't literal source code either).
> 
> This patch series also adds a new configure option --with-strict-align-lib 
> that needs documenting in the corresponding patch.
> 
> -- 
> Joseph S. Myers
> joseph@codesourcery.com

Thanks for the review.  Does the following fix look good?
If so, I will include these in the patchset.

Yujie

---
 gcc/doc/install.texi | 44 +++++++++++++++++++++++---------------------
 1 file changed, 23 insertions(+), 21 deletions(-)

diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index 05a626280b7..3e589080f4e 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -1236,7 +1236,7 @@ sysv, aix.
 @itemx --without-multilib-list
 Specify what multilibs to build.  @var{list} is a comma separated list of
 values, possibly consisting of a single value.  Currently only implemented
-for aarch64*-*-*, arm*-*-*, loongarch64-*-*, riscv*-*-*, sh*-*-* and
+for aarch64*-*-*, arm*-*-*, loongarch*-*-*, riscv*-*-*, sh*-*-* and
 x86-64-*-linux*.  The accepted values and meaning for each target is given
 below.
 
@@ -1331,27 +1331,27 @@ the following ABI identifiers: @code{lp64d[/base]} @code{lp64f[/base]}
 @code{lp64d[/base]} (the @code{/base} suffix may be omitted)
 to enable their respective run-time libraries.
 
-A suffix @code{[/ARCH][/OPTION]...]} may follow immediately after the ABI
-identifier to customize the compiler options for building the given set of
-libraries.  @code{ARCH} denotes the architecture name recognized by the
-@code{-march=ARCH} compiler option, which acts as a basic target ISA
-configuration that can be adjusted using the subsequent @code{OPTION}
-suffixes, where each @code{OPTION} is a compiler option itself.
+A suffix @code{[/@var{arch}][/@var{option}/@dots{}]} may follow immediately
+after the ABI identifier to customize the compiler options for building the
+given set of libraries.  @var{arch} denotes the architecture name recognized
+by the @option{-march=@var{arch}} compiler option, which acts as a basic target
+ISA configuration that can be adjusted using the subsequent @var{option}
+suffixes, where each @var{option} is a compiler option itself.
 
-If none of such suffix is present, the configured value of
-@option{--with-multilib-default} can be used as a common default suffix
-for all library ABI variants.  Otherwise, the default build option
-@code{-march=abi-default} is applied when building the variants without
-a suffix.
+If no such suffix is present for a given multilib variant, the
+configured value of @code{--with-multilib-default} is appended as a default
+suffix.  If @code{--with-multilib-default} is not given, the default build
+option @code{-march=abi-default} is applied when building the variants
+without a suffix.
 
-As a special case, @code{fixed} may be used in the position of @code{ARCH},
-which means use the architecture configured with @option{--with-arch=ARCH},
-or its default value (e.g. @code{loongarch64} for @code{loongarch64-*}
-targets).
+As a special case, @code{fixed} may be used in the position of @var{arch},
+which means using the architecture configured with
+@code{--with-arch=@var{arch}}, or its default value (e.g. @code{loongarch64}
+for @code{loongarch64-*} targets).
 
-If @var{list} is empty or @code{default}, or if @option{--with-multilib-list}
-is not specified, then the default ABI as specified by @option{--with-abi} or
-implied by @option{--target}.
+If @var{list} is empty or @code{default}, or if @code{--with-multilib-list}
+is not specified, then only the default variant of the libraries are built,
+where the default ABI is implied by the configured target triplet.
 
 @item riscv*-*-*
 @var{list} is a single ABI name.  The target architecture must be either
@@ -1414,6 +1414,9 @@ Multiple @code{OPTION}s may appear consecutively while @code{ARCH} may only
 appear in the beginning or be omitted (which means @code{-march=abi-default}
 is applied when building the libraries).
 
+@item --with-strict-align-lib
+On LoongArch targets, build all enabled multilibs with @code{-mstrict-align}
+(Not enabled by default).
 
 @item --with-multilib-generator=@var{config}
 Specify what multilibs to build.  @var{config} is a semicolon separated list of
@@ -4539,8 +4542,7 @@ Uses @code{lp64s/base} ABI by default.
 @end table
 
 @item loongarch64-linux-gnu
-Same as @code{loongarch64-linux-gnuf64}, but may be used with
-@option{--with-abi=*} to configure the default ABI type.
+Same as @code{loongarch64-linux-gnuf64} for legacy support.
 @end table
 
 More information about LoongArch can be found at
-- 
2.42.0


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 1/4] LoongArch: improved target configuration interface
  2023-08-31  3:14     ` Yujie Yang
@ 2023-08-31  7:36       ` Yujie Yang
  2023-08-31 17:56       ` Joseph Myers
  1 sibling, 0 replies; 14+ messages in thread
From: Yujie Yang @ 2023-08-31  7:36 UTC (permalink / raw)
  To: Joseph Myers; +Cc: Yang Yujie, gcc-patches

On Thu, Aug 31, 2023 at 11:14:13AM +0800, Yujie Yang wrote:
> On Wed, Aug 30, 2023 at 09:36:22PM +0000, Joseph Myers wrote:
> > On Wed, 30 Aug 2023, Yang Yujie wrote:
> > 
> > > +A suffix @code{[/ARCH][/OPTION]...]} may follow immediately after the ABI
> > > +identifier to customize the compiler options for building the given set of
> > > +libraries.  @code{ARCH} denotes the architecture name recognized by the
> > > +@code{-march=ARCH} compiler option, which acts as a basic target ISA
> > > +configuration that can be adjusted using the subsequent @code{OPTION}
> > > +suffixes, where each @code{OPTION} is a compiler option itself.
> > 
> > Since ARCH and OPTION are not literal strings of program source code, you 
> > should actually be using @var{arch} and @var{option} for them (and @dots{} 
> > instead of ..., since the ... isn't literal source code either).
> > 
> > This patch series also adds a new configure option --with-strict-align-lib 
> > that needs documenting in the corresponding patch.
> > 
> > -- 
> > Joseph S. Myers
> > joseph@codesourcery.com
> 
> Thanks for the review.  Does the following fix look good?
> If so, I will include these in the patchset.

Found something else to fix, I will post them in the next version
of the patchset.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 1/4] LoongArch: improved target configuration interface
  2023-08-31  3:14     ` Yujie Yang
  2023-08-31  7:36       ` Yujie Yang
@ 2023-08-31 17:56       ` Joseph Myers
  2023-09-01  1:19         ` Yujie Yang
  1 sibling, 1 reply; 14+ messages in thread
From: Joseph Myers @ 2023-08-31 17:56 UTC (permalink / raw)
  To: Yujie Yang; +Cc: gcc-patches, xuchenghua, panchenghui, chenglulu

On Thu, 31 Aug 2023, Yujie Yang wrote:

> -If none of such suffix is present, the configured value of
> -@option{--with-multilib-default} can be used as a common default suffix
> -for all library ABI variants.  Otherwise, the default build option
> -@code{-march=abi-default} is applied when building the variants without
> -a suffix.
> +If no such suffix is present for a given multilib variant, the
> +configured value of @code{--with-multilib-default} is appended as a default
> +suffix.  If @code{--with-multilib-default} is not given, the default build
> +option @code{-march=abi-default} is applied when building the variants
> +without a suffix.

@option is appropriate for --with-multilib-default and other configure 
options; it shouldn't be changed to @code.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2 1/4] LoongArch: improved target configuration interface
  2023-08-31 17:56       ` Joseph Myers
@ 2023-09-01  1:19         ` Yujie Yang
  0 siblings, 0 replies; 14+ messages in thread
From: Yujie Yang @ 2023-09-01  1:19 UTC (permalink / raw)
  To: Joseph Myers; +Cc: gcc-patches

On Thu, Aug 31, 2023 at 05:56:26PM +0000, Joseph Myers wrote:
> On Thu, 31 Aug 2023, Yujie Yang wrote:
> 
> > -If none of such suffix is present, the configured value of
> > -@option{--with-multilib-default} can be used as a common default suffix
> > -for all library ABI variants.  Otherwise, the default build option
> > -@code{-march=abi-default} is applied when building the variants without
> > -a suffix.
> > +If no such suffix is present for a given multilib variant, the
> > +configured value of @code{--with-multilib-default} is appended as a default
> > +suffix.  If @code{--with-multilib-default} is not given, the default build
> > +option @code{-march=abi-default} is applied when building the variants
> > +without a suffix.
> 
> @option is appropriate for --with-multilib-default and other configure 
> options; it shouldn't be changed to @code.
> 

Thanks! Fixed in the v3 patchset.


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2023-09-01  1:19 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-30  1:58 [PATCH 0/4] LoongArch: target configuration interface update Yang Yujie
2023-08-30  1:58 ` [PATCH v2 1/4] LoongArch: improved target configuration interface Yang Yujie
2023-08-30 21:36   ` Joseph Myers
2023-08-31  3:14     ` Yujie Yang
2023-08-31  7:36       ` Yujie Yang
2023-08-31 17:56       ` Joseph Myers
2023-09-01  1:19         ` Yujie Yang
2023-08-30  1:58 ` [PATCH v2 2/4] LoongArch: define preprocessing macros "__loongarch_{arch,tune}" Yang Yujie
2023-08-30  1:58 ` [PATCH v2 3/4] LoongArch: add new configure option --with-strict-align-lib Yang Yujie
2023-08-30  5:25   ` Xi Ruoyao
2023-08-30  6:51     ` Yujie Yang
2023-08-30  8:22       ` Xi Ruoyao
2023-08-30 10:01         ` Yujie Yang
2023-08-30  1:58 ` [PATCH v2 4/4] LoongArch: support loongarch*-elf target Yang Yujie

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).