diff mbox series

[v1,2/6] Extract ix86 dllimport implementation to mingw

Message ID PR3PR83MB0425CF54E7A1BA0A96BE1A10F80E2@PR3PR83MB0425.EURPRD83.prod.outlook.com
State New
Headers show
Series Add DLL import/export implementation to AArch64 | expand

Commit Message

Evgeny Karpov April 18, 2024, 9:43 p.m. UTC
This patch extracts the ix86 implementation for expanding a SYMBOL
into its corresponding dllimport, far-address, or refptr symbol.
It will be reused in the aarch64-w64-mingw32 target.
The implementation is copied as is from i386/i386.cc with
minor changes to follow to the code style.

Also this patch replaces the original DLL import/export
implementation in ix86 with mingw.

gcc/ChangeLog:

	* config.gcc: Add winnt-dll.o, which contains the DLL
	import/export implementation.
	* config/i386/cygming.h (SUB_TARGET_RECORD_STUB): Remove the
	old implementation. Rename the required function to MinGW.
	Rename it to a conditional function that will reuse the
	MinGW implementation for COFF and nothing otherwise.
	* config/i386/i386-expand.cc (ix86_expand_move): Likewise.
	* config/i386/i386-expand.h (is_imported_p): Likewise.
	(mingw_GOT_alias_set): Likewise.
	(ix86_legitimize_pe_coff_symbol): Likewise.
	* config/i386/i386-protos.h: Likewise.
	* config/i386/i386.cc (is_imported_p): Likewise.
	(ix86_legitimize_pe_coff_symbol): Likewise.
	(ix86_GOT_alias_set): Likewise.
	(legitimize_pic_address): Likewise.
	(struct dllimport_hasher):
	(GTY): Likewise.
	(get_dllimport_decl): Likewise.
	(legitimize_pe_coff_extern_decl): Likewise.
	(legitimize_dllimport_symbol): Likewise.
	(legitimize_pe_coff_symbol): Likewise.
	(ix86_legitimize_address): Likewise.
	* config/mingw/winnt.h (mingw_pe_record_stub): Likewise.
	* config/mingw/winnt.cc (i386_pe_record_stub): Likewise.
	(mingw_pe_record_stub): Likewise.
	* config/mingw/t-cygming: Add the winnt-dll.o compilation.
	* config/mingw/winnt-dll.cc: New file.
---
 gcc/config.gcc                 |   6 +-
 gcc/config/i386/cygming.h      |   2 +-
 gcc/config/i386/i386-expand.cc |   2 +-
 gcc/config/i386/i386-expand.h  |   2 +-
 gcc/config/i386/i386-protos.h  |   2 +-
 gcc/config/i386/i386.cc        | 211 ++++--------------------------
 gcc/config/mingw/t-cygming     |   6 +
 gcc/config/mingw/winnt-dll.cc  | 229 +++++++++++++++++++++++++++++++++
 gcc/config/mingw/winnt-dll.h   |  26 ++++
 gcc/config/mingw/winnt.cc      |   2 +-
 gcc/config/mingw/winnt.h       |   1 +
 11 files changed, 292 insertions(+), 197 deletions(-)
 create mode 100644 gcc/config/mingw/winnt-dll.cc
 create mode 100644 gcc/config/mingw/winnt-dll.h

Comments

Richard Sandiford May 22, 2024, 11:05 a.m. UTC | #1
Evgeny Karpov <Evgeny.Karpov@microsoft.com> writes:
> This patch extracts the ix86 implementation for expanding a SYMBOL
> into its corresponding dllimport, far-address, or refptr symbol.
> It will be reused in the aarch64-w64-mingw32 target.
> The implementation is copied as is from i386/i386.cc with
> minor changes to follow to the code style.
>
> Also this patch replaces the original DLL import/export
> implementation in ix86 with mingw.
>
> gcc/ChangeLog:
>
> 	* config.gcc: Add winnt-dll.o, which contains the DLL
> 	import/export implementation.
> 	* config/i386/cygming.h (SUB_TARGET_RECORD_STUB): Remove the
> 	old implementation. Rename the required function to MinGW.
> 	Rename it to a conditional function that will reuse the
> 	MinGW implementation for COFF and nothing otherwise.
> 	* config/i386/i386-expand.cc (ix86_expand_move): Likewise.
> 	* config/i386/i386-expand.h (is_imported_p): Likewise.
> 	(mingw_GOT_alias_set): Likewise.
> 	(ix86_legitimize_pe_coff_symbol): Likewise.
> 	* config/i386/i386-protos.h: Likewise.
> 	* config/i386/i386.cc (is_imported_p): Likewise.
> 	(ix86_legitimize_pe_coff_symbol): Likewise.
> 	(ix86_GOT_alias_set): Likewise.
> 	(legitimize_pic_address): Likewise.
> 	(struct dllimport_hasher):
> 	(GTY): Likewise.
> 	(get_dllimport_decl): Likewise.
> 	(legitimize_pe_coff_extern_decl): Likewise.
> 	(legitimize_dllimport_symbol): Likewise.
> 	(legitimize_pe_coff_symbol): Likewise.
> 	(ix86_legitimize_address): Likewise.
> 	* config/mingw/winnt.h (mingw_pe_record_stub): Likewise.
> 	* config/mingw/winnt.cc (i386_pe_record_stub): Likewise.
> 	(mingw_pe_record_stub): Likewise.
> 	* config/mingw/t-cygming: Add the winnt-dll.o compilation.
> 	* config/mingw/winnt-dll.cc: New file.

This looks good to me apart from a couple of very minor comments below,
but please get approval from the x86 maintainers as well.  In particular,
they might prefer to handle ix86_legitimize_pe_coff_symbol in some other way.

> [...]
> diff --git a/gcc/config/mingw/winnt-dll.cc b/gcc/config/mingw/winnt-dll.cc
> new file mode 100644
> index 00000000000..349ade6f5c0
> --- /dev/null
> +++ b/gcc/config/mingw/winnt-dll.cc
> @@ -0,0 +1,229 @@
> +/* Expand a SYMBOL into its corresponding dllimport, far-address,
> +or refptr symbol.
> +Copyright (C) 2024 Free Software Foundation, Inc.

I suppose this should retain the range from the i386 file that the
code is moving from:

   Copyright (C) 1988-2024 Free Software Foundation, Inc.

> [...]
> diff --git a/gcc/config/mingw/winnt-dll.h b/gcc/config/mingw/winnt-dll.h
> new file mode 100644
> index 00000000000..19c16e747a2
> --- /dev/null
> +++ b/gcc/config/mingw/winnt-dll.h
> @@ -0,0 +1,26 @@
> +/* Expand a SYMBOL into its corresponding dllimport, far-address,
> +or refptr symbol.
> +Copyright (C) 2024 Free Software Foundation, Inc.
> +
> +GCC is free software; you can redistribute it and/or modify it under
> +the terms of the GNU General Public License as published by the Free
> +Software Foundation; either version 3, or (at your option) any later
> +version.
> +
> +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +for more details.
> +
> +You should have received a copy of the GNU General Public License
> +along with GCC; see the file COPYING3.  If not see
> +http://www.gnu.org/licenses/.  */
> +
> +#ifndef GCC_MINGW_WINNT_DLL_H
> +#define GCC_MINGW_WINNT_DLL_H
> +
> +extern bool is_imported_p (rtx x);
> +extern alias_set_type mingw_GOT_alias_set (void);
> +extern rtx legitimize_pe_coff_symbol (rtx addr, bool inreg);
> +
> +#endif
> \ No newline at end of file

Would be good to add the newlihe.

Thanks,
Richard
Evgeny Karpov May 22, 2024, 2:32 p.m. UTC | #2
Wednesday, May 22, 2024 1:06 PM
Richard Sandiford <richard.sandiford@arm.com> wrote:

> This looks good to me apart from a couple of very minor comments below, but
> please get approval from the x86 maintainers as well.  In particular, they might
> prefer to handle ix86_legitimize_pe_coff_symbol in some other way.

Thanks, Richard, for the review!
The suggestions will be addressed in the next version.

Jan and Uros, could you please review x86 refactoring for mingw part? Thanks.

Regards,
Evgeny
Uros Bizjak May 23, 2024, 8:35 a.m. UTC | #3
On Wed, May 22, 2024 at 4:32 PM Evgeny Karpov
<Evgeny.Karpov@microsoft.com> wrote:
>
> Wednesday, May 22, 2024 1:06 PM
> Richard Sandiford <richard.sandiford@arm.com> wrote:
>
> > This looks good to me apart from a couple of very minor comments below, but
> > please get approval from the x86 maintainers as well.  In particular, they might
> > prefer to handle ix86_legitimize_pe_coff_symbol in some other way.
>
> Thanks, Richard, for the review!
> The suggestions will be addressed in the next version.
>
> Jan and Uros, could you please review x86 refactoring for mingw part? Thanks.

Yes, perhaps legitimize_pe_coff_symbol should be handled similar to
how machopic_legitimize_pic_address is handled.and just use "#if
TARGET_PECOFF" at call sites when calling functions from the new
winnt-dll.h. This would also allow us to remove  the early check for
!TARGET_PECOFF in legitimize_pe_coff_symbol.

Uros.
Uros Bizjak May 23, 2024, 8:41 a.m. UTC | #4
On Thu, May 23, 2024 at 10:35 AM Uros Bizjak <ubizjak@gmail.com> wrote:
>
> On Wed, May 22, 2024 at 4:32 PM Evgeny Karpov
> <Evgeny.Karpov@microsoft.com> wrote:
> >
> > Wednesday, May 22, 2024 1:06 PM
> > Richard Sandiford <richard.sandiford@arm.com> wrote:
> >
> > > This looks good to me apart from a couple of very minor comments below, but
> > > please get approval from the x86 maintainers as well.  In particular, they might
> > > prefer to handle ix86_legitimize_pe_coff_symbol in some other way.
> >
> > Thanks, Richard, for the review!
> > The suggestions will be addressed in the next version.
> >
> > Jan and Uros, could you please review x86 refactoring for mingw part? Thanks.
>
> Yes, perhaps legitimize_pe_coff_symbol should be handled similar to
> how machopic_legitimize_pic_address is handled.and just use "#if
> TARGET_PECOFF" at call sites when calling functions from the new
> winnt-dll.h. This would also allow us to remove  the early check for
> !TARGET_PECOFF in legitimize_pe_coff_symbol.

Maybe you should look how TARGET_MACHO is handled in config/i386/* files.

Uros.
Evgeny Karpov May 23, 2024, 5:53 p.m. UTC | #5
Thursday, May 23, 2024 10:35 AM
Uros Bizjak <ubizjak@gmail.com> wrote:

> Richard Sandiford <richard.sandiford@arm.com> wrote:
> >
> > > This looks good to me apart from a couple of very minor comments
> > > below, but please get approval from the x86 maintainers as well.  In
> > > particular, they might prefer to handle ix86_legitimize_pe_coff_symbol in
> some other way.
> >
> > Jan and Uros, could you please review x86 refactoring for mingw part?
> 
> Yes, perhaps legitimize_pe_coff_symbol should be handled similar to how
> machopic_legitimize_pic_address is handled.and just use "#if TARGET_PECOFF"
> at call sites when calling functions from the new winnt-dll.h. This would also
> allow us to remove  the early check for !TARGET_PECOFF in
> legitimize_pe_coff_symbol.
> 
> Uros.


The function legitimize_pe_coff_symbol is now part of mingw and will not be used for linux targets. 
This is why ix86_legitimize_pe_coff_symbol has been introduced, to be available for all platforms.

Regards,
Evgeny
Uros Bizjak May 23, 2024, 7:37 p.m. UTC | #6
On Thu, May 23, 2024 at 7:53 PM Evgeny Karpov
<Evgeny.Karpov@microsoft.com> wrote:
>
>
> Thursday, May 23, 2024 10:35 AM
> Uros Bizjak <ubizjak@gmail.com> wrote:
>
> > Richard Sandiford <richard.sandiford@arm.com> wrote:
> > >
> > > > This looks good to me apart from a couple of very minor comments
> > > > below, but please get approval from the x86 maintainers as well.  In
> > > > particular, they might prefer to handle ix86_legitimize_pe_coff_symbol in
> > some other way.
> > >
> > > Jan and Uros, could you please review x86 refactoring for mingw part?
> >
> > Yes, perhaps legitimize_pe_coff_symbol should be handled similar to how
> > machopic_legitimize_pic_address is handled.and just use "#if TARGET_PECOFF"
> > at call sites when calling functions from the new winnt-dll.h. This would also
> > allow us to remove  the early check for !TARGET_PECOFF in
> > legitimize_pe_coff_symbol.
> >
> > Uros.
>
>
> The function legitimize_pe_coff_symbol is now part of mingw and will not be used for linux targets.
> This is why ix86_legitimize_pe_coff_symbol has been introduced, to be available for all platforms.

There is no need for a ix86_legitimize_pe_coff_symbol. This function
is now defined in a header that is not included by default, so the
call sites should use #if TARGET_PECOFF to isolate its use. Please see
how "#if TARGET_MACHO" is used in config/i386/* files for the similar
issue. I think that TARGET_PECOFF should follow this example.

Uros.
diff mbox series

Patch

diff --git a/gcc/config.gcc b/gcc/config.gcc
index ef7f854735a..be2b20a155c 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -2181,7 +2181,7 @@  i[34567]86-*-cygwin*)
 	tmake_file="${tmake_file} mingw/t-cygming t-slibgcc"
 	target_gtfiles="$target_gtfiles \$(srcdir)/config/mingw/winnt.cc"
 	extra_options="${extra_options} mingw/cygming.opt i386/cygwin.opt"
-	extra_objs="${extra_objs} winnt.o winnt-stubs.o"
+	extra_objs="${extra_objs} winnt.o winnt-stubs.o winnt-dll.o"
 	c_target_objs="${c_target_objs} msformat-c.o"
 	cxx_target_objs="${cxx_target_objs} winnt-cxx.o msformat-c.o"
 	d_target_objs="${d_target_objs} cygwin-d.o"
@@ -2199,7 +2199,7 @@  x86_64-*-cygwin*)
 	tmake_file="${tmake_file} mingw/t-cygming t-slibgcc"
 	target_gtfiles="$target_gtfiles \$(srcdir)/config/mingw/winnt.cc"
 	extra_options="${extra_options} mingw/cygming.opt i386/cygwin.opt"
-	extra_objs="${extra_objs} winnt.o winnt-stubs.o"
+	extra_objs="${extra_objs} winnt.o winnt-stubs.o winnt-dll.o"
 	c_target_objs="${c_target_objs} msformat-c.o"
 	cxx_target_objs="${cxx_target_objs} winnt-cxx.o msformat-c.o"
 	d_target_objs="${d_target_objs} cygwin-d.o"
@@ -2283,7 +2283,7 @@  i[34567]86-*-mingw* | x86_64-*-mingw*)
 		*)
 			;;
 	esac
-	extra_objs="${extra_objs} winnt.o winnt-stubs.o"
+	extra_objs="${extra_objs} winnt.o winnt-stubs.o winnt-dll.o"
 	c_target_objs="${c_target_objs} msformat-c.o"
 	cxx_target_objs="${cxx_target_objs} winnt-cxx.o msformat-c.o"
 	gas=yes
diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h
index beedf7c398a..4110ceab824 100644
--- a/gcc/config/i386/cygming.h
+++ b/gcc/config/i386/cygming.h
@@ -459,7 +459,7 @@  do {						\
 #define TARGET_ASM_ASSEMBLE_VISIBILITY i386_pe_assemble_visibility
 
 #undef SUB_TARGET_RECORD_STUB
-#define SUB_TARGET_RECORD_STUB i386_pe_record_stub
+#define SUB_TARGET_RECORD_STUB mingw_pe_record_stub
 
 /* Static stack checking is supported by means of probes.  */
 #define STACK_CHECK_STATIC_BUILTIN 1
diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index 8bb8f21e686..77bf4433aa8 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -412,7 +412,7 @@  ix86_expand_move (machine_mode mode, rtx operands[])
 	}
       else
 	{
-	  tmp = legitimize_pe_coff_symbol (op1, addend != NULL_RTX);
+	  tmp = ix86_legitimize_pe_coff_symbol (op1, addend != NULL_RTX);
 	  if (tmp)
 	    {
 	      op1 = tmp;
diff --git a/gcc/config/i386/i386-expand.h b/gcc/config/i386/i386-expand.h
index 65cb49c921c..a8c20993954 100644
--- a/gcc/config/i386/i386-expand.h
+++ b/gcc/config/i386/i386-expand.h
@@ -36,7 +36,7 @@  struct expand_vec_perm_d
 rtx legitimize_tls_address (rtx x, enum tls_model model, bool for_mov);
 alias_set_type ix86_GOT_alias_set (void);
 rtx legitimize_pic_address (rtx orig, rtx reg);
-rtx legitimize_pe_coff_symbol (rtx addr, bool inreg);
+rtx ix86_legitimize_pe_coff_symbol (rtx addr, bool inreg);
 
 bool insn_defines_reg (unsigned int regno1, unsigned int regno2,
 		       rtx_insn *insn);
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 96368521380..dbced12f8d4 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -18,6 +18,7 @@  along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config/mingw/winnt.h"
+#include "config/mingw/winnt-dll.h"
 
 /* In i386-common.cc.  */
 extern bool ix86_handle_option (struct gcc_options *opts,
@@ -314,7 +315,6 @@  extern void i386_pe_end_cold_function (FILE *, const char *, tree);
 extern void i386_pe_assemble_visibility (tree, int);
 extern tree i386_pe_mangle_decl_assembler_name (tree, tree);
 extern tree i386_pe_mangle_assembler_name (const char *);
-extern void i386_pe_record_stub (const char *);
 
 extern void i386_pe_seh_init (FILE *);
 extern void i386_pe_seh_end_prologue (FILE *);
diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
index 4d6b2b98761..a17e819602a 100644
--- a/gcc/config/i386/i386.cc
+++ b/gcc/config/i386/i386.cc
@@ -11230,20 +11230,6 @@  ix86_cannot_force_const_mem (machine_mode mode, rtx x)
   return !ix86_legitimate_constant_p (mode, x);
 }
 
-/*  Nonzero if the symbol is marked as dllimport, or as stub-variable,
-    otherwise zero.  */
-
-static bool
-is_imported_p (rtx x)
-{
-  if (!TARGET_DLLIMPORT_DECL_ATTRIBUTES
-      || GET_CODE (x) != SYMBOL_REF)
-    return false;
-
-  return SYMBOL_REF_DLLIMPORT_P (x) || SYMBOL_REF_STUBVAR_P (x);
-}
-
-
 /* Nonzero if the constant value X is a legitimate general operand
    when generating PIC code.  It is given that flag_pic is on and
    that X satisfies CONSTANT_P.  */
@@ -11822,17 +11808,31 @@  constant_address_p (rtx x)
   return CONSTANT_P (x) && ix86_legitimate_address_p (Pmode, x, 1);
 }
 

-/* Return a unique alias set for the GOT.  */
+
+#if TARGET_PECOFF
+rtx ix86_legitimize_pe_coff_symbol (rtx addr, bool inreg)
+{
+  return legitimize_pe_coff_symbol (addr, inreg);
+}
 
 alias_set_type
 ix86_GOT_alias_set (void)
 {
-  static alias_set_type set = -1;
-  if (set == -1)
-    set = new_alias_set ();
-  return set;
+  return mingw_GOT_alias_set ();
+}
+#else
+rtx ix86_legitimize_pe_coff_symbol (rtx addr, bool inreg)
+{
+  return NULL_RTX;
 }
 
+alias_set_type
+ix86_GOT_alias_set (void)
+{
+  return -1;
+}
+#endif
+
 /* Return a legitimate reference for ORIG (an address) using the
    register REG.  If REG is 0, a new pseudo is generated.
 
@@ -11869,7 +11869,7 @@  legitimize_pic_address (rtx orig, rtx reg)
 
   if (TARGET_64BIT && TARGET_DLLIMPORT_DECL_ATTRIBUTES)
     {
-      rtx tmp = legitimize_pe_coff_symbol (addr, true);
+      rtx tmp = ix86_legitimize_pe_coff_symbol (addr, true);
       if (tmp)
         return tmp;
     }
@@ -11914,7 +11914,7 @@  legitimize_pic_address (rtx orig, rtx reg)
 	      on VxWorks, see gotoff_operand.  */
 	   || (TARGET_VXWORKS_RTP && GET_CODE (addr) == LABEL_REF))
     {
-      rtx tmp = legitimize_pe_coff_symbol (addr, true);
+      rtx tmp = ix86_legitimize_pe_coff_symbol (addr, true);
       if (tmp)
         return tmp;
 
@@ -12489,173 +12489,6 @@  ix86_rewrite_tls_address (rtx pattern)
   return pattern;
 }
 
-/* Create or return the unique __imp_DECL dllimport symbol corresponding
-   to symbol DECL if BEIMPORT is true.  Otherwise create or return the
-   unique refptr-DECL symbol corresponding to symbol DECL.  */
-
-struct dllimport_hasher : ggc_cache_ptr_hash<tree_map>
-{
-  static inline hashval_t hash (tree_map *m) { return m->hash; }
-  static inline bool
-  equal (tree_map *a, tree_map *b)
-  {
-    return a->base.from == b->base.from;
-  }
-
-  static int
-  keep_cache_entry (tree_map *&m)
-  {
-    return ggc_marked_p (m->base.from);
-  }
-};
-
-static GTY((cache)) hash_table<dllimport_hasher> *dllimport_map;
-
-static tree
-get_dllimport_decl (tree decl, bool beimport)
-{
-  struct tree_map *h, in;
-  const char *name;
-  const char *prefix;
-  size_t namelen, prefixlen;
-  char *imp_name;
-  tree to;
-  rtx rtl;
-
-  if (!dllimport_map)
-    dllimport_map = hash_table<dllimport_hasher>::create_ggc (512);
-
-  in.hash = htab_hash_pointer (decl);
-  in.base.from = decl;
-  tree_map **loc = dllimport_map->find_slot_with_hash (&in, in.hash, INSERT);
-  h = *loc;
-  if (h)
-    return h->to;
-
-  *loc = h = ggc_alloc<tree_map> ();
-  h->hash = in.hash;
-  h->base.from = decl;
-  h->to = to = build_decl (DECL_SOURCE_LOCATION (decl),
-			   VAR_DECL, NULL, ptr_type_node);
-  DECL_ARTIFICIAL (to) = 1;
-  DECL_IGNORED_P (to) = 1;
-  DECL_EXTERNAL (to) = 1;
-  TREE_READONLY (to) = 1;
-
-  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-  name = targetm.strip_name_encoding (name);
-  if (beimport)
-    prefix = name[0] == FASTCALL_PREFIX || user_label_prefix[0] == 0
-      ? "*__imp_" : "*__imp__";
-  else
-    prefix = user_label_prefix[0] == 0 ? "*.refptr." : "*refptr.";
-  namelen = strlen (name);
-  prefixlen = strlen (prefix);
-  imp_name = (char *) alloca (namelen + prefixlen + 1);
-  memcpy (imp_name, prefix, prefixlen);
-  memcpy (imp_name + prefixlen, name, namelen + 1);
-
-  name = ggc_alloc_string (imp_name, namelen + prefixlen);
-  rtl = gen_rtx_SYMBOL_REF (Pmode, name);
-  SET_SYMBOL_REF_DECL (rtl, to);
-  SYMBOL_REF_FLAGS (rtl) = SYMBOL_FLAG_LOCAL | SYMBOL_FLAG_STUBVAR;
-  if (!beimport)
-    {
-      SYMBOL_REF_FLAGS (rtl) |= SYMBOL_FLAG_EXTERNAL;
-#ifdef SUB_TARGET_RECORD_STUB
-      SUB_TARGET_RECORD_STUB (name);
-#endif
-    }      
-
-  rtl = gen_const_mem (Pmode, rtl);
-  set_mem_alias_set (rtl, ix86_GOT_alias_set ());
-
-  SET_DECL_RTL (to, rtl);
-  SET_DECL_ASSEMBLER_NAME (to, get_identifier (name));
-
-  return to;
-}
-
-/* Expand SYMBOL into its corresponding far-address symbol.
-   WANT_REG is true if we require the result be a register.  */
-
-static rtx
-legitimize_pe_coff_extern_decl (rtx symbol, bool want_reg)
-{
-  tree imp_decl;
-  rtx x;
-
-  gcc_assert (SYMBOL_REF_DECL (symbol));
-  imp_decl = get_dllimport_decl (SYMBOL_REF_DECL (symbol), false);
-
-  x = DECL_RTL (imp_decl);
-  if (want_reg)
-    x = force_reg (Pmode, x);
-  return x;
-}
-
-/* Expand SYMBOL into its corresponding dllimport symbol.  WANT_REG is
-   true if we require the result be a register.  */
-
-static rtx
-legitimize_dllimport_symbol (rtx symbol, bool want_reg)
-{
-  tree imp_decl;
-  rtx x;
-
-  gcc_assert (SYMBOL_REF_DECL (symbol));
-  imp_decl = get_dllimport_decl (SYMBOL_REF_DECL (symbol), true);
-
-  x = DECL_RTL (imp_decl);
-  if (want_reg)
-    x = force_reg (Pmode, x);
-  return x;
-}
-
-/* Expand SYMBOL into its corresponding dllimport or refptr symbol.  WANT_REG 
-   is true if we require the result be a register.  */
-
-rtx
-legitimize_pe_coff_symbol (rtx addr, bool inreg)
-{
-  if (!TARGET_PECOFF)
-    return NULL_RTX;
-
-  if (TARGET_DLLIMPORT_DECL_ATTRIBUTES)
-    {
-      if (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_DLLIMPORT_P (addr))
-	return legitimize_dllimport_symbol (addr, inreg);
-      if (GET_CODE (addr) == CONST
-	  && GET_CODE (XEXP (addr, 0)) == PLUS
-	  && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF
-	  && SYMBOL_REF_DLLIMPORT_P (XEXP (XEXP (addr, 0), 0)))
-	{
-	  rtx t = legitimize_dllimport_symbol (XEXP (XEXP (addr, 0), 0), inreg);
-	  return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (addr, 0), 1));
-	}
-    }
-
-  if (ix86_cmodel != CM_LARGE_PIC && ix86_cmodel != CM_MEDIUM_PIC)
-    return NULL_RTX;
-  if (GET_CODE (addr) == SYMBOL_REF
-      && !is_imported_p (addr)
-      && SYMBOL_REF_EXTERNAL_P (addr)
-      && SYMBOL_REF_DECL (addr))
-    return legitimize_pe_coff_extern_decl (addr, inreg);
-
-  if (GET_CODE (addr) == CONST
-      && GET_CODE (XEXP (addr, 0)) == PLUS
-      && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF
-      && !is_imported_p (XEXP (XEXP (addr, 0), 0))
-      && SYMBOL_REF_EXTERNAL_P (XEXP (XEXP (addr, 0), 0))
-      && SYMBOL_REF_DECL (XEXP (XEXP (addr, 0), 0)))
-    {
-      rtx t = legitimize_pe_coff_extern_decl (XEXP (XEXP (addr, 0), 0), inreg);
-      return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (addr, 0), 1));
-    }
-  return NULL_RTX;
-}
-
 /* Try machine-dependent ways of modifying an illegitimate address
    to be legitimate.  If we find one, return the new, valid address.
    This macro is used in only one place: `memory_address' in explow.cc.
@@ -12695,7 +12528,7 @@  ix86_legitimize_address (rtx x, rtx, machine_mode mode)
 
   if (TARGET_DLLIMPORT_DECL_ATTRIBUTES)
     {
-      rtx tmp = legitimize_pe_coff_symbol (x, true);
+      rtx tmp = ix86_legitimize_pe_coff_symbol (x, true);
       if (tmp)
         return tmp;
     }
diff --git a/gcc/config/mingw/t-cygming b/gcc/config/mingw/t-cygming
index f5de941c8e5..73679a9d6c0 100644
--- a/gcc/config/mingw/t-cygming
+++ b/gcc/config/mingw/t-cygming
@@ -33,6 +33,12 @@  winnt-cxx.o: $(srcdir)/config/mingw/winnt-cxx.cc $(CONFIG_H) $(SYSTEM_H) \
 	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
 	$(srcdir)/config/mingw/winnt-cxx.cc
 
+winnt-dll.o: $(srcdir)/config/mingw/winnt-dll.cc $(CONFIG_H) $(SYSTEM_H) \
+  coretypes.h \
+  $(TM_H) $(TREE_H) flags.h \
+  $(TM_P_H) $(HASHTAB_H) $(GGC_H)
+	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+	$(srcdir)/config/mingw/winnt-dll.cc
 
 winnt-stubs.o: $(srcdir)/config/mingw/winnt-stubs.cc $(CONFIG_H) $(SYSTEM_H) \
   coretypes.h \
diff --git a/gcc/config/mingw/winnt-dll.cc b/gcc/config/mingw/winnt-dll.cc
new file mode 100644
index 00000000000..349ade6f5c0
--- /dev/null
+++ b/gcc/config/mingw/winnt-dll.cc
@@ -0,0 +1,229 @@ 
+/* Expand a SYMBOL into its corresponding dllimport, far-address,
+or refptr symbol.
+Copyright (C) 2024 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+http://www.gnu.org/licenses/.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "target.h"
+#include "rtl.h"
+#include "tree.h"
+#include "memmodel.h"
+#include "stringpool.h"
+#include "emit-rtl.h"
+#include "alias.h"
+#include "varasm.h"
+#include "output.h"
+#include "explow.h"
+#include "winnt.h"
+
+/* Create or return the unique __imp_DECL dllimport symbol corresponding
+   to symbol DECL if BEIMPORT is true.  Otherwise create or return the
+   unique refptr-DECL symbol corresponding to symbol DECL.  */
+
+struct dllimport_hasher : ggc_cache_ptr_hash<tree_map>
+{
+  static inline hashval_t hash (tree_map *m)
+  {
+    return m->hash;
+  }
+
+  static inline bool
+  equal (tree_map *a, tree_map *b)
+  {
+    return a->base.from == b->base.from;
+  }
+
+  static int
+  keep_cache_entry (tree_map *&m)
+  {
+    return ggc_marked_p (m->base.from);
+  }
+};
+
+static GTY ((cache)) hash_table<dllimport_hasher> *dllimport_map;
+
+/*  Nonzero if the symbol is marked as dllimport, or as stub-variable,
+    otherwise zero.  */
+
+bool
+is_imported_p (rtx x)
+{
+  if (!TARGET_DLLIMPORT_DECL_ATTRIBUTES
+      || GET_CODE (x) != SYMBOL_REF)
+    return false;
+
+  return SYMBOL_REF_DLLIMPORT_P (x) || SYMBOL_REF_STUBVAR_P (x);
+}
+
+/* Return a unique alias set for the GOT.  */
+
+alias_set_type
+mingw_GOT_alias_set (void)
+{
+  static alias_set_type set = -1;
+  if (set == -1)
+    set = new_alias_set ();
+  return set;
+}
+
+static tree
+get_dllimport_decl (tree decl, bool beimport)
+{
+  struct tree_map *h, in;
+  const char *name;
+  const char *prefix;
+  size_t namelen, prefixlen;
+  char *imp_name;
+  tree to;
+  rtx rtl;
+
+  if (!dllimport_map)
+    dllimport_map = hash_table<dllimport_hasher>::create_ggc (512);
+
+  in.hash = htab_hash_pointer (decl);
+  in.base.from = decl;
+  tree_map **loc = dllimport_map->find_slot_with_hash (&in, in.hash, INSERT);
+  h = *loc;
+  if (h)
+    return h->to;
+
+  *loc = h = ggc_alloc<tree_map> ();
+  h->hash = in.hash;
+  h->base.from = decl;
+  h->to = to = build_decl (DECL_SOURCE_LOCATION (decl),
+			   VAR_DECL, NULL, ptr_type_node);
+  DECL_ARTIFICIAL (to) = 1;
+  DECL_IGNORED_P (to) = 1;
+  DECL_EXTERNAL (to) = 1;
+  TREE_READONLY (to) = 1;
+
+  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+  name = targetm.strip_name_encoding (name);
+  if (beimport)
+    prefix = name[0] == FASTCALL_PREFIX || user_label_prefix[0] == 0
+      ? "*__imp_" : "*__imp__";
+  else
+    prefix = user_label_prefix[0] == 0 ? "*.refptr." : "*refptr.";
+  namelen = strlen (name);
+  prefixlen = strlen (prefix);
+  imp_name = (char *) alloca (namelen + prefixlen + 1);
+  memcpy (imp_name, prefix, prefixlen);
+  memcpy (imp_name + prefixlen, name, namelen + 1);
+
+  name = ggc_alloc_string (imp_name, namelen + prefixlen);
+  rtl = gen_rtx_SYMBOL_REF (Pmode, name);
+  SET_SYMBOL_REF_DECL (rtl, to);
+  SYMBOL_REF_FLAGS (rtl) = SYMBOL_FLAG_LOCAL | SYMBOL_FLAG_STUBVAR;
+  if (!beimport)
+    {
+      SYMBOL_REF_FLAGS (rtl) |= SYMBOL_FLAG_EXTERNAL;
+#ifdef SUB_TARGET_RECORD_STUB
+      SUB_TARGET_RECORD_STUB (name);
+#endif
+    }
+
+  rtl = gen_const_mem (Pmode, rtl);
+  set_mem_alias_set (rtl, mingw_GOT_alias_set ());
+
+  SET_DECL_RTL (to, rtl);
+  SET_DECL_ASSEMBLER_NAME (to, get_identifier (name));
+
+  return to;
+}
+
+/* Expand SYMBOL into its corresponding far-address symbol.
+   WANT_REG is true if we require the result be a register.  */
+
+static rtx
+legitimize_pe_coff_extern_decl (rtx symbol, bool want_reg)
+{
+  tree imp_decl;
+  rtx x;
+
+  gcc_assert (SYMBOL_REF_DECL (symbol));
+  imp_decl = get_dllimport_decl (SYMBOL_REF_DECL (symbol), false);
+
+  x = DECL_RTL (imp_decl);
+  if (want_reg)
+    x = force_reg (Pmode, x);
+  return x;
+}
+
+/* Expand SYMBOL into its corresponding dllimport symbol.  WANT_REG is
+   true if we require the result be a register.  */
+
+static rtx
+legitimize_dllimport_symbol (rtx symbol, bool want_reg)
+{
+  tree imp_decl;
+  rtx x;
+
+  gcc_assert (SYMBOL_REF_DECL (symbol));
+  imp_decl = get_dllimport_decl (SYMBOL_REF_DECL (symbol), true);
+
+  x = DECL_RTL (imp_decl);
+  if (want_reg)
+    x = force_reg (Pmode, x);
+  return x;
+}
+
+/* Expand SYMBOL into its corresponding dllimport or refptr symbol.  WANT_REG
+   is true if we require the result be a register.  */
+
+rtx
+legitimize_pe_coff_symbol (rtx addr, bool inreg)
+{
+  if (!TARGET_PECOFF)
+    return NULL_RTX;
+
+  if (TARGET_DLLIMPORT_DECL_ATTRIBUTES)
+    {
+      if (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_DLLIMPORT_P (addr))
+	return legitimize_dllimport_symbol (addr, inreg);
+      if (GET_CODE (addr) == CONST
+	  && GET_CODE (XEXP (addr, 0)) == PLUS
+	  && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF
+	  && SYMBOL_REF_DLLIMPORT_P (XEXP (XEXP (addr, 0), 0)))
+	{
+	  rtx t = legitimize_dllimport_symbol (XEXP (XEXP (addr, 0), 0), inreg);
+	  return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (addr, 0), 1));
+	}
+    }
+
+  if (ix86_cmodel != CM_LARGE_PIC && ix86_cmodel != CM_MEDIUM_PIC)
+    return NULL_RTX;
+
+  if (GET_CODE (addr) == SYMBOL_REF
+      && !is_imported_p (addr)
+      && SYMBOL_REF_EXTERNAL_P (addr)
+      && SYMBOL_REF_DECL (addr))
+    return legitimize_pe_coff_extern_decl (addr, inreg);
+
+  if (GET_CODE (addr) == CONST
+      && GET_CODE (XEXP (addr, 0)) == PLUS
+      && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF
+      && !is_imported_p (XEXP (XEXP (addr, 0), 0))
+      && SYMBOL_REF_EXTERNAL_P (XEXP (XEXP (addr, 0), 0))
+      && SYMBOL_REF_DECL (XEXP (XEXP (addr, 0), 0)))
+    {
+      rtx t = legitimize_pe_coff_extern_decl (XEXP (XEXP (addr, 0), 0), inreg);
+      return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (addr, 0), 1));
+    }
+  return NULL_RTX;
+}
diff --git a/gcc/config/mingw/winnt-dll.h b/gcc/config/mingw/winnt-dll.h
new file mode 100644
index 00000000000..19c16e747a2
--- /dev/null
+++ b/gcc/config/mingw/winnt-dll.h
@@ -0,0 +1,26 @@ 
+/* Expand a SYMBOL into its corresponding dllimport, far-address,
+or refptr symbol.
+Copyright (C) 2024 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+http://www.gnu.org/licenses/.  */
+
+#ifndef GCC_MINGW_WINNT_DLL_H
+#define GCC_MINGW_WINNT_DLL_H
+
+extern bool is_imported_p (rtx x);
+extern alias_set_type mingw_GOT_alias_set (void);
+extern rtx legitimize_pe_coff_symbol (rtx addr, bool inreg);
+
+#endif
\ No newline at end of file
diff --git a/gcc/config/mingw/winnt.cc b/gcc/config/mingw/winnt.cc
index 2a4fc03fc56..9901576ade0 100644
--- a/gcc/config/mingw/winnt.cc
+++ b/gcc/config/mingw/winnt.cc
@@ -672,7 +672,7 @@  mingw_pe_maybe_record_exported_symbol (tree decl, const char *name, int is_data)
 }
 
 void
-i386_pe_record_stub (const char *name)
+mingw_pe_record_stub (const char *name)
 {
   struct stub_list *p;
 
diff --git a/gcc/config/mingw/winnt.h b/gcc/config/mingw/winnt.h
index da8445904ce..646654e872d 100644
--- a/gcc/config/mingw/winnt.h
+++ b/gcc/config/mingw/winnt.h
@@ -23,6 +23,7 @@  extern void mingw_pe_declare_function_type (FILE *file, const char *name,
 	int pub);
 extern void mingw_pe_encode_section_info (tree, rtx, int);
 extern void mingw_pe_maybe_record_exported_symbol (tree, const char *, int);
+extern void mingw_pe_record_stub (const char *name);
 extern unsigned int mingw_pe_section_type_flags (tree, const char *, int);
 extern void mingw_pe_unique_section (tree, int);