[PR c++/84492] stmt expr ending with overload
[official-gcc.git] / gcc / config / i386 / winnt.c
blob3e5396755aecbeb697cf6b591f447472a2c5f234
1 /* Subroutines for insn-output.c for Windows NT.
2 Contributed by Douglas Rupp (drupp@cs.washington.edu)
3 Copyright (C) 1995-2018 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #define IN_TARGET_CODE 1
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "target.h"
27 #include "function.h"
28 #include "basic-block.h"
29 #include "rtl.h"
30 #include "tree.h"
31 #include "gimple.h"
32 #include "memmodel.h"
33 #include "tm_p.h"
34 #include "stringpool.h"
35 #include "attribs.h"
36 #include "emit-rtl.h"
37 #include "cgraph.h"
38 #include "lto-streamer.h"
39 #include "output.h"
40 #include "varasm.h"
41 #include "lto-section-names.h"
43 /* i386/PE specific attribute support.
45 i386/PE has two new attributes:
46 dllexport - for exporting a function/variable that will live in a dll
47 dllimport - for importing a function/variable from a dll
49 Microsoft allows multiple declspecs in one __declspec, separating
50 them with spaces. We do NOT support this. Instead, use __declspec
51 multiple times.
54 /* Handle a "shared" attribute;
55 arguments as in struct attribute_spec.handler. */
56 tree
57 ix86_handle_shared_attribute (tree *node, tree name, tree, int,
58 bool *no_add_attrs)
60 if (TREE_CODE (*node) != VAR_DECL)
62 warning (OPT_Wattributes, "%qE attribute only applies to variables",
63 name);
64 *no_add_attrs = true;
67 return NULL_TREE;
70 /* Handle a "selectany" attribute;
71 arguments as in struct attribute_spec.handler. */
72 tree
73 ix86_handle_selectany_attribute (tree *node, tree name, tree, int,
74 bool *no_add_attrs)
76 tree decl = *node;
77 /* The attribute applies only to objects that are initialized and have
78 external linkage. However, we may not know about initialization
79 until the language frontend has processed the decl. Therefore
80 we make sure that variable isn't initialized as common. */
81 if (TREE_CODE (decl) != VAR_DECL || !TREE_PUBLIC (decl))
82 error ("%qE attribute applies only to initialized variables"
83 " with external linkage", name);
84 else
86 make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl));
87 /* A variable with attribute selectany never can be common. */
88 DECL_COMMON (decl) = 0;
91 /* We don't need to keep attribute itself. */
92 *no_add_attrs = true;
93 return NULL_TREE;
97 /* Return the type that we should use to determine if DECL is
98 imported or exported. */
100 static tree
101 associated_type (tree decl)
103 return (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl))
104 ? DECL_CONTEXT (decl) : NULL_TREE);
107 /* Return true if DECL should be a dllexport'd object. */
109 static bool
110 i386_pe_determine_dllexport_p (tree decl)
112 if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
113 return false;
115 /* Don't export local clones of dllexports. */
116 if (!TREE_PUBLIC (decl))
117 return false;
119 if (TREE_CODE (decl) == FUNCTION_DECL
120 && DECL_DECLARED_INLINE_P (decl)
121 && !flag_keep_inline_dllexport)
122 return false;
124 if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
125 return true;
127 return false;
130 /* Return true if DECL should be a dllimport'd object. */
132 static bool
133 i386_pe_determine_dllimport_p (tree decl)
135 tree assoc;
137 if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
138 return false;
140 if (DECL_DLLIMPORT_P (decl))
141 return true;
143 /* The DECL_DLLIMPORT_P flag was set for decls in the class definition
144 by targetm.cxx.adjust_class_at_definition. Check again to emit
145 error message if the class attribute has been overridden by an
146 out-of-class definition of static data. */
147 assoc = associated_type (decl);
148 if (assoc && lookup_attribute ("dllimport", TYPE_ATTRIBUTES (assoc))
149 && TREE_CODE (decl) == VAR_DECL
150 && TREE_STATIC (decl) && TREE_PUBLIC (decl)
151 && !DECL_EXTERNAL (decl)
152 /* vtable's are linkonce constants, so defining a vtable is not
153 an error as long as we don't try to import it too. */
154 && !DECL_VIRTUAL_P (decl))
155 error ("definition of static data member %q+D of "
156 "dllimport%'d class", decl);
158 return false;
161 /* Handle the -mno-fun-dllimport target switch. */
163 bool
164 i386_pe_valid_dllimport_attribute_p (const_tree decl)
166 if (TARGET_NOP_FUN_DLLIMPORT && TREE_CODE (decl) == FUNCTION_DECL)
167 return false;
168 return true;
171 /* Return string which is the function name, identified by ID, modified
172 with a suffix consisting of an atsign (@) followed by the number of
173 bytes of arguments. If ID is NULL use the DECL_NAME as base. If
174 FASTCALL is true, also add the FASTCALL_PREFIX.
175 Return NULL if no change required. */
177 static tree
178 gen_stdcall_or_fastcall_suffix (tree decl, tree id, bool fastcall)
180 HOST_WIDE_INT total = 0;
181 const char *old_str = IDENTIFIER_POINTER (id != NULL_TREE ? id : DECL_NAME (decl));
182 char *new_str, *p;
183 tree type = TREE_TYPE (DECL_ORIGIN (decl));
184 tree arg;
185 function_args_iterator args_iter;
187 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
189 if (prototype_p (type))
191 /* This attribute is ignored for variadic functions. */
192 if (stdarg_p (type))
193 return NULL_TREE;
195 /* Quit if we hit an incomplete type. Error is reported
196 by convert_arguments in c-typeck.c or cp/typeck.c. */
197 FOREACH_FUNCTION_ARGS(type, arg, args_iter)
199 HOST_WIDE_INT parm_size;
200 HOST_WIDE_INT parm_boundary_bytes = PARM_BOUNDARY / BITS_PER_UNIT;
202 if (! COMPLETE_TYPE_P (arg))
203 break;
205 parm_size = int_size_in_bytes (arg);
206 if (parm_size < 0)
207 break;
209 /* Must round up to include padding. This is done the same
210 way as in store_one_arg. */
211 parm_size = ((parm_size + parm_boundary_bytes - 1)
212 / parm_boundary_bytes * parm_boundary_bytes);
213 total += parm_size;
217 /* Assume max of 8 base 10 digits in the suffix. */
218 p = new_str = XALLOCAVEC (char, 1 + strlen (old_str) + 1 + 8 + 1);
219 if (fastcall)
220 *p++ = FASTCALL_PREFIX;
221 sprintf (p, "%s@" HOST_WIDE_INT_PRINT_DEC, old_str, total);
223 return get_identifier (new_str);
226 /* Maybe decorate and get a new identifier for the DECL of a stdcall or
227 fastcall function. The original identifier is supplied in ID. */
229 static tree
230 i386_pe_maybe_mangle_decl_assembler_name (tree decl, tree id)
232 tree new_id = NULL_TREE;
234 if (TREE_CODE (decl) == FUNCTION_DECL)
236 unsigned int ccvt = ix86_get_callcvt (TREE_TYPE (decl));
237 if ((ccvt & IX86_CALLCVT_STDCALL) != 0)
239 if (TARGET_RTD)
240 /* If we are using -mrtd emit undecorated symbol and let linker
241 do the proper resolving. */
242 return NULL_TREE;
243 new_id = gen_stdcall_or_fastcall_suffix (decl, id, false);
245 else if ((ccvt & IX86_CALLCVT_FASTCALL) != 0)
246 new_id = gen_stdcall_or_fastcall_suffix (decl, id, true);
249 return new_id;
252 /* Emit an assembler directive to set symbol for DECL visibility to
253 the visibility type VIS, which must not be VISIBILITY_DEFAULT.
254 As for PE there is no hidden support in gas, we just warn for
255 user-specified visibility attributes. */
257 void
258 i386_pe_assemble_visibility (tree decl, int)
260 if (!decl
261 || !lookup_attribute ("visibility", DECL_ATTRIBUTES (decl)))
262 return;
263 if (!DECL_ARTIFICIAL (decl))
264 warning (OPT_Wattributes, "visibility attribute not supported "
265 "in this configuration; ignored");
268 /* This is used as a target hook to modify the DECL_ASSEMBLER_NAME
269 in the language-independent default hook
270 langhooks,c:lhd_set_decl_assembler_name ()
271 and in cp/mangle,c:mangle_decl (). */
272 tree
273 i386_pe_mangle_decl_assembler_name (tree decl, tree id)
275 tree new_id = i386_pe_maybe_mangle_decl_assembler_name (decl, id);
277 return (new_id ? new_id : id);
280 /* This hook behaves the same as varasm.c/assemble_name(), but
281 generates the name into memory rather than outputting it to
282 a file stream. */
284 tree
285 i386_pe_mangle_assembler_name (const char *name)
287 const char *skipped = name + (*name == '*' ? 1 : 0);
288 const char *stripped = targetm.strip_name_encoding (skipped);
289 if (*name != '*' && *user_label_prefix && *stripped != FASTCALL_PREFIX)
290 stripped = ACONCAT ((user_label_prefix, stripped, NULL));
291 return get_identifier (stripped);
294 void
295 i386_pe_encode_section_info (tree decl, rtx rtl, int first)
297 rtx symbol;
298 int flags;
300 /* Do this last, due to our frobbing of DECL_DLLIMPORT_P above. */
301 default_encode_section_info (decl, rtl, first);
303 /* Careful not to prod global register variables. */
304 if (!MEM_P (rtl))
305 return;
307 symbol = XEXP (rtl, 0);
308 gcc_assert (GET_CODE (symbol) == SYMBOL_REF);
310 switch (TREE_CODE (decl))
312 case FUNCTION_DECL:
313 case VAR_DECL:
314 break;
316 default:
317 return;
320 /* Mark the decl so we can tell from the rtl whether the object is
321 dllexport'd or dllimport'd. tree.c: merge_dllimport_decl_attributes
322 handles dllexport/dllimport override semantics. */
323 flags = (SYMBOL_REF_FLAGS (symbol) &
324 ~(SYMBOL_FLAG_DLLIMPORT | SYMBOL_FLAG_DLLEXPORT));
325 if (i386_pe_determine_dllexport_p (decl))
326 flags |= SYMBOL_FLAG_DLLEXPORT;
327 else if (i386_pe_determine_dllimport_p (decl))
328 flags |= SYMBOL_FLAG_DLLIMPORT;
330 SYMBOL_REF_FLAGS (symbol) = flags;
334 bool
335 i386_pe_binds_local_p (const_tree exp)
337 if ((TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == FUNCTION_DECL)
338 && DECL_DLLIMPORT_P (exp))
339 return false;
341 /* External public symbols, which aren't weakref-s,
342 have local-binding for PE targets. */
343 if (DECL_P (exp)
344 && !lookup_attribute ("weakref", DECL_ATTRIBUTES (exp))
345 && TREE_PUBLIC (exp)
346 && DECL_EXTERNAL (exp))
347 return true;
349 #ifndef MAKE_DECL_ONE_ONLY
350 /* PR target/66655: If a function has been marked as DECL_ONE_ONLY
351 but we do not the means to make it so, then do not allow it to
352 bind locally. */
353 if (DECL_P (exp)
354 && TREE_CODE (exp) == FUNCTION_DECL
355 && TREE_PUBLIC (exp)
356 && DECL_ONE_ONLY (exp)
357 && ! DECL_EXTERNAL (exp)
358 && DECL_DECLARED_INLINE_P (exp))
359 return false;
360 #endif
362 return default_binds_local_p_1 (exp, 0);
365 /* Also strip the fastcall prefix and stdcall suffix. */
367 const char *
368 i386_pe_strip_name_encoding_full (const char *str)
370 const char *p;
371 const char *name = default_strip_name_encoding (str);
373 /* Strip leading '@' on fastcall symbols. */
374 if (*name == '@')
375 name++;
377 /* Strip trailing "@n". */
378 p = strchr (name, '@');
379 if (p)
380 return ggc_alloc_string (name, p - name);
382 return name;
385 void
386 i386_pe_unique_section (tree decl, int reloc)
388 int len;
389 const char *name, *prefix;
390 char *string;
392 /* Ignore RELOC, if we are allowed to put relocated
393 const data into read-only section. */
394 if (!flag_writable_rel_rdata)
395 reloc = 0;
396 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
397 name = i386_pe_strip_name_encoding_full (name);
399 /* The object is put in, for example, section .text$foo.
400 The linker will then ultimately place them in .text
401 (everything from the $ on is stripped). Don't put
402 read-only data in .rdata section to avoid a PE linker
403 bug when .rdata$* grouped sections are used in code
404 without a .rdata section. */
405 if (TREE_CODE (decl) == FUNCTION_DECL)
406 prefix = ".text$";
407 else if (decl_readonly_section (decl, reloc))
408 prefix = ".rdata$";
409 else
410 prefix = ".data$";
411 len = strlen (name) + strlen (prefix);
412 string = XALLOCAVEC (char, len + 1);
413 sprintf (string, "%s%s", prefix, name);
415 set_decl_section_name (decl, string);
418 /* Local and global relocs can be placed always into readonly memory for
419 memory for PE-COFF targets. */
421 i386_pe_reloc_rw_mask (void)
423 return 0;
426 /* Select a set of attributes for section NAME based on the properties
427 of DECL and whether or not RELOC indicates that DECL's initializer
428 might contain runtime relocations.
430 We make the section read-only and executable for a function decl,
431 read-only for a const data decl, and writable for a non-const data decl.
433 If the section has already been defined, to not allow it to have
434 different attributes, as (1) this is ambiguous since we're not seeing
435 all the declarations up front and (2) some assemblers (e.g. SVR4)
436 do not recognize section redefinitions. */
437 /* ??? This differs from the "standard" PE implementation in that we
438 handle the SHARED variable attribute. Should this be done for all
439 PE targets? */
441 #define SECTION_PE_SHARED SECTION_MACH_DEP
443 unsigned int
444 i386_pe_section_type_flags (tree decl, const char *, int reloc)
446 unsigned int flags;
448 /* Ignore RELOC, if we are allowed to put relocated
449 const data into read-only section. */
450 if (!flag_writable_rel_rdata)
451 reloc = 0;
453 if (decl && TREE_CODE (decl) == FUNCTION_DECL)
454 flags = SECTION_CODE;
455 else if (decl && decl_readonly_section (decl, reloc))
456 flags = 0;
457 else
459 flags = SECTION_WRITE;
461 if (decl && TREE_CODE (decl) == VAR_DECL
462 && lookup_attribute ("shared", DECL_ATTRIBUTES (decl)))
463 flags |= SECTION_PE_SHARED;
466 if (decl && DECL_P (decl) && DECL_ONE_ONLY (decl))
467 flags |= SECTION_LINKONCE;
469 return flags;
472 void
473 i386_pe_asm_named_section (const char *name, unsigned int flags,
474 tree decl)
476 char flagchars[8], *f = flagchars;
478 #if defined (HAVE_GAS_SECTION_EXCLUDE) && HAVE_GAS_SECTION_EXCLUDE == 1
479 if ((flags & SECTION_EXCLUDE) != 0)
480 *f++ = 'e';
481 #endif
483 if ((flags & (SECTION_CODE | SECTION_WRITE)) == 0)
484 /* readonly data */
486 *f++ ='d'; /* This is necessary for older versions of gas. */
487 *f++ ='r';
489 else
491 if (flags & SECTION_CODE)
492 *f++ = 'x';
493 if (flags & SECTION_WRITE)
494 *f++ = 'w';
495 if (flags & SECTION_PE_SHARED)
496 *f++ = 's';
497 #if !defined (HAVE_GAS_SECTION_EXCLUDE) || HAVE_GAS_SECTION_EXCLUDE == 0
498 /* If attribute "e" isn't supported we mark this section as
499 never-load. */
500 if ((flags & SECTION_EXCLUDE) != 0)
501 *f++ = 'n';
502 #endif
505 /* LTO sections need 1-byte alignment to avoid confusing the
506 zlib decompression algorithm with trailing zero pad bytes. */
507 if (strncmp (name, LTO_SECTION_NAME_PREFIX,
508 strlen (LTO_SECTION_NAME_PREFIX)) == 0)
509 *f++ = '0';
511 *f = '\0';
513 fprintf (asm_out_file, "\t.section\t%s,\"%s\"\n", name, flagchars);
515 if (flags & SECTION_LINKONCE)
517 /* Functions may have been compiled at various levels of
518 optimization so we can't use `same_size' here.
519 Instead, have the linker pick one, without warning.
520 If 'selectany' attribute has been specified, MS compiler
521 sets 'discard' characteristic, rather than telling linker
522 to warn of size or content mismatch, so do the same. */
523 bool discard = (flags & SECTION_CODE)
524 || (TREE_CODE (decl) != IDENTIFIER_NODE
525 && lookup_attribute ("selectany",
526 DECL_ATTRIBUTES (decl)));
527 fprintf (asm_out_file, "\t.linkonce %s\n",
528 (discard ? "discard" : "same_size"));
532 /* Beware, DECL may be NULL if compile_file() is emitting the LTO marker. */
534 void
535 i386_pe_asm_output_aligned_decl_common (FILE *stream, tree decl,
536 const char *name, HOST_WIDE_INT size,
537 HOST_WIDE_INT align)
539 HOST_WIDE_INT rounded;
541 /* Compute as in assemble_noswitch_variable, since we don't have
542 support for aligned common on older binutils. We must also
543 avoid emitting a common symbol of size zero, as this is the
544 overloaded representation that indicates an undefined external
545 symbol in the PE object file format. */
546 rounded = size ? size : 1;
547 rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;
548 rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
549 * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
551 i386_pe_maybe_record_exported_symbol (decl, name, 1);
553 fprintf (stream, "\t.comm\t");
554 assemble_name (stream, name);
555 if (use_pe_aligned_common)
556 fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC ", %d\n",
557 size ? size : HOST_WIDE_INT_1,
558 exact_log2 (align) - exact_log2 (CHAR_BIT));
559 else
560 fprintf (stream, ", " HOST_WIDE_INT_PRINT_DEC "\t" ASM_COMMENT_START
561 " " HOST_WIDE_INT_PRINT_DEC "\n", rounded, size);
564 /* The Microsoft linker requires that every function be marked as
565 DT_FCN. When using gas on cygwin, we must emit appropriate .type
566 directives. */
568 #include "gsyms.h"
570 /* Mark a function appropriately. This should only be called for
571 functions for which we are not emitting COFF debugging information.
572 FILE is the assembler output file, NAME is the name of the
573 function, and PUB is nonzero if the function is globally
574 visible. */
576 void
577 i386_pe_declare_function_type (FILE *file, const char *name, int pub)
579 fprintf (file, "\t.def\t");
580 assemble_name (file, name);
581 fprintf (file, ";\t.scl\t%d;\t.type\t%d;\t.endef\n",
582 pub ? (int) C_EXT : (int) C_STAT,
583 (int) DT_FCN << N_BTSHFT);
586 /* Keep a list of external functions. */
588 struct GTY(()) extern_list
590 struct extern_list *next;
591 tree decl;
592 const char *name;
595 static GTY(()) struct extern_list *extern_head;
597 /* Assemble an external function reference. We need to keep a list of
598 these, so that we can output the function types at the end of the
599 assembly. We can't output the types now, because we might see a
600 definition of the function later on and emit debugging information
601 for it then. */
603 void
604 i386_pe_record_external_function (tree decl, const char *name)
606 struct extern_list *p;
608 p = ggc_alloc<extern_list> ();
609 p->next = extern_head;
610 p->decl = decl;
611 p->name = name;
612 extern_head = p;
615 /* Keep a list of exported symbols. */
617 struct GTY(()) export_list
619 struct export_list *next;
620 const char *name;
621 int is_data; /* used to type tag exported symbols. */
624 /* Keep a list of stub symbols. */
626 struct GTY(()) stub_list
628 struct stub_list *next;
629 const char *name;
632 static GTY(()) struct export_list *export_head;
634 static GTY(()) struct stub_list *stub_head;
636 /* Assemble an export symbol entry. We need to keep a list of
637 these, so that we can output the export list at the end of the
638 assembly. We used to output these export symbols in each function,
639 but that causes problems with GNU ld when the sections are
640 linkonce. Beware, DECL may be NULL if compile_file() is emitting
641 the LTO marker. */
643 void
644 i386_pe_maybe_record_exported_symbol (tree decl, const char *name, int is_data)
646 rtx symbol;
647 struct export_list *p;
649 if (!decl)
650 return;
652 symbol = XEXP (DECL_RTL (decl), 0);
653 gcc_assert (GET_CODE (symbol) == SYMBOL_REF);
654 if (!SYMBOL_REF_DLLEXPORT_P (symbol))
655 return;
657 gcc_assert (TREE_PUBLIC (decl));
659 p = ggc_alloc<export_list> ();
660 p->next = export_head;
661 p->name = name;
662 p->is_data = is_data;
663 export_head = p;
666 void
667 i386_pe_record_stub (const char *name)
669 struct stub_list *p;
671 if (!name || *name == 0)
672 return;
674 p = stub_head;
675 while (p != NULL)
677 if (p->name[0] == *name
678 && !strcmp (p->name, name))
679 return;
680 p = p->next;
683 p = ggc_alloc<stub_list> ();
684 p->next = stub_head;
685 p->name = name;
686 stub_head = p;
690 #ifdef CXX_WRAP_SPEC_LIST
692 /* Search for a function named TARGET in the list of library wrappers
693 we are using, returning a pointer to it if found or NULL if not.
694 This function might be called on quite a few symbols, and we only
695 have the list of names of wrapped functions available to us as a
696 spec string, so first time round we lazily initialise a hash table
697 to make things quicker. */
699 static const char *
700 i386_find_on_wrapper_list (const char *target)
702 static char first_time = 1;
703 static hash_table<nofree_string_hash> *wrappers;
705 if (first_time)
707 /* Beware that this is not a complicated parser, it assumes
708 that any sequence of non-whitespace beginning with an
709 underscore is one of the wrapped symbols. For now that's
710 adequate to distinguish symbols from spec substitutions
711 and command-line options. */
712 static char wrapper_list_buffer[] = CXX_WRAP_SPEC_LIST;
713 char *bufptr;
714 /* Breaks up the char array into separated strings
715 strings and enter them into the hash table. */
716 wrappers = new hash_table<nofree_string_hash> (8);
717 for (bufptr = wrapper_list_buffer; *bufptr; ++bufptr)
719 char *found = NULL;
720 if (ISSPACE (*bufptr))
721 continue;
722 if (*bufptr == '_')
723 found = bufptr;
724 while (*bufptr && !ISSPACE (*bufptr))
725 ++bufptr;
726 if (*bufptr)
727 *bufptr = 0;
728 if (found)
729 *wrappers->find_slot (found, INSERT) = found;
731 first_time = 0;
734 return wrappers->find (target);
737 #endif /* CXX_WRAP_SPEC_LIST */
739 /* This is called at the end of assembly. For each external function
740 which has not been defined, we output a declaration now. We also
741 output the .drectve section. */
743 void
744 i386_pe_file_end (void)
746 struct extern_list *p;
748 for (p = extern_head; p != NULL; p = p->next)
750 tree decl;
752 decl = p->decl;
754 /* Positively ensure only one declaration for any given symbol. */
755 if (! TREE_ASM_WRITTEN (decl)
756 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
758 #ifdef CXX_WRAP_SPEC_LIST
759 /* To ensure the DLL that provides the corresponding real
760 functions is still loaded at runtime, we must reference
761 the real function so that an (unused) import is created. */
762 const char *realsym = i386_find_on_wrapper_list (p->name);
763 if (realsym)
764 i386_pe_declare_function_type (asm_out_file,
765 concat ("__real_", realsym, NULL), TREE_PUBLIC (decl));
766 #endif /* CXX_WRAP_SPEC_LIST */
767 TREE_ASM_WRITTEN (decl) = 1;
768 i386_pe_declare_function_type (asm_out_file, p->name,
769 TREE_PUBLIC (decl));
773 if (export_head)
775 struct export_list *q;
776 drectve_section ();
777 for (q = export_head; q != NULL; q = q->next)
779 fprintf (asm_out_file, "\t.ascii \" -export:\\\"%s\\\"%s\"\n",
780 default_strip_name_encoding (q->name),
781 (q->is_data ? ",data" : ""));
785 if (stub_head)
787 struct stub_list *q;
789 for (q = stub_head; q != NULL; q = q->next)
791 const char *name = q->name;
792 const char *oname;
794 if (name[0] == '*')
795 ++name;
796 oname = name;
797 if (name[0] == '.')
798 ++name;
799 if (strncmp (name, "refptr.", 7) != 0)
800 continue;
801 name += 7;
802 fprintf (asm_out_file, "\t.section\t.rdata$%s, \"dr\"\n"
803 "\t.globl\t%s\n"
804 "\t.linkonce\tdiscard\n", oname, oname);
805 fprintf (asm_out_file, "%s:\n\t.quad\t%s\n", oname, name);
811 /* x64 Structured Exception Handling unwind info. */
813 struct seh_frame_state
815 /* SEH records saves relative to the "current" stack pointer, whether
816 or not there's a frame pointer in place. This tracks the current
817 stack pointer offset from the CFA. */
818 HOST_WIDE_INT sp_offset;
820 /* The CFA is located at CFA_REG + CFA_OFFSET. */
821 HOST_WIDE_INT cfa_offset;
822 rtx cfa_reg;
825 /* Set up data structures beginning output for SEH. */
827 void
828 i386_pe_seh_init (FILE *f)
830 struct seh_frame_state *seh;
832 if (!TARGET_SEH)
833 return;
834 if (cfun->is_thunk)
835 return;
837 /* We cannot support DRAP with SEH. We turned off support for it by
838 re-defining MAX_STACK_ALIGNMENT when SEH is enabled. */
839 gcc_assert (!stack_realign_drap);
841 seh = XCNEW (struct seh_frame_state);
842 cfun->machine->seh = seh;
844 seh->sp_offset = INCOMING_FRAME_SP_OFFSET;
845 seh->cfa_offset = INCOMING_FRAME_SP_OFFSET;
846 seh->cfa_reg = stack_pointer_rtx;
848 fputs ("\t.seh_proc\t", f);
849 assemble_name (f, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (cfun->decl)));
850 fputc ('\n', f);
853 void
854 i386_pe_seh_end_prologue (FILE *f)
856 struct seh_frame_state *seh;
858 if (!TARGET_SEH)
859 return;
860 if (cfun->is_thunk)
861 return;
862 seh = cfun->machine->seh;
864 XDELETE (seh);
865 cfun->machine->seh = NULL;
867 fputs ("\t.seh_endprologue\n", f);
870 static void
871 i386_pe_seh_fini (FILE *f)
873 if (!TARGET_SEH)
874 return;
875 if (cfun->is_thunk)
876 return;
877 fputs ("\t.seh_endproc\n", f);
880 /* Emit an assembler directive to save REG via a PUSH. */
882 static void
883 seh_emit_push (FILE *f, struct seh_frame_state *seh, rtx reg)
885 unsigned int regno = REGNO (reg);
887 gcc_checking_assert (GENERAL_REGNO_P (regno));
889 seh->sp_offset += UNITS_PER_WORD;
890 if (seh->cfa_reg == stack_pointer_rtx)
891 seh->cfa_offset += UNITS_PER_WORD;
893 fputs ("\t.seh_pushreg\t", f);
894 print_reg (reg, 0, f);
895 fputc ('\n', f);
898 /* Emit an assembler directive to save REG at CFA - CFA_OFFSET. */
900 static void
901 seh_emit_save (FILE *f, struct seh_frame_state *seh,
902 rtx reg, HOST_WIDE_INT cfa_offset)
904 unsigned int regno = REGNO (reg);
905 HOST_WIDE_INT offset;
907 /* Negative save offsets are of course not supported, since that
908 would be a store below the stack pointer and thus clobberable. */
909 gcc_assert (seh->sp_offset >= cfa_offset);
910 offset = seh->sp_offset - cfa_offset;
912 fputs ((SSE_REGNO_P (regno) ? "\t.seh_savexmm\t"
913 : GENERAL_REGNO_P (regno) ? "\t.seh_savereg\t"
914 : (gcc_unreachable (), "")), f);
915 print_reg (reg, 0, f);
916 fprintf (f, ", " HOST_WIDE_INT_PRINT_DEC "\n", offset);
919 /* Emit an assembler directive to adjust RSP by OFFSET. */
921 static void
922 seh_emit_stackalloc (FILE *f, struct seh_frame_state *seh,
923 HOST_WIDE_INT offset)
925 /* We're only concerned with prologue stack allocations, which all
926 are subtractions from the stack pointer. */
927 gcc_assert (offset < 0);
928 offset = -offset;
930 if (seh->cfa_reg == stack_pointer_rtx)
931 seh->cfa_offset += offset;
932 seh->sp_offset += offset;
934 /* Do not output the stackalloc in that case (it won't work as there is no
935 encoding for very large frame size). */
936 if (offset < SEH_MAX_FRAME_SIZE)
937 fprintf (f, "\t.seh_stackalloc\t" HOST_WIDE_INT_PRINT_DEC "\n", offset);
940 /* Process REG_CFA_ADJUST_CFA for SEH. */
942 static void
943 seh_cfa_adjust_cfa (FILE *f, struct seh_frame_state *seh, rtx pat)
945 rtx dest, src;
946 HOST_WIDE_INT reg_offset = 0;
947 unsigned int dest_regno;
949 dest = SET_DEST (pat);
950 src = SET_SRC (pat);
952 if (GET_CODE (src) == PLUS)
954 reg_offset = INTVAL (XEXP (src, 1));
955 src = XEXP (src, 0);
957 else if (GET_CODE (src) == MINUS)
959 reg_offset = -INTVAL (XEXP (src, 1));
960 src = XEXP (src, 0);
962 gcc_assert (src == stack_pointer_rtx);
963 gcc_assert (seh->cfa_reg == stack_pointer_rtx);
964 dest_regno = REGNO (dest);
966 if (dest_regno == STACK_POINTER_REGNUM)
967 seh_emit_stackalloc (f, seh, reg_offset);
968 else if (dest_regno == HARD_FRAME_POINTER_REGNUM)
970 HOST_WIDE_INT offset;
972 seh->cfa_reg = dest;
973 seh->cfa_offset -= reg_offset;
975 offset = seh->sp_offset - seh->cfa_offset;
977 gcc_assert ((offset & 15) == 0);
978 gcc_assert (IN_RANGE (offset, 0, 240));
980 fputs ("\t.seh_setframe\t", f);
981 print_reg (seh->cfa_reg, 0, f);
982 fprintf (f, ", " HOST_WIDE_INT_PRINT_DEC "\n", offset);
984 else
985 gcc_unreachable ();
988 /* Process REG_CFA_OFFSET for SEH. */
990 static void
991 seh_cfa_offset (FILE *f, struct seh_frame_state *seh, rtx pat)
993 rtx dest, src;
994 HOST_WIDE_INT reg_offset;
996 dest = SET_DEST (pat);
997 src = SET_SRC (pat);
999 gcc_assert (MEM_P (dest));
1000 dest = XEXP (dest, 0);
1001 if (REG_P (dest))
1002 reg_offset = 0;
1003 else
1005 gcc_assert (GET_CODE (dest) == PLUS);
1006 reg_offset = INTVAL (XEXP (dest, 1));
1007 dest = XEXP (dest, 0);
1009 gcc_assert (dest == seh->cfa_reg);
1011 seh_emit_save (f, seh, src, seh->cfa_offset - reg_offset);
1014 /* Process a FRAME_RELATED_EXPR for SEH. */
1016 static void
1017 seh_frame_related_expr (FILE *f, struct seh_frame_state *seh, rtx pat)
1019 rtx dest, src;
1020 HOST_WIDE_INT addend;
1022 /* See the full loop in dwarf2out_frame_debug_expr. */
1023 if (GET_CODE (pat) == PARALLEL || GET_CODE (pat) == SEQUENCE)
1025 int i, n = XVECLEN (pat, 0), pass, npass;
1027 npass = (GET_CODE (pat) == PARALLEL ? 2 : 1);
1028 for (pass = 0; pass < npass; ++pass)
1029 for (i = 0; i < n; ++i)
1031 rtx ele = XVECEXP (pat, 0, i);
1033 if (GET_CODE (ele) != SET)
1034 continue;
1035 dest = SET_DEST (ele);
1037 /* Process each member of the PARALLEL independently. The first
1038 member is always processed; others only if they are marked. */
1039 if (i == 0 || RTX_FRAME_RELATED_P (ele))
1041 /* Evaluate all register saves in the first pass and all
1042 register updates in the second pass. */
1043 if ((MEM_P (dest) ^ pass) || npass == 1)
1044 seh_frame_related_expr (f, seh, ele);
1047 return;
1050 dest = SET_DEST (pat);
1051 src = SET_SRC (pat);
1053 switch (GET_CODE (dest))
1055 case REG:
1056 switch (GET_CODE (src))
1058 case REG:
1059 /* REG = REG: This should be establishing a frame pointer. */
1060 gcc_assert (src == stack_pointer_rtx);
1061 gcc_assert (dest == hard_frame_pointer_rtx);
1062 seh_cfa_adjust_cfa (f, seh, pat);
1063 break;
1065 case PLUS:
1066 addend = INTVAL (XEXP (src, 1));
1067 src = XEXP (src, 0);
1068 if (dest == hard_frame_pointer_rtx)
1069 seh_cfa_adjust_cfa (f, seh, pat);
1070 else if (dest == stack_pointer_rtx)
1072 gcc_assert (src == stack_pointer_rtx);
1073 seh_emit_stackalloc (f, seh, addend);
1075 else
1076 gcc_unreachable ();
1077 break;
1079 default:
1080 gcc_unreachable ();
1082 break;
1084 case MEM:
1085 /* A save of some kind. */
1086 dest = XEXP (dest, 0);
1087 if (GET_CODE (dest) == PRE_DEC)
1089 gcc_checking_assert (GET_MODE (src) == Pmode);
1090 gcc_checking_assert (REG_P (src));
1091 seh_emit_push (f, seh, src);
1093 else
1094 seh_cfa_offset (f, seh, pat);
1095 break;
1097 default:
1098 gcc_unreachable ();
1102 /* This function looks at a single insn and emits any SEH directives
1103 required for unwind of this insn. */
1105 void
1106 i386_pe_seh_unwind_emit (FILE *asm_out_file, rtx_insn *insn)
1108 rtx note, pat;
1109 bool handled_one = false;
1110 struct seh_frame_state *seh;
1112 if (!TARGET_SEH)
1113 return;
1115 /* We free the SEH data once done with the prologue. Ignore those
1116 RTX_FRAME_RELATED_P insns that are associated with the epilogue. */
1117 seh = cfun->machine->seh;
1118 if (seh == NULL)
1119 return;
1121 if (NOTE_P (insn) || !RTX_FRAME_RELATED_P (insn))
1122 return;
1124 for (note = REG_NOTES (insn); note ; note = XEXP (note, 1))
1126 switch (REG_NOTE_KIND (note))
1128 case REG_FRAME_RELATED_EXPR:
1129 pat = XEXP (note, 0);
1130 goto found;
1132 case REG_CFA_DEF_CFA:
1133 case REG_CFA_EXPRESSION:
1134 /* Only emitted with DRAP and aligned memory access using a
1135 realigned SP, both of which we disable. */
1136 gcc_unreachable ();
1137 break;
1139 case REG_CFA_REGISTER:
1140 /* Only emitted in epilogues, which we skip. */
1141 gcc_unreachable ();
1143 case REG_CFA_ADJUST_CFA:
1144 pat = XEXP (note, 0);
1145 if (pat == NULL)
1147 pat = PATTERN (insn);
1148 if (GET_CODE (pat) == PARALLEL)
1149 pat = XVECEXP (pat, 0, 0);
1151 seh_cfa_adjust_cfa (asm_out_file, seh, pat);
1152 handled_one = true;
1153 break;
1155 case REG_CFA_OFFSET:
1156 pat = XEXP (note, 0);
1157 if (pat == NULL)
1158 pat = single_set (insn);
1159 seh_cfa_offset (asm_out_file, seh, pat);
1160 handled_one = true;
1161 break;
1163 default:
1164 break;
1167 if (handled_one)
1168 return;
1169 pat = PATTERN (insn);
1170 found:
1171 seh_frame_related_expr (asm_out_file, seh, pat);
1174 void
1175 i386_pe_seh_emit_except_personality (rtx personality)
1177 int flags = 0;
1179 if (!TARGET_SEH)
1180 return;
1182 fputs ("\t.seh_handler\t", asm_out_file);
1183 output_addr_const (asm_out_file, personality);
1185 #if 0
1186 /* ??? The current implementation of _GCC_specific_handler requires
1187 both except and unwind handling, regardless of which sorts the
1188 user-level function requires. */
1189 eh_region r;
1190 FOR_ALL_EH_REGION(r)
1192 if (r->type == ERT_CLEANUP)
1193 flags |= 1;
1194 else
1195 flags |= 2;
1197 #else
1198 flags = 3;
1199 #endif
1201 if (flags & 1)
1202 fputs (", @unwind", asm_out_file);
1203 if (flags & 2)
1204 fputs (", @except", asm_out_file);
1205 fputc ('\n', asm_out_file);
1208 void
1209 i386_pe_seh_init_sections (void)
1211 if (TARGET_SEH)
1212 exception_section = get_unnamed_section (0, output_section_asm_op,
1213 "\t.seh_handlerdata");
1216 void
1217 i386_pe_start_function (FILE *f, const char *name, tree decl)
1219 i386_pe_maybe_record_exported_symbol (decl, name, 0);
1220 i386_pe_declare_function_type (f, name, TREE_PUBLIC (decl));
1221 /* In case section was altered by debugging output. */
1222 if (decl != NULL_TREE)
1223 switch_to_section (function_section (decl));
1224 ASM_OUTPUT_FUNCTION_LABEL (f, name, decl);
1227 void
1228 i386_pe_end_function (FILE *f, const char *, tree)
1230 i386_pe_seh_fini (f);
1234 #include "gt-winnt.h"