diff --git a/gcc/config/loongarch/genopts/loongarch.opt.in b/gcc/config/loongarch/genopts/loongarch.opt.in
index ebdd9538d48..e10618777b2 100644
--- a/gcc/config/loongarch/genopts/loongarch.opt.in
+++ b/gcc/config/loongarch/genopts/loongarch.opt.in
@@ -184,3 +184,7 @@ Enum(cmodel) String(@@STR_CMODEL_EXTREME@@) Value(CMODEL_EXTREME)
 mcmodel=
 Target RejectNegative Joined Enum(cmodel) Var(la_opt_cmodel) Init(CMODEL_NORMAL)
 Specify the code model.
+
+mdirect-extern-access
+Target Var(TARGET_DIRECT_EXTERN_ACCESS) Init(0)
+Avoid using the GOT to access external symbols.
diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
index 77e3a105390..c9187bf81a7 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -1610,6 +1610,9 @@ loongarch_weak_symbol_p (const_rtx x)
 bool
 loongarch_symbol_binds_local_p (const_rtx x)
 {
+  if (TARGET_DIRECT_EXTERN_ACCESS)
+    return true;
+
   if (SYMBOL_REF_P (x))
     return (SYMBOL_REF_DECL (x)
 	    ? targetm.binds_local_p (SYMBOL_REF_DECL (x))
@@ -6093,6 +6096,9 @@ loongarch_option_override_internal (struct gcc_options *opts)
   if (loongarch_branch_cost == 0)
     loongarch_branch_cost = loongarch_cost->branch_cost;
 
+  if (TARGET_DIRECT_EXTERN_ACCESS && flag_shlib)
+    error ("%qs cannot be used for compiling a shared library",
+	   "-mdirect-extern-access");
 
   switch (la_target.cmodel)
     {
diff --git a/gcc/config/loongarch/loongarch.opt b/gcc/config/loongarch/loongarch.opt
index 6395234218b..96c811c850b 100644
--- a/gcc/config/loongarch/loongarch.opt
+++ b/gcc/config/loongarch/loongarch.opt
@@ -191,3 +191,7 @@ Enum(cmodel) String(extreme) Value(CMODEL_EXTREME)
 mcmodel=
 Target RejectNegative Joined Enum(cmodel) Var(la_opt_cmodel) Init(CMODEL_NORMAL)
 Specify the code model.
+
+mdirect-extern-access
+Target Var(TARGET_DIRECT_EXTERN_ACCESS) Init(0)
+Avoid using the GOT to access external symbols.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index dd3302fcd15..9d662e35316 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1017,6 +1017,7 @@ Objective-C and Objective-C++ Dialects}.
 -memcpy  -mno-memcpy -mstrict-align -mno-strict-align @gol
 -mmax-inline-memcpy-size=@var{n} @gol
 -mexplicit-relocs -mno-explicit-relocs @gol
+-mdirect-extern-access -mno-direct-extern-access @gol
 -mcmodel=@var{code-model}}
 
 @emph{M32R/D Options}
@@ -25090,6 +25091,20 @@ GCC build-time by detecting corresponding assembler support:
 @code{-mno-explicit-relocs} otherwise.  This option is mostly useful for
 debugging, or interoperation with assemblers different from the build-time
 one.
+
+@item -mdirect-extern-access
+@itemx -mno-direct-extern-access
+@opindex mdirect-extern-access
+Do not use or use GOT to access external symbols.  The default is
+@option{-mno-direct-extern-access}: GOT is used for external symbols with
+default visibility, but not used for other external symbols.
+
+With @option{-mdirect-extern-access}, GOT is not used and all external
+symbols are PC-relatively addressed.  It is @strong{only} suitable for
+environments where no dynamic link is performed, like firmwares, OS
+kernels, executables linked with @option{-static} or @option{-static-pie}.
+@option{-mdirect-extern-access} is not compatible with @option{-fPIC} or
+@option{-fpic}.
 @end table
 
 @node M32C Options
diff --git a/gcc/testsuite/gcc.target/loongarch/direct-extern-1.c b/gcc/testsuite/gcc.target/loongarch/direct-extern-1.c
new file mode 100644
index 00000000000..85c6c1e8a88
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/direct-extern-1.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-mexplicit-relocs -mdirect-extern-access" } */
+/* { dg-final { scan-assembler-not "got" } } */
+
+extern int x;
+int f() { return x; }
diff --git a/gcc/testsuite/gcc.target/loongarch/direct-extern-2.c b/gcc/testsuite/gcc.target/loongarch/direct-extern-2.c
new file mode 100644
index 00000000000..58d8bd68a06
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/direct-extern-2.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-mno-explicit-relocs -mdirect-extern-access" } */
+/* { dg-final { scan-assembler-not "la.global" } } */
+
+extern int x;
+int f() { return x; }
