1 /* Subroutines for insn-output.c for Windows NT.
2 Contributed by Douglas Rupp (drupp@cs.washington.edu)
3 Copyright (C) 1995-2015 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
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
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/>. */
23 #include "coretypes.h"
27 #include "hard-reg-set.h"
32 #include "double-int.h"
39 #include "fold-const.h"
40 #include "stringpool.h"
44 #include "diagnostic-core.h"
45 #include "hash-table.h"
46 #include "langhooks.h"
50 #include "hash-table.h"
55 #include "dominance.h"
61 #include "cfgcleanup.h"
62 #include "basic-block.h"
63 #include "tree-ssa-alias.h"
64 #include "internal-fn.h"
65 #include "gimple-fold.h"
67 #include "gimple-expr.h"
71 #include "plugin-api.h"
74 #include "lto-streamer.h"
75 #include "lto-section-names.h"
78 /* i386/PE specific attribute support.
80 i386/PE has two new attributes:
81 dllexport - for exporting a function/variable that will live in a dll
82 dllimport - for importing a function/variable from a dll
84 Microsoft allows multiple declspecs in one __declspec, separating
85 them with spaces. We do NOT support this. Instead, use __declspec
89 /* Handle a "shared" attribute;
90 arguments as in struct attribute_spec.handler. */
92 ix86_handle_shared_attribute (tree
*node
, tree name
, tree
, int,
95 if (TREE_CODE (*node
) != VAR_DECL
)
97 warning (OPT_Wattributes
, "%qE attribute only applies to variables",
105 /* Handle a "selectany" attribute;
106 arguments as in struct attribute_spec.handler. */
108 ix86_handle_selectany_attribute (tree
*node
, tree name
, tree
, int,
111 /* The attribute applies only to objects that are initialized and have
112 external linkage. However, we may not know about initialization
113 until the language frontend has processed the decl. We'll check for
114 initialization later in encode_section_info. */
115 if (TREE_CODE (*node
) != VAR_DECL
|| !TREE_PUBLIC (*node
))
117 error ("%qE attribute applies only to initialized variables"
118 " with external linkage", name
);
119 *no_add_attrs
= true;
126 /* Return the type that we should use to determine if DECL is
127 imported or exported. */
130 associated_type (tree decl
)
132 return (DECL_CONTEXT (decl
) && TYPE_P (DECL_CONTEXT (decl
))
133 ? DECL_CONTEXT (decl
) : NULL_TREE
);
136 /* Return true if DECL should be a dllexport'd object. */
139 i386_pe_determine_dllexport_p (tree decl
)
141 if (TREE_CODE (decl
) != VAR_DECL
&& TREE_CODE (decl
) != FUNCTION_DECL
)
144 /* Don't export local clones of dllexports. */
145 if (!TREE_PUBLIC (decl
))
148 if (TREE_CODE (decl
) == FUNCTION_DECL
149 && DECL_DECLARED_INLINE_P (decl
)
150 && !flag_keep_inline_dllexport
)
153 if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl
)))
159 /* Return true if DECL should be a dllimport'd object. */
162 i386_pe_determine_dllimport_p (tree decl
)
166 if (TREE_CODE (decl
) != VAR_DECL
&& TREE_CODE (decl
) != FUNCTION_DECL
)
169 if (DECL_DLLIMPORT_P (decl
))
172 /* The DECL_DLLIMPORT_P flag was set for decls in the class definition
173 by targetm.cxx.adjust_class_at_definition. Check again to emit
174 error message if the class attribute has been overridden by an
175 out-of-class definition of static data. */
176 assoc
= associated_type (decl
);
177 if (assoc
&& lookup_attribute ("dllimport", TYPE_ATTRIBUTES (assoc
))
178 && TREE_CODE (decl
) == VAR_DECL
179 && TREE_STATIC (decl
) && TREE_PUBLIC (decl
)
180 && !DECL_EXTERNAL (decl
)
181 /* vtable's are linkonce constants, so defining a vtable is not
182 an error as long as we don't try to import it too. */
183 && !DECL_VIRTUAL_P (decl
))
184 error ("definition of static data member %q+D of "
185 "dllimport%'d class", decl
);
190 /* Handle the -mno-fun-dllimport target switch. */
193 i386_pe_valid_dllimport_attribute_p (const_tree decl
)
195 if (TARGET_NOP_FUN_DLLIMPORT
&& TREE_CODE (decl
) == FUNCTION_DECL
)
200 /* Return string which is the function name, identified by ID, modified
201 with a suffix consisting of an atsign (@) followed by the number of
202 bytes of arguments. If ID is NULL use the DECL_NAME as base. If
203 FASTCALL is true, also add the FASTCALL_PREFIX.
204 Return NULL if no change required. */
207 gen_stdcall_or_fastcall_suffix (tree decl
, tree id
, bool fastcall
)
209 HOST_WIDE_INT total
= 0;
210 const char *old_str
= IDENTIFIER_POINTER (id
!= NULL_TREE
? id
: DECL_NAME (decl
));
212 tree type
= TREE_TYPE (DECL_ORIGIN (decl
));
214 function_args_iterator args_iter
;
216 gcc_assert (TREE_CODE (decl
) == FUNCTION_DECL
);
218 if (prototype_p (type
))
220 /* This attribute is ignored for variadic functions. */
224 /* Quit if we hit an incomplete type. Error is reported
225 by convert_arguments in c-typeck.c or cp/typeck.c. */
226 FOREACH_FUNCTION_ARGS(type
, arg
, args_iter
)
228 HOST_WIDE_INT parm_size
;
229 HOST_WIDE_INT parm_boundary_bytes
= PARM_BOUNDARY
/ BITS_PER_UNIT
;
231 if (! COMPLETE_TYPE_P (arg
))
234 parm_size
= int_size_in_bytes (arg
);
238 /* Must round up to include padding. This is done the same
239 way as in store_one_arg. */
240 parm_size
= ((parm_size
+ parm_boundary_bytes
- 1)
241 / parm_boundary_bytes
* parm_boundary_bytes
);
246 /* Assume max of 8 base 10 digits in the suffix. */
247 p
= new_str
= XALLOCAVEC (char, 1 + strlen (old_str
) + 1 + 8 + 1);
249 *p
++ = FASTCALL_PREFIX
;
250 sprintf (p
, "%s@" HOST_WIDE_INT_PRINT_DEC
, old_str
, total
);
252 return get_identifier (new_str
);
255 /* Maybe decorate and get a new identifier for the DECL of a stdcall or
256 fastcall function. The original identifier is supplied in ID. */
259 i386_pe_maybe_mangle_decl_assembler_name (tree decl
, tree id
)
261 tree new_id
= NULL_TREE
;
263 if (TREE_CODE (decl
) == FUNCTION_DECL
)
265 unsigned int ccvt
= ix86_get_callcvt (TREE_TYPE (decl
));
266 if ((ccvt
& IX86_CALLCVT_STDCALL
) != 0)
269 /* If we are using -mrtd emit undecorated symbol and let linker
270 do the proper resolving. */
272 new_id
= gen_stdcall_or_fastcall_suffix (decl
, id
, false);
274 else if ((ccvt
& IX86_CALLCVT_FASTCALL
) != 0)
275 new_id
= gen_stdcall_or_fastcall_suffix (decl
, id
, true);
281 /* Emit an assembler directive to set symbol for DECL visibility to
282 the visibility type VIS, which must not be VISIBILITY_DEFAULT.
283 As for PE there is no hidden support in gas, we just warn for
284 user-specified visibility attributes. */
287 i386_pe_assemble_visibility (tree decl
, int)
290 || !lookup_attribute ("visibility", DECL_ATTRIBUTES (decl
)))
292 if (!DECL_ARTIFICIAL (decl
))
293 warning (OPT_Wattributes
, "visibility attribute not supported "
294 "in this configuration; ignored");
297 /* This is used as a target hook to modify the DECL_ASSEMBLER_NAME
298 in the language-independent default hook
299 langhooks,c:lhd_set_decl_assembler_name ()
300 and in cp/mangle,c:mangle_decl (). */
302 i386_pe_mangle_decl_assembler_name (tree decl
, tree id
)
304 tree new_id
= i386_pe_maybe_mangle_decl_assembler_name (decl
, id
);
306 return (new_id
? new_id
: id
);
309 /* This hook behaves the same as varasm.c/assemble_name(), but
310 generates the name into memory rather than outputting it to
314 i386_pe_mangle_assembler_name (const char *name
)
316 const char *skipped
= name
+ (*name
== '*' ? 1 : 0);
317 const char *stripped
= targetm
.strip_name_encoding (skipped
);
318 if (*name
!= '*' && *user_label_prefix
&& *stripped
!= FASTCALL_PREFIX
)
319 stripped
= ACONCAT ((user_label_prefix
, stripped
, NULL
));
320 return get_identifier (stripped
);
324 i386_pe_encode_section_info (tree decl
, rtx rtl
, int first
)
329 /* Do this last, due to our frobbing of DECL_DLLIMPORT_P above. */
330 default_encode_section_info (decl
, rtl
, first
);
332 /* Careful not to prod global register variables. */
336 symbol
= XEXP (rtl
, 0);
337 gcc_assert (GET_CODE (symbol
) == SYMBOL_REF
);
339 switch (TREE_CODE (decl
))
342 /* FIXME: Imported stdcall names are not modified by the Ada frontend.
343 Check and decorate the RTL name now. */
344 if (strcmp (lang_hooks
.name
, "GNU Ada") == 0)
347 tree old_id
= DECL_ASSEMBLER_NAME (decl
);
348 const char* asm_str
= IDENTIFIER_POINTER (old_id
);
349 /* Do not change the identifier if a verbatim asmspec
350 or if stdcall suffix already added. */
351 if (!(*asm_str
== '*' || strchr (asm_str
, '@'))
352 && (new_id
= i386_pe_maybe_mangle_decl_assembler_name (decl
,
354 XSTR (symbol
, 0) = IDENTIFIER_POINTER (new_id
);
359 if (lookup_attribute ("selectany", DECL_ATTRIBUTES (decl
)))
361 if (DECL_INITIAL (decl
)
362 /* If an object is initialized with a ctor, the static
363 initialization and destruction code for it is present in
364 each unit defining the object. The code that calls the
365 ctor is protected by a link-once guard variable, so that
366 the object still has link-once semantics, */
367 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl
)))
368 make_decl_one_only (decl
, DECL_ASSEMBLER_NAME (decl
));
370 error ("%q+D:'selectany' attribute applies only to "
371 "initialized objects", decl
);
379 /* Mark the decl so we can tell from the rtl whether the object is
380 dllexport'd or dllimport'd. tree.c: merge_dllimport_decl_attributes
381 handles dllexport/dllimport override semantics. */
382 flags
= (SYMBOL_REF_FLAGS (symbol
) &
383 ~(SYMBOL_FLAG_DLLIMPORT
| SYMBOL_FLAG_DLLEXPORT
));
384 if (i386_pe_determine_dllexport_p (decl
))
385 flags
|= SYMBOL_FLAG_DLLEXPORT
;
386 else if (i386_pe_determine_dllimport_p (decl
))
387 flags
|= SYMBOL_FLAG_DLLIMPORT
;
389 SYMBOL_REF_FLAGS (symbol
) = flags
;
394 i386_pe_binds_local_p (const_tree exp
)
396 if ((TREE_CODE (exp
) == VAR_DECL
|| TREE_CODE (exp
) == FUNCTION_DECL
)
397 && DECL_DLLIMPORT_P (exp
))
400 /* External public symbols, which aren't weakref-s,
401 have local-binding for PE targets. */
403 && !lookup_attribute ("weakref", DECL_ATTRIBUTES (exp
))
405 && DECL_EXTERNAL (exp
))
407 return default_binds_local_p_1 (exp
, 0);
410 /* Also strip the fastcall prefix and stdcall suffix. */
413 i386_pe_strip_name_encoding_full (const char *str
)
416 const char *name
= default_strip_name_encoding (str
);
418 /* Strip leading '@' on fastcall symbols. */
422 /* Strip trailing "@n". */
423 p
= strchr (name
, '@');
425 return ggc_alloc_string (name
, p
- name
);
431 i386_pe_unique_section (tree decl
, int reloc
)
434 const char *name
, *prefix
;
437 /* Ignore RELOC, if we are allowed to put relocated
438 const data into read-only section. */
439 if (!flag_writable_rel_rdata
)
441 name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
442 name
= i386_pe_strip_name_encoding_full (name
);
444 /* The object is put in, for example, section .text$foo.
445 The linker will then ultimately place them in .text
446 (everything from the $ on is stripped). Don't put
447 read-only data in .rdata section to avoid a PE linker
448 bug when .rdata$* grouped sections are used in code
449 without a .rdata section. */
450 if (TREE_CODE (decl
) == FUNCTION_DECL
)
452 else if (decl_readonly_section (decl
, reloc
))
456 len
= strlen (name
) + strlen (prefix
);
457 string
= XALLOCAVEC (char, len
+ 1);
458 sprintf (string
, "%s%s", prefix
, name
);
460 set_decl_section_name (decl
, string
);
463 /* Local and global relocs can be placed always into readonly memory for
464 memory for PE-COFF targets. */
466 i386_pe_reloc_rw_mask (void)
471 /* Select a set of attributes for section NAME based on the properties
472 of DECL and whether or not RELOC indicates that DECL's initializer
473 might contain runtime relocations.
475 We make the section read-only and executable for a function decl,
476 read-only for a const data decl, and writable for a non-const data decl.
478 If the section has already been defined, to not allow it to have
479 different attributes, as (1) this is ambiguous since we're not seeing
480 all the declarations up front and (2) some assemblers (e.g. SVR4)
481 do not recognize section redefinitions. */
482 /* ??? This differs from the "standard" PE implementation in that we
483 handle the SHARED variable attribute. Should this be done for all
486 #define SECTION_PE_SHARED SECTION_MACH_DEP
489 i386_pe_section_type_flags (tree decl
, const char *, int reloc
)
493 /* Ignore RELOC, if we are allowed to put relocated
494 const data into read-only section. */
495 if (!flag_writable_rel_rdata
)
498 if (decl
&& TREE_CODE (decl
) == FUNCTION_DECL
)
499 flags
= SECTION_CODE
;
500 else if (decl
&& decl_readonly_section (decl
, reloc
))
504 flags
= SECTION_WRITE
;
506 if (decl
&& TREE_CODE (decl
) == VAR_DECL
507 && lookup_attribute ("shared", DECL_ATTRIBUTES (decl
)))
508 flags
|= SECTION_PE_SHARED
;
511 if (decl
&& DECL_P (decl
) && DECL_ONE_ONLY (decl
))
512 flags
|= SECTION_LINKONCE
;
518 i386_pe_asm_named_section (const char *name
, unsigned int flags
,
521 char flagchars
[8], *f
= flagchars
;
523 #if defined (HAVE_GAS_SECTION_EXCLUDE) && HAVE_GAS_SECTION_EXCLUDE == 1
524 if ((flags
& SECTION_EXCLUDE
) != 0)
528 if ((flags
& (SECTION_CODE
| SECTION_WRITE
)) == 0)
531 *f
++ ='d'; /* This is necessary for older versions of gas. */
536 if (flags
& SECTION_CODE
)
538 if (flags
& SECTION_WRITE
)
540 if (flags
& SECTION_PE_SHARED
)
542 #if !defined (HAVE_GAS_SECTION_EXCLUDE) || HAVE_GAS_SECTION_EXCLUDE == 0
543 /* If attribute "e" isn't supported we mark this section as
545 if ((flags
& SECTION_EXCLUDE
) != 0)
550 /* LTO sections need 1-byte alignment to avoid confusing the
551 zlib decompression algorithm with trailing zero pad bytes. */
552 if (strncmp (name
, LTO_SECTION_NAME_PREFIX
,
553 strlen (LTO_SECTION_NAME_PREFIX
)) == 0)
558 fprintf (asm_out_file
, "\t.section\t%s,\"%s\"\n", name
, flagchars
);
560 if (flags
& SECTION_LINKONCE
)
562 /* Functions may have been compiled at various levels of
563 optimization so we can't use `same_size' here.
564 Instead, have the linker pick one, without warning.
565 If 'selectany' attribute has been specified, MS compiler
566 sets 'discard' characteristic, rather than telling linker
567 to warn of size or content mismatch, so do the same. */
568 bool discard
= (flags
& SECTION_CODE
)
569 || (TREE_CODE (decl
) != IDENTIFIER_NODE
570 && lookup_attribute ("selectany",
571 DECL_ATTRIBUTES (decl
)));
572 fprintf (asm_out_file
, "\t.linkonce %s\n",
573 (discard
? "discard" : "same_size"));
577 /* Beware, DECL may be NULL if compile_file() is emitting the LTO marker. */
580 i386_pe_asm_output_aligned_decl_common (FILE *stream
, tree decl
,
581 const char *name
, HOST_WIDE_INT size
,
584 HOST_WIDE_INT rounded
;
586 /* Compute as in assemble_noswitch_variable, since we don't have
587 support for aligned common on older binutils. We must also
588 avoid emitting a common symbol of size zero, as this is the
589 overloaded representation that indicates an undefined external
590 symbol in the PE object file format. */
591 rounded
= size
? size
: 1;
592 rounded
+= (BIGGEST_ALIGNMENT
/ BITS_PER_UNIT
) - 1;
593 rounded
= (rounded
/ (BIGGEST_ALIGNMENT
/ BITS_PER_UNIT
)
594 * (BIGGEST_ALIGNMENT
/ BITS_PER_UNIT
));
596 i386_pe_maybe_record_exported_symbol (decl
, name
, 1);
598 fprintf (stream
, "\t.comm\t");
599 assemble_name (stream
, name
);
600 if (use_pe_aligned_common
)
601 fprintf (stream
, ", " HOST_WIDE_INT_PRINT_DEC
", %d\n",
602 size
? size
: HOST_WIDE_INT_1
,
603 exact_log2 (align
) - exact_log2 (CHAR_BIT
));
605 fprintf (stream
, ", " HOST_WIDE_INT_PRINT_DEC
"\t" ASM_COMMENT_START
606 " " HOST_WIDE_INT_PRINT_DEC
"\n", rounded
, size
);
609 /* The Microsoft linker requires that every function be marked as
610 DT_FCN. When using gas on cygwin, we must emit appropriate .type
615 /* Mark a function appropriately. This should only be called for
616 functions for which we are not emitting COFF debugging information.
617 FILE is the assembler output file, NAME is the name of the
618 function, and PUB is nonzero if the function is globally
622 i386_pe_declare_function_type (FILE *file
, const char *name
, int pub
)
624 fprintf (file
, "\t.def\t");
625 assemble_name (file
, name
);
626 fprintf (file
, ";\t.scl\t%d;\t.type\t%d;\t.endef\n",
627 pub
? (int) C_EXT
: (int) C_STAT
,
628 (int) DT_FCN
<< N_BTSHFT
);
631 /* Keep a list of external functions. */
633 struct GTY(()) extern_list
635 struct extern_list
*next
;
640 static GTY(()) struct extern_list
*extern_head
;
642 /* Assemble an external function reference. We need to keep a list of
643 these, so that we can output the function types at the end of the
644 assembly. We can't output the types now, because we might see a
645 definition of the function later on and emit debugging information
649 i386_pe_record_external_function (tree decl
, const char *name
)
651 struct extern_list
*p
;
653 p
= ggc_alloc
<extern_list
> ();
654 p
->next
= extern_head
;
660 /* Keep a list of exported symbols. */
662 struct GTY(()) export_list
664 struct export_list
*next
;
666 int is_data
; /* used to type tag exported symbols. */
669 /* Keep a list of stub symbols. */
671 struct GTY(()) stub_list
673 struct stub_list
*next
;
677 static GTY(()) struct export_list
*export_head
;
679 static GTY(()) struct stub_list
*stub_head
;
681 /* Assemble an export symbol entry. We need to keep a list of
682 these, so that we can output the export list at the end of the
683 assembly. We used to output these export symbols in each function,
684 but that causes problems with GNU ld when the sections are
685 linkonce. Beware, DECL may be NULL if compile_file() is emitting
689 i386_pe_maybe_record_exported_symbol (tree decl
, const char *name
, int is_data
)
692 struct export_list
*p
;
697 symbol
= XEXP (DECL_RTL (decl
), 0);
698 gcc_assert (GET_CODE (symbol
) == SYMBOL_REF
);
699 if (!SYMBOL_REF_DLLEXPORT_P (symbol
))
702 gcc_assert (TREE_PUBLIC (decl
));
704 p
= ggc_alloc
<export_list
> ();
705 p
->next
= export_head
;
707 p
->is_data
= is_data
;
712 i386_pe_record_stub (const char *name
)
716 if (!name
|| *name
== 0)
722 if (p
->name
[0] == *name
723 && !strcmp (p
->name
, name
))
728 p
= ggc_alloc
<stub_list
> ();
735 #ifdef CXX_WRAP_SPEC_LIST
737 /* Hashtable helpers. */
739 struct wrapped_symbol_hasher
: typed_noop_remove
<char>
741 typedef char *value_type
;
742 typedef char *compare_type
;
743 static inline hashval_t
hash (const char *);
744 static inline bool equal (const char *, const char *);
745 static inline void remove (char *);
749 wrapped_symbol_hasher::hash (const char *v
)
751 return htab_hash_string (v
);
754 /* Hash table equality helper function. */
757 wrapped_symbol_hasher::equal (const char *x
, const char *y
)
759 return !strcmp (x
, y
);
762 /* Search for a function named TARGET in the list of library wrappers
763 we are using, returning a pointer to it if found or NULL if not.
764 This function might be called on quite a few symbols, and we only
765 have the list of names of wrapped functions available to us as a
766 spec string, so first time round we lazily initialise a hash table
767 to make things quicker. */
770 i386_find_on_wrapper_list (const char *target
)
772 static char first_time
= 1;
773 static hash_table
<wrapped_symbol_hasher
> *wrappers
;
777 /* Beware that this is not a complicated parser, it assumes
778 that any sequence of non-whitespace beginning with an
779 underscore is one of the wrapped symbols. For now that's
780 adequate to distinguish symbols from spec substitutions
781 and command-line options. */
782 static char wrapper_list_buffer
[] = CXX_WRAP_SPEC_LIST
;
784 /* Breaks up the char array into separated strings
785 strings and enter them into the hash table. */
786 wrappers
= new hash_table
<wrapped_symbol_hasher
> (8);
787 for (bufptr
= wrapper_list_buffer
; *bufptr
; ++bufptr
)
790 if (ISSPACE (*bufptr
))
794 while (*bufptr
&& !ISSPACE (*bufptr
))
799 *wrappers
->find_slot (found
, INSERT
) = found
;
804 return wrappers
->find (target
);
807 #endif /* CXX_WRAP_SPEC_LIST */
809 /* This is called at the end of assembly. For each external function
810 which has not been defined, we output a declaration now. We also
811 output the .drectve section. */
814 i386_pe_file_end (void)
816 struct extern_list
*p
;
818 for (p
= extern_head
; p
!= NULL
; p
= p
->next
)
824 /* Positively ensure only one declaration for any given symbol. */
825 if (! TREE_ASM_WRITTEN (decl
)
826 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl
)))
828 #ifdef CXX_WRAP_SPEC_LIST
829 /* To ensure the DLL that provides the corresponding real
830 functions is still loaded at runtime, we must reference
831 the real function so that an (unused) import is created. */
832 const char *realsym
= i386_find_on_wrapper_list (p
->name
);
834 i386_pe_declare_function_type (asm_out_file
,
835 concat ("__real_", realsym
, NULL
), TREE_PUBLIC (decl
));
836 #endif /* CXX_WRAP_SPEC_LIST */
837 TREE_ASM_WRITTEN (decl
) = 1;
838 i386_pe_declare_function_type (asm_out_file
, p
->name
,
845 struct export_list
*q
;
847 for (q
= export_head
; q
!= NULL
; q
= q
->next
)
849 fprintf (asm_out_file
, "\t.ascii \" -export:\\\"%s\\\"%s\"\n",
850 default_strip_name_encoding (q
->name
),
851 (q
->is_data
? ",data" : ""));
859 for (q
= stub_head
; q
!= NULL
; q
= q
->next
)
861 const char *name
= q
->name
;
869 if (strncmp (name
, "refptr.", 7) != 0)
872 fprintf (asm_out_file
, "\t.section\t.rdata$%s, \"dr\"\n"
874 "\t.linkonce\tdiscard\n", oname
, oname
);
875 fprintf (asm_out_file
, "%s:\n\t.quad\t%s\n", oname
, name
);
881 /* x64 Structured Exception Handling unwind info. */
883 struct seh_frame_state
885 /* SEH records saves relative to the "current" stack pointer, whether
886 or not there's a frame pointer in place. This tracks the current
887 stack pointer offset from the CFA. */
888 HOST_WIDE_INT sp_offset
;
890 /* The CFA is located at CFA_REG + CFA_OFFSET. */
891 HOST_WIDE_INT cfa_offset
;
895 /* Set up data structures beginning output for SEH. */
898 i386_pe_seh_init (FILE *f
)
900 struct seh_frame_state
*seh
;
907 /* We cannot support DRAP with SEH. We turned off support for it by
908 re-defining MAX_STACK_ALIGNMENT when SEH is enabled. */
909 gcc_assert (!stack_realign_drap
);
911 seh
= XCNEW (struct seh_frame_state
);
912 cfun
->machine
->seh
= seh
;
914 seh
->sp_offset
= INCOMING_FRAME_SP_OFFSET
;
915 seh
->cfa_offset
= INCOMING_FRAME_SP_OFFSET
;
916 seh
->cfa_reg
= stack_pointer_rtx
;
918 fputs ("\t.seh_proc\t", f
);
919 assemble_name (f
, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (cfun
->decl
)));
924 i386_pe_seh_end_prologue (FILE *f
)
926 struct seh_frame_state
*seh
;
932 seh
= cfun
->machine
->seh
;
935 cfun
->machine
->seh
= NULL
;
937 fputs ("\t.seh_endprologue\n", f
);
941 i386_pe_seh_fini (FILE *f
)
947 fputs ("\t.seh_endproc\n", f
);
950 /* Emit an assembler directive to save REG via a PUSH. */
953 seh_emit_push (FILE *f
, struct seh_frame_state
*seh
, rtx reg
)
955 unsigned int regno
= REGNO (reg
);
957 gcc_checking_assert (GENERAL_REGNO_P (regno
));
959 seh
->sp_offset
+= UNITS_PER_WORD
;
960 if (seh
->cfa_reg
== stack_pointer_rtx
)
961 seh
->cfa_offset
+= UNITS_PER_WORD
;
963 fputs ("\t.seh_pushreg\t", f
);
964 print_reg (reg
, 0, f
);
968 /* Emit an assembler directive to save REG at CFA - CFA_OFFSET. */
971 seh_emit_save (FILE *f
, struct seh_frame_state
*seh
,
972 rtx reg
, HOST_WIDE_INT cfa_offset
)
974 unsigned int regno
= REGNO (reg
);
975 HOST_WIDE_INT offset
;
977 /* Negative save offsets are of course not supported, since that
978 would be a store below the stack pointer and thus clobberable. */
979 gcc_assert (seh
->sp_offset
>= cfa_offset
);
980 offset
= seh
->sp_offset
- cfa_offset
;
982 fputs ((SSE_REGNO_P (regno
) ? "\t.seh_savexmm\t"
983 : GENERAL_REGNO_P (regno
) ? "\t.seh_savereg\t"
984 : (gcc_unreachable (), "")), f
);
985 print_reg (reg
, 0, f
);
986 fprintf (f
, ", " HOST_WIDE_INT_PRINT_DEC
"\n", offset
);
989 /* Emit an assembler directive to adjust RSP by OFFSET. */
992 seh_emit_stackalloc (FILE *f
, struct seh_frame_state
*seh
,
993 HOST_WIDE_INT offset
)
995 /* We're only concerned with prologue stack allocations, which all
996 are subtractions from the stack pointer. */
997 gcc_assert (offset
< 0);
1000 if (seh
->cfa_reg
== stack_pointer_rtx
)
1001 seh
->cfa_offset
+= offset
;
1002 seh
->sp_offset
+= offset
;
1004 /* Do not output the stackalloc in that case (it won't work as there is no
1005 encoding for very large frame size). */
1006 if (offset
< SEH_MAX_FRAME_SIZE
)
1007 fprintf (f
, "\t.seh_stackalloc\t" HOST_WIDE_INT_PRINT_DEC
"\n", offset
);
1010 /* Process REG_CFA_ADJUST_CFA for SEH. */
1013 seh_cfa_adjust_cfa (FILE *f
, struct seh_frame_state
*seh
, rtx pat
)
1016 HOST_WIDE_INT reg_offset
= 0;
1017 unsigned int dest_regno
;
1019 dest
= SET_DEST (pat
);
1020 src
= SET_SRC (pat
);
1022 if (GET_CODE (src
) == PLUS
)
1024 reg_offset
= INTVAL (XEXP (src
, 1));
1025 src
= XEXP (src
, 0);
1027 else if (GET_CODE (src
) == MINUS
)
1029 reg_offset
= -INTVAL (XEXP (src
, 1));
1030 src
= XEXP (src
, 0);
1032 gcc_assert (src
== stack_pointer_rtx
);
1033 gcc_assert (seh
->cfa_reg
== stack_pointer_rtx
);
1034 dest_regno
= REGNO (dest
);
1036 if (dest_regno
== STACK_POINTER_REGNUM
)
1037 seh_emit_stackalloc (f
, seh
, reg_offset
);
1038 else if (dest_regno
== HARD_FRAME_POINTER_REGNUM
)
1040 HOST_WIDE_INT offset
;
1042 seh
->cfa_reg
= dest
;
1043 seh
->cfa_offset
-= reg_offset
;
1045 offset
= seh
->sp_offset
- seh
->cfa_offset
;
1047 gcc_assert ((offset
& 15) == 0);
1048 gcc_assert (IN_RANGE (offset
, 0, 240));
1050 fputs ("\t.seh_setframe\t", f
);
1051 print_reg (seh
->cfa_reg
, 0, f
);
1052 fprintf (f
, ", " HOST_WIDE_INT_PRINT_DEC
"\n", offset
);
1058 /* Process REG_CFA_OFFSET for SEH. */
1061 seh_cfa_offset (FILE *f
, struct seh_frame_state
*seh
, rtx pat
)
1064 HOST_WIDE_INT reg_offset
;
1066 dest
= SET_DEST (pat
);
1067 src
= SET_SRC (pat
);
1069 gcc_assert (MEM_P (dest
));
1070 dest
= XEXP (dest
, 0);
1075 gcc_assert (GET_CODE (dest
) == PLUS
);
1076 reg_offset
= INTVAL (XEXP (dest
, 1));
1077 dest
= XEXP (dest
, 0);
1079 gcc_assert (dest
== seh
->cfa_reg
);
1081 seh_emit_save (f
, seh
, src
, seh
->cfa_offset
- reg_offset
);
1084 /* Process a FRAME_RELATED_EXPR for SEH. */
1087 seh_frame_related_expr (FILE *f
, struct seh_frame_state
*seh
, rtx pat
)
1090 HOST_WIDE_INT addend
;
1092 /* See the full loop in dwarf2out_frame_debug_expr. */
1093 if (GET_CODE (pat
) == PARALLEL
|| GET_CODE (pat
) == SEQUENCE
)
1095 int i
, n
= XVECLEN (pat
, 0), pass
, npass
;
1097 npass
= (GET_CODE (pat
) == PARALLEL
? 2 : 1);
1098 for (pass
= 0; pass
< npass
; ++pass
)
1099 for (i
= 0; i
< n
; ++i
)
1101 rtx ele
= XVECEXP (pat
, 0, i
);
1103 if (GET_CODE (ele
) != SET
)
1105 dest
= SET_DEST (ele
);
1107 /* Process each member of the PARALLEL independently. The first
1108 member is always processed; others only if they are marked. */
1109 if (i
== 0 || RTX_FRAME_RELATED_P (ele
))
1111 /* Evaluate all register saves in the first pass and all
1112 register updates in the second pass. */
1113 if ((MEM_P (dest
) ^ pass
) || npass
== 1)
1114 seh_frame_related_expr (f
, seh
, ele
);
1120 dest
= SET_DEST (pat
);
1121 src
= SET_SRC (pat
);
1123 switch (GET_CODE (dest
))
1126 switch (GET_CODE (src
))
1129 /* REG = REG: This should be establishing a frame pointer. */
1130 gcc_assert (src
== stack_pointer_rtx
);
1131 gcc_assert (dest
== hard_frame_pointer_rtx
);
1132 seh_cfa_adjust_cfa (f
, seh
, pat
);
1136 addend
= INTVAL (XEXP (src
, 1));
1137 src
= XEXP (src
, 0);
1138 if (dest
== hard_frame_pointer_rtx
)
1139 seh_cfa_adjust_cfa (f
, seh
, pat
);
1140 else if (dest
== stack_pointer_rtx
)
1142 gcc_assert (src
== stack_pointer_rtx
);
1143 seh_emit_stackalloc (f
, seh
, addend
);
1155 /* A save of some kind. */
1156 dest
= XEXP (dest
, 0);
1157 if (GET_CODE (dest
) == PRE_DEC
)
1159 gcc_checking_assert (GET_MODE (src
) == Pmode
);
1160 gcc_checking_assert (REG_P (src
));
1161 seh_emit_push (f
, seh
, src
);
1164 seh_cfa_offset (f
, seh
, pat
);
1172 /* This function looks at a single insn and emits any SEH directives
1173 required for unwind of this insn. */
1176 i386_pe_seh_unwind_emit (FILE *asm_out_file
, rtx_insn
*insn
)
1179 bool handled_one
= false;
1180 struct seh_frame_state
*seh
;
1185 /* We free the SEH data once done with the prologue. Ignore those
1186 RTX_FRAME_RELATED_P insns that are associated with the epilogue. */
1187 seh
= cfun
->machine
->seh
;
1191 if (NOTE_P (insn
) || !RTX_FRAME_RELATED_P (insn
))
1194 for (note
= REG_NOTES (insn
); note
; note
= XEXP (note
, 1))
1196 switch (REG_NOTE_KIND (note
))
1198 case REG_FRAME_RELATED_EXPR
:
1199 pat
= XEXP (note
, 0);
1202 case REG_CFA_DEF_CFA
:
1203 case REG_CFA_EXPRESSION
:
1204 /* Only emitted with DRAP, which we disable. */
1208 case REG_CFA_REGISTER
:
1209 /* Only emitted in epilogues, which we skip. */
1212 case REG_CFA_ADJUST_CFA
:
1213 pat
= XEXP (note
, 0);
1216 pat
= PATTERN (insn
);
1217 if (GET_CODE (pat
) == PARALLEL
)
1218 pat
= XVECEXP (pat
, 0, 0);
1220 seh_cfa_adjust_cfa (asm_out_file
, seh
, pat
);
1224 case REG_CFA_OFFSET
:
1225 pat
= XEXP (note
, 0);
1227 pat
= single_set (insn
);
1228 seh_cfa_offset (asm_out_file
, seh
, pat
);
1238 pat
= PATTERN (insn
);
1240 seh_frame_related_expr (asm_out_file
, seh
, pat
);
1244 i386_pe_seh_emit_except_personality (rtx personality
)
1251 fputs ("\t.seh_handler\t", asm_out_file
);
1252 output_addr_const (asm_out_file
, personality
);
1255 /* ??? The current implementation of _GCC_specific_handler requires
1256 both except and unwind handling, regardless of which sorts the
1257 user-level function requires. */
1259 FOR_ALL_EH_REGION(r
)
1261 if (r
->type
== ERT_CLEANUP
)
1271 fputs (", @unwind", asm_out_file
);
1273 fputs (", @except", asm_out_file
);
1274 fputc ('\n', asm_out_file
);
1278 i386_pe_seh_init_sections (void)
1281 exception_section
= get_unnamed_section (0, output_section_asm_op
,
1282 "\t.seh_handlerdata");
1286 i386_pe_start_function (FILE *f
, const char *name
, tree decl
)
1288 i386_pe_maybe_record_exported_symbol (decl
, name
, 0);
1289 if (write_symbols
!= SDB_DEBUG
)
1290 i386_pe_declare_function_type (f
, name
, TREE_PUBLIC (decl
));
1291 /* In case section was altered by debugging output. */
1292 if (decl
!= NULL_TREE
)
1293 switch_to_section (function_section (decl
));
1294 ASM_OUTPUT_FUNCTION_LABEL (f
, name
, decl
);
1298 i386_pe_end_function (FILE *f
, const char *, tree
)
1300 i386_pe_seh_fini (f
);
1304 #include "gt-winnt.h"