加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
LoongArch-improved-target-configuration-interface.patch 97.53 KB
一键复制 编辑 原始数据 按行查看 历史
ticat_fp 提交于 2024-03-26 09:26 . LoongArch: update from gcc upstream
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024
From b980a32eabcbd34e8f8e6a245dbba1898256555e Mon Sep 17 00:00:00 2001
From: Yang Yujie <yangyujie@loongson.cn>
Date: Wed, 23 Aug 2023 15:16:21 +0800
Subject: [PATCH 058/124] LoongArch: improved target configuration interface
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:
1. lp64d/base ABI (built with "-march=la464 -mno-strict-align -msimd=lsx")
2. lp64s/base 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.
Signed-off-by: Peng Fan <fanpeng@loongson.cn>
Signed-off-by: ticat_fp <fanpeng@loongson.cn>
---
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 | 52 ++-
19 files changed, 1136 insertions(+), 681 deletions(-)
diff --git a/config-ml.in b/config-ml.in
index 68854a4f1..ad0db0781 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 5c378c698..62525c296 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -4965,43 +4965,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";;
@@ -5010,42 +5013,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.
@@ -5059,73 +5044,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"
;;
@@ -5138,7 +5091,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
@@ -5157,7 +5110,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
@@ -5178,7 +5131,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
@@ -5186,32 +5139,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
@@ -5223,13 +5163,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
@@ -5245,25 +5225,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
@@ -5272,57 +5248,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
@@ -5783,34 +5813,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 44ebb7ab1..21245f52a 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 e10618777..c6e337d05 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 0ae177610..89d61bf58 100644
--- a/gcc/config/loongarch/la464.md
+++ b/gcc/config/loongarch/la464.md
@@ -43,88 +43,88 @@
;; 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 f779a7355..2cf84eec7 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");
+ }
+
/* Add support for FLOAT128_TYPE on the LoongArch architecture. */
builtin_define ("__FLOAT128_TYPE__");
diff --git a/gcc/config/loongarch/loongarch-cpu.cc b/gcc/config/loongarch/loongarch-cpu.cc
index a886dd932..ea05526d7 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 93d656f70..eacb38774 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 74d422ce0..d29d5f001 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 eb87a79a5..0aee7dc19 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 0adcc923b..b3626984d 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 2e4a7a9c8..6cfe0efb5 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 e13eafb58..200702b0e 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 3523a4cf7..e3f9b6f99 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 9f1b0989c..6b12754a3 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 41d344b82..bd774d4a9 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -2551,7 +2551,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,
@@ -2593,7 +2593,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:
@@ -6060,8 +6060,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;
}
@@ -6072,8 +6072,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;
}
@@ -6250,17 +6250,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;
@@ -6269,33 +6306,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
@@ -6303,12 +6320,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");
@@ -6378,7 +6389,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 96c811c85..f96d32769 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 136b27d0a..62a870b66 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 19d073256..1fc5f0bfa 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -1173,7 +1173,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.
@@ -1263,12 +1263,33 @@ 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{[/@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 without a leading dash
+('-').
+
+If no such suffix is present for a given multilib variant, the
+configured value of @option{--with-multilib-default} is appended as a default
+suffix. If @option{--with-multilib-default} is not given, the default build
+option @option{-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 @var{arch},
+which means using the architecture configured with
+@option{--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 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
@@ -1319,6 +1340,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{[/@var{arch}][/@var{option}/@dots{}]}, where @var{arch} is an
+architecture name recognized by @option{-march=@var{arch}} compiler option,
+and subsequent @var{option} suffixes are compiler options minus a leading
+dash ('-').
+
+Multiple @var{option}s may appear consecutively while @var{arch} may only
+appear in the beginning or be omitted (which means @option{-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
@@ -1468,6 +1502,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
@@ -4489,8 +4524,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.33.0
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化