1 /* Subroutines for insn-output.c for Windows NT.
2 Contributed by Douglas Rupp (drupp@cs.washington.edu)
3 Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
24 #include "coretypes.h"
28 #include "hard-reg-set.h"
33 #include "diagnostic-core.h"
35 #include "langhooks.h"
39 #include "lto-streamer.h"
41 /* i386/PE specific attribute support.
43 i386/PE has two new attributes:
44 dllexport - for exporting a function/variable that will live in a dll
45 dllimport - for importing a function/variable from a dll
47 Microsoft allows multiple declspecs in one __declspec, separating
48 them with spaces. We do NOT support this. Instead, use __declspec
52 /* Handle a "shared" attribute;
53 arguments as in struct attribute_spec.handler. */
55 ix86_handle_shared_attribute (tree
*node
, tree name
,
56 tree args ATTRIBUTE_UNUSED
,
57 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
59 if (TREE_CODE (*node
) != VAR_DECL
)
61 warning (OPT_Wattributes
, "%qE attribute only applies to variables",
69 /* Handle a "selectany" attribute;
70 arguments as in struct attribute_spec.handler. */
72 ix86_handle_selectany_attribute (tree
*node
, tree name
,
73 tree args ATTRIBUTE_UNUSED
,
74 int flags ATTRIBUTE_UNUSED
,
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. We'll check for
80 initialization later in encode_section_info. */
81 if (TREE_CODE (*node
) != VAR_DECL
|| !TREE_PUBLIC (*node
))
83 error ("%qE attribute applies only to initialized variables"
84 " with external linkage", name
);
92 /* Return the type that we should use to determine if DECL is
93 imported or exported. */
96 associated_type (tree decl
)
98 return (DECL_CONTEXT (decl
) && TYPE_P (DECL_CONTEXT (decl
))
99 ? DECL_CONTEXT (decl
) : NULL_TREE
);
102 /* Return true if DECL should be a dllexport'd object. */
105 i386_pe_determine_dllexport_p (tree decl
)
107 if (TREE_CODE (decl
) != VAR_DECL
&& TREE_CODE (decl
) != FUNCTION_DECL
)
110 /* Don't export local clones of dllexports. */
111 if (!TREE_PUBLIC (decl
))
114 if (lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl
)))
120 /* Return true if DECL should be a dllimport'd object. */
123 i386_pe_determine_dllimport_p (tree decl
)
127 if (TREE_CODE (decl
) != VAR_DECL
&& TREE_CODE (decl
) != FUNCTION_DECL
)
130 if (DECL_DLLIMPORT_P (decl
))
133 /* The DECL_DLLIMPORT_P flag was set for decls in the class definition
134 by targetm.cxx.adjust_class_at_definition. Check again to emit
135 error message if the class attribute has been overridden by an
136 out-of-class definition of static data. */
137 assoc
= associated_type (decl
);
138 if (assoc
&& lookup_attribute ("dllimport", TYPE_ATTRIBUTES (assoc
))
139 && TREE_CODE (decl
) == VAR_DECL
140 && TREE_STATIC (decl
) && TREE_PUBLIC (decl
)
141 && !DECL_EXTERNAL (decl
)
142 /* vtable's are linkonce constants, so defining a vtable is not
143 an error as long as we don't try to import it too. */
144 && !DECL_VIRTUAL_P (decl
))
145 error ("definition of static data member %q+D of "
146 "dllimport%'d class", decl
);
151 /* Handle the -mno-fun-dllimport target switch. */
154 i386_pe_valid_dllimport_attribute_p (const_tree decl
)
156 if (TARGET_NOP_FUN_DLLIMPORT
&& TREE_CODE (decl
) == FUNCTION_DECL
)
161 /* Return string which is the function name, identified by ID, modified
162 with a suffix consisting of an atsign (@) followed by the number of
163 bytes of arguments. If ID is NULL use the DECL_NAME as base. If
164 FASTCALL is true, also add the FASTCALL_PREFIX.
165 Return NULL if no change required. */
168 gen_stdcall_or_fastcall_suffix (tree decl
, tree id
, bool fastcall
)
170 HOST_WIDE_INT total
= 0;
171 const char *old_str
= IDENTIFIER_POINTER (id
!= NULL_TREE
? id
: DECL_NAME (decl
));
173 tree type
= TREE_TYPE (DECL_ORIGIN (decl
));
175 function_args_iterator args_iter
;
177 gcc_assert (TREE_CODE (decl
) == FUNCTION_DECL
);
179 if (prototype_p (type
))
181 /* This attribute is ignored for variadic functions. */
185 /* Quit if we hit an incomplete type. Error is reported
186 by convert_arguments in c-typeck.c or cp/typeck.c. */
187 FOREACH_FUNCTION_ARGS(type
, arg
, args_iter
)
189 HOST_WIDE_INT parm_size
;
190 HOST_WIDE_INT parm_boundary_bytes
= PARM_BOUNDARY
/ BITS_PER_UNIT
;
192 if (! COMPLETE_TYPE_P (arg
))
195 parm_size
= int_size_in_bytes (arg
);
199 /* Must round up to include padding. This is done the same
200 way as in store_one_arg. */
201 parm_size
= ((parm_size
+ parm_boundary_bytes
- 1)
202 / parm_boundary_bytes
* parm_boundary_bytes
);
207 /* Assume max of 8 base 10 digits in the suffix. */
208 p
= new_str
= XALLOCAVEC (char, 1 + strlen (old_str
) + 1 + 8 + 1);
210 *p
++ = FASTCALL_PREFIX
;
211 sprintf (p
, "%s@" HOST_WIDE_INT_PRINT_DEC
, old_str
, total
);
213 return get_identifier (new_str
);
216 /* Maybe decorate and get a new identifier for the DECL of a stdcall or
217 fastcall function. The original identifier is supplied in ID. */
220 i386_pe_maybe_mangle_decl_assembler_name (tree decl
, tree id
)
222 tree new_id
= NULL_TREE
;
224 if (TREE_CODE (decl
) == FUNCTION_DECL
)
226 unsigned int ccvt
= ix86_get_callcvt (TREE_TYPE (decl
));
227 if ((ccvt
& IX86_CALLCVT_STDCALL
) != 0)
230 /* If we are using -mrtd emit undecorated symbol and let linker
231 do the proper resolving. */
233 new_id
= gen_stdcall_or_fastcall_suffix (decl
, id
, false);
235 else if ((ccvt
& IX86_CALLCVT_FASTCALL
) != 0)
236 new_id
= gen_stdcall_or_fastcall_suffix (decl
, id
, true);
242 /* Emit an assembler directive to set symbol for DECL visibility to
243 the visibility type VIS, which must not be VISIBILITY_DEFAULT.
244 As for PE there is no hidden support in gas, we just warn for
245 user-specified visibility attributes. */
248 i386_pe_assemble_visibility (tree decl
,
249 int vis ATTRIBUTE_UNUSED
)
252 || !lookup_attribute ("visibility", DECL_ATTRIBUTES (decl
)))
254 warning (OPT_Wattributes
, "visibility attribute not supported "
255 "in this configuration; ignored");
258 /* This is used as a target hook to modify the DECL_ASSEMBLER_NAME
259 in the language-independent default hook
260 langhooks,c:lhd_set_decl_assembler_name ()
261 and in cp/mangle,c:mangle_decl (). */
263 i386_pe_mangle_decl_assembler_name (tree decl
, tree id
)
265 tree new_id
= i386_pe_maybe_mangle_decl_assembler_name (decl
, id
);
267 return (new_id
? new_id
: id
);
270 /* This hook behaves the same as varasm.c/assemble_name(), but
271 generates the name into memory rather than outputting it to
275 i386_pe_mangle_assembler_name (const char *name ATTRIBUTE_UNUSED
)
277 const char *skipped
= name
+ (*name
== '*' ? 1 : 0);
278 const char *stripped
= targetm
.strip_name_encoding (skipped
);
279 if (*name
!= '*' && *user_label_prefix
&& *stripped
!= FASTCALL_PREFIX
)
280 stripped
= ACONCAT ((user_label_prefix
, stripped
, NULL
));
281 return get_identifier (stripped
);
285 i386_pe_encode_section_info (tree decl
, rtx rtl
, int first
)
290 /* Do this last, due to our frobbing of DECL_DLLIMPORT_P above. */
291 default_encode_section_info (decl
, rtl
, first
);
293 /* Careful not to prod global register variables. */
297 symbol
= XEXP (rtl
, 0);
298 gcc_assert (GET_CODE (symbol
) == SYMBOL_REF
);
300 switch (TREE_CODE (decl
))
303 /* FIXME: Imported stdcall names are not modified by the Ada frontend.
304 Check and decorate the RTL name now. */
305 if (strcmp (lang_hooks
.name
, "GNU Ada") == 0)
308 tree old_id
= DECL_ASSEMBLER_NAME (decl
);
309 const char* asm_str
= IDENTIFIER_POINTER (old_id
);
310 /* Do not change the identifier if a verbatim asmspec
311 or if stdcall suffix already added. */
312 if (!(*asm_str
== '*' || strchr (asm_str
, '@'))
313 && (new_id
= i386_pe_maybe_mangle_decl_assembler_name (decl
,
315 XSTR (symbol
, 0) = IDENTIFIER_POINTER (new_id
);
320 if (lookup_attribute ("selectany", DECL_ATTRIBUTES (decl
)))
322 if (DECL_INITIAL (decl
)
323 /* If an object is initialized with a ctor, the static
324 initialization and destruction code for it is present in
325 each unit defining the object. The code that calls the
326 ctor is protected by a link-once guard variable, so that
327 the object still has link-once semantics, */
328 || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl
)))
329 make_decl_one_only (decl
, DECL_ASSEMBLER_NAME (decl
));
331 error ("%q+D:'selectany' attribute applies only to "
332 "initialized objects", decl
);
340 /* Mark the decl so we can tell from the rtl whether the object is
341 dllexport'd or dllimport'd. tree.c: merge_dllimport_decl_attributes
342 handles dllexport/dllimport override semantics. */
343 flags
= (SYMBOL_REF_FLAGS (symbol
) &
344 ~(SYMBOL_FLAG_DLLIMPORT
| SYMBOL_FLAG_DLLEXPORT
));
345 if (i386_pe_determine_dllexport_p (decl
))
346 flags
|= SYMBOL_FLAG_DLLEXPORT
;
347 else if (i386_pe_determine_dllimport_p (decl
))
348 flags
|= SYMBOL_FLAG_DLLIMPORT
;
350 SYMBOL_REF_FLAGS (symbol
) = flags
;
355 i386_pe_binds_local_p (const_tree exp
)
357 if ((TREE_CODE (exp
) == VAR_DECL
|| TREE_CODE (exp
) == FUNCTION_DECL
)
358 && DECL_DLLIMPORT_P (exp
))
361 /* External public symbols, which aren't weakref-s,
362 have local-binding for PE targets. */
364 && !lookup_attribute ("weakref", DECL_ATTRIBUTES (exp
))
366 && DECL_EXTERNAL (exp
))
368 return default_binds_local_p_1 (exp
, 0);
371 /* Also strip the fastcall prefix and stdcall suffix. */
374 i386_pe_strip_name_encoding_full (const char *str
)
377 const char *name
= default_strip_name_encoding (str
);
379 /* Strip leading '@' on fastcall symbols. */
383 /* Strip trailing "@n". */
384 p
= strchr (name
, '@');
386 return ggc_alloc_string (name
, p
- name
);
392 i386_pe_unique_section (tree decl
, int reloc
)
395 const char *name
, *prefix
;
398 /* Ignore RELOC, if we are allowed to put relocated
399 const data into read-only section. */
400 if (!flag_writable_rel_rdata
)
402 name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
403 name
= i386_pe_strip_name_encoding_full (name
);
405 /* The object is put in, for example, section .text$foo.
406 The linker will then ultimately place them in .text
407 (everything from the $ on is stripped). Don't put
408 read-only data in .rdata section to avoid a PE linker
409 bug when .rdata$* grouped sections are used in code
410 without a .rdata section. */
411 if (TREE_CODE (decl
) == FUNCTION_DECL
)
413 else if (decl_readonly_section (decl
, reloc
))
417 len
= strlen (name
) + strlen (prefix
);
418 string
= XALLOCAVEC (char, len
+ 1);
419 sprintf (string
, "%s%s", prefix
, name
);
421 DECL_SECTION_NAME (decl
) = build_string (len
, string
);
424 /* Select a set of attributes for section NAME based on the properties
425 of DECL and whether or not RELOC indicates that DECL's initializer
426 might contain runtime relocations.
428 We make the section read-only and executable for a function decl,
429 read-only for a const data decl, and writable for a non-const data decl.
431 If the section has already been defined, to not allow it to have
432 different attributes, as (1) this is ambiguous since we're not seeing
433 all the declarations up front and (2) some assemblers (e.g. SVR4)
434 do not recognize section redefinitions. */
435 /* ??? This differs from the "standard" PE implementation in that we
436 handle the SHARED variable attribute. Should this be done for all
439 #define SECTION_PE_SHARED SECTION_MACH_DEP
442 i386_pe_section_type_flags (tree decl
, const char *name
, int reloc
)
448 /* Ignore RELOC, if we are allowed to put relocated
449 const data into read-only section. */
450 if (!flag_writable_rel_rdata
)
452 /* The names we put in the hashtable will always be the unique
453 versions given to us by the stringtable, so we can just use
454 their addresses as the keys. */
456 htab
= htab_create (31, htab_hash_pointer
, htab_eq_pointer
, NULL
);
458 if (decl
&& TREE_CODE (decl
) == FUNCTION_DECL
)
459 flags
= SECTION_CODE
;
460 else if (decl
&& decl_readonly_section (decl
, reloc
))
464 flags
= SECTION_WRITE
;
466 if (decl
&& TREE_CODE (decl
) == VAR_DECL
467 && lookup_attribute ("shared", DECL_ATTRIBUTES (decl
)))
468 flags
|= SECTION_PE_SHARED
;
471 if (decl
&& DECL_ONE_ONLY (decl
))
472 flags
|= SECTION_LINKONCE
;
474 /* See if we already have an entry for this section. */
475 slot
= (unsigned int **) htab_find_slot (htab
, name
, INSERT
);
478 *slot
= (unsigned int *) xmalloc (sizeof (unsigned int));
483 if (decl
&& **slot
!= flags
)
484 error ("%q+D causes a section type conflict", decl
);
491 i386_pe_asm_named_section (const char *name
, unsigned int flags
,
494 char flagchars
[8], *f
= flagchars
;
496 #if defined (HAVE_GAS_SECTION_EXCLUDE) && HAVE_GAS_SECTION_EXCLUDE == 1
497 if ((flags
& SECTION_EXCLUDE
) != 0)
501 if ((flags
& (SECTION_CODE
| SECTION_WRITE
)) == 0)
504 *f
++ ='d'; /* This is necessary for older versions of gas. */
509 if (flags
& SECTION_CODE
)
511 if (flags
& SECTION_WRITE
)
513 if (flags
& SECTION_PE_SHARED
)
515 #if !defined (HAVE_GAS_SECTION_EXCLUDE) || HAVE_GAS_SECTION_EXCLUDE == 0
516 /* If attribute "e" isn't supported we mark this section as
518 if ((flags
& SECTION_EXCLUDE
) != 0)
523 /* LTO sections need 1-byte alignment to avoid confusing the
524 zlib decompression algorithm with trailing zero pad bytes. */
525 if (strncmp (name
, LTO_SECTION_NAME_PREFIX
,
526 strlen (LTO_SECTION_NAME_PREFIX
)) == 0)
531 fprintf (asm_out_file
, "\t.section\t%s,\"%s\"\n", name
, flagchars
);
533 if (flags
& SECTION_LINKONCE
)
535 /* Functions may have been compiled at various levels of
536 optimization so we can't use `same_size' here.
537 Instead, have the linker pick one, without warning.
538 If 'selectany' attribute has been specified, MS compiler
539 sets 'discard' characteristic, rather than telling linker
540 to warn of size or content mismatch, so do the same. */
541 bool discard
= (flags
& SECTION_CODE
)
542 || lookup_attribute ("selectany",
543 DECL_ATTRIBUTES (decl
));
544 fprintf (asm_out_file
, "\t.linkonce %s\n",
545 (discard
? "discard" : "same_size"));
549 /* Beware, DECL may be NULL if compile_file() is emitting the LTO marker. */
552 i386_pe_asm_output_aligned_decl_common (FILE *stream
, tree decl
,
553 const char *name
, HOST_WIDE_INT size
,
554 HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
556 HOST_WIDE_INT rounded
;
558 /* Compute as in assemble_noswitch_variable, since we don't have
559 support for aligned common on older binutils. We must also
560 avoid emitting a common symbol of size zero, as this is the
561 overloaded representation that indicates an undefined external
562 symbol in the PE object file format. */
563 rounded
= size
? size
: 1;
564 rounded
+= (BIGGEST_ALIGNMENT
/ BITS_PER_UNIT
) - 1;
565 rounded
= (rounded
/ (BIGGEST_ALIGNMENT
/ BITS_PER_UNIT
)
566 * (BIGGEST_ALIGNMENT
/ BITS_PER_UNIT
));
568 i386_pe_maybe_record_exported_symbol (decl
, name
, 1);
570 fprintf (stream
, "\t.comm\t");
571 assemble_name (stream
, name
);
572 if (use_pe_aligned_common
)
573 fprintf (stream
, ", " HOST_WIDE_INT_PRINT_DEC
", %d\n",
574 size
? size
: (HOST_WIDE_INT
) 1,
575 exact_log2 (align
) - exact_log2 (CHAR_BIT
));
577 fprintf (stream
, ", " HOST_WIDE_INT_PRINT_DEC
"\t" ASM_COMMENT_START
578 " " HOST_WIDE_INT_PRINT_DEC
"\n", rounded
, size
);
581 /* The Microsoft linker requires that every function be marked as
582 DT_FCN. When using gas on cygwin, we must emit appropriate .type
587 /* Mark a function appropriately. This should only be called for
588 functions for which we are not emitting COFF debugging information.
589 FILE is the assembler output file, NAME is the name of the
590 function, and PUB is nonzero if the function is globally
594 i386_pe_declare_function_type (FILE *file
, const char *name
, int pub
)
596 fprintf (file
, "\t.def\t");
597 assemble_name (file
, name
);
598 fprintf (file
, ";\t.scl\t%d;\t.type\t%d;\t.endef\n",
599 pub
? (int) C_EXT
: (int) C_STAT
,
600 (int) DT_FCN
<< N_BTSHFT
);
603 /* Keep a list of external functions. */
605 struct GTY(()) extern_list
607 struct extern_list
*next
;
612 static GTY(()) struct extern_list
*extern_head
;
614 /* Assemble an external function reference. We need to keep a list of
615 these, so that we can output the function types at the end of the
616 assembly. We can't output the types now, because we might see a
617 definition of the function later on and emit debugging information
621 i386_pe_record_external_function (tree decl
, const char *name
)
623 struct extern_list
*p
;
625 p
= ggc_alloc_extern_list ();
626 p
->next
= extern_head
;
632 /* Keep a list of exported symbols. */
634 struct GTY(()) export_list
636 struct export_list
*next
;
638 int is_data
; /* used to type tag exported symbols. */
641 static GTY(()) struct export_list
*export_head
;
643 /* Assemble an export symbol entry. We need to keep a list of
644 these, so that we can output the export list at the end of the
645 assembly. We used to output these export symbols in each function,
646 but that causes problems with GNU ld when the sections are
647 linkonce. Beware, DECL may be NULL if compile_file() is emitting
651 i386_pe_maybe_record_exported_symbol (tree decl
, const char *name
, int is_data
)
654 struct export_list
*p
;
659 symbol
= XEXP (DECL_RTL (decl
), 0);
660 gcc_assert (GET_CODE (symbol
) == SYMBOL_REF
);
661 if (!SYMBOL_REF_DLLEXPORT_P (symbol
))
664 gcc_assert (TREE_PUBLIC (decl
));
666 p
= ggc_alloc_export_list ();
667 p
->next
= export_head
;
669 p
->is_data
= is_data
;
673 #ifdef CXX_WRAP_SPEC_LIST
675 /* Hash table equality helper function. */
678 wrapper_strcmp (const void *x
, const void *y
)
680 return !strcmp ((const char *) x
, (const char *) y
);
683 /* Search for a function named TARGET in the list of library wrappers
684 we are using, returning a pointer to it if found or NULL if not.
685 This function might be called on quite a few symbols, and we only
686 have the list of names of wrapped functions available to us as a
687 spec string, so first time round we lazily initialise a hash table
688 to make things quicker. */
691 i386_find_on_wrapper_list (const char *target
)
693 static char first_time
= 1;
694 static htab_t wrappers
;
698 /* Beware that this is not a complicated parser, it assumes
699 that any sequence of non-whitespace beginning with an
700 underscore is one of the wrapped symbols. For now that's
701 adequate to distinguish symbols from spec substitutions
702 and command-line options. */
703 static char wrapper_list_buffer
[] = CXX_WRAP_SPEC_LIST
;
705 /* Breaks up the char array into separated strings
706 strings and enter them into the hash table. */
707 wrappers
= htab_create_alloc (8, htab_hash_string
, wrapper_strcmp
,
709 for (bufptr
= wrapper_list_buffer
; *bufptr
; ++bufptr
)
712 if (ISSPACE (*bufptr
))
716 while (*bufptr
&& !ISSPACE (*bufptr
))
721 *htab_find_slot (wrappers
, found
, INSERT
) = found
;
726 return (const char *) htab_find (wrappers
, target
);
729 #endif /* CXX_WRAP_SPEC_LIST */
731 /* This is called at the end of assembly. For each external function
732 which has not been defined, we output a declaration now. We also
733 output the .drectve section. */
736 i386_pe_file_end (void)
738 struct extern_list
*p
;
740 for (p
= extern_head
; p
!= NULL
; p
= p
->next
)
746 /* Positively ensure only one declaration for any given symbol. */
747 if (! TREE_ASM_WRITTEN (decl
)
748 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl
)))
750 #ifdef CXX_WRAP_SPEC_LIST
751 /* To ensure the DLL that provides the corresponding real
752 functions is still loaded at runtime, we must reference
753 the real function so that an (unused) import is created. */
754 const char *realsym
= i386_find_on_wrapper_list (p
->name
);
756 i386_pe_declare_function_type (asm_out_file
,
757 concat ("__real_", realsym
, NULL
), TREE_PUBLIC (decl
));
758 #endif /* CXX_WRAP_SPEC_LIST */
759 TREE_ASM_WRITTEN (decl
) = 1;
760 i386_pe_declare_function_type (asm_out_file
, p
->name
,
767 struct export_list
*q
;
769 for (q
= export_head
; q
!= NULL
; q
= q
->next
)
771 fprintf (asm_out_file
, "\t.ascii \" -export:\\\"%s\\\"%s\"\n",
772 default_strip_name_encoding (q
->name
),
773 (q
->is_data
? ",data" : ""));
779 /* x64 Structured Exception Handling unwind info. */
781 struct seh_frame_state
783 /* SEH records saves relative to the "current" stack pointer, whether
784 or not there's a frame pointer in place. This tracks the current
785 stack pointer offset from the CFA. */
786 HOST_WIDE_INT sp_offset
;
788 /* The CFA is located at CFA_REG + CFA_OFFSET. */
789 HOST_WIDE_INT cfa_offset
;
793 /* Set up data structures beginning output for SEH. */
796 i386_pe_seh_init (FILE *f
)
798 struct seh_frame_state
*seh
;
805 /* We cannot support DRAP with SEH. We turned off support for it by
806 re-defining MAX_STACK_ALIGNMENT when SEH is enabled. */
807 gcc_assert (!stack_realign_drap
);
809 seh
= XCNEW (struct seh_frame_state
);
810 cfun
->machine
->seh
= seh
;
812 seh
->sp_offset
= INCOMING_FRAME_SP_OFFSET
;
813 seh
->cfa_offset
= INCOMING_FRAME_SP_OFFSET
;
814 seh
->cfa_reg
= stack_pointer_rtx
;
816 fputs ("\t.seh_proc\t", f
);
817 assemble_name (f
, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (cfun
->decl
)));
822 i386_pe_seh_end_prologue (FILE *f
)
824 struct seh_frame_state
*seh
;
830 seh
= cfun
->machine
->seh
;
833 cfun
->machine
->seh
= NULL
;
835 fputs ("\t.seh_endprologue\n", f
);
839 i386_pe_seh_fini (FILE *f
)
845 fputs ("\t.seh_endproc\n", f
);
848 /* Emit an assembler directive to save REG via a PUSH. */
851 seh_emit_push (FILE *f
, struct seh_frame_state
*seh
, rtx reg
)
853 unsigned int regno
= REGNO (reg
);
855 gcc_checking_assert (GENERAL_REGNO_P (regno
));
857 seh
->sp_offset
+= UNITS_PER_WORD
;
858 if (seh
->cfa_reg
== stack_pointer_rtx
)
859 seh
->cfa_offset
+= UNITS_PER_WORD
;
861 fputs ("\t.seh_pushreg\t", f
);
862 print_reg (reg
, 0, f
);
866 /* Emit an assembler directive to save REG at CFA - CFA_OFFSET. */
869 seh_emit_save (FILE *f
, struct seh_frame_state
*seh
,
870 rtx reg
, HOST_WIDE_INT cfa_offset
)
872 unsigned int regno
= REGNO (reg
);
873 HOST_WIDE_INT offset
;
875 /* Negative save offsets are of course not supported, since that
876 would be a store below the stack pointer and thus clobberable. */
877 gcc_assert (seh
->sp_offset
>= cfa_offset
);
878 offset
= seh
->sp_offset
- cfa_offset
;
880 fputs ((SSE_REGNO_P (regno
) ? "\t.seh_savexmm\t"
881 : GENERAL_REGNO_P (regno
) ? "\t.seh_savereg\t"
882 : (gcc_unreachable (), "")), f
);
883 print_reg (reg
, 0, f
);
884 fprintf (f
, ", " HOST_WIDE_INT_PRINT_DEC
"\n", offset
);
887 /* Emit an assembler directive to adjust RSP by OFFSET. */
890 seh_emit_stackalloc (FILE *f
, struct seh_frame_state
*seh
,
891 HOST_WIDE_INT offset
)
893 /* We're only concerned with prologue stack allocations, which all
894 are subtractions from the stack pointer. */
895 gcc_assert (offset
< 0);
898 if (seh
->cfa_reg
== stack_pointer_rtx
)
899 seh
->cfa_offset
+= offset
;
900 seh
->sp_offset
+= offset
;
902 /* Do not output the stackalloc in that case (it won't work as there is no
903 encoding for very large frame size). */
904 if (offset
< SEH_MAX_FRAME_SIZE
)
905 fprintf (f
, "\t.seh_stackalloc\t" HOST_WIDE_INT_PRINT_DEC
"\n", offset
);
908 /* Process REG_CFA_ADJUST_CFA for SEH. */
911 seh_cfa_adjust_cfa (FILE *f
, struct seh_frame_state
*seh
, rtx pat
)
914 HOST_WIDE_INT reg_offset
= 0;
915 unsigned int dest_regno
;
917 dest
= SET_DEST (pat
);
920 if (GET_CODE (src
) == PLUS
)
922 reg_offset
= INTVAL (XEXP (src
, 1));
925 else if (GET_CODE (src
) == MINUS
)
927 reg_offset
= -INTVAL (XEXP (src
, 1));
930 gcc_assert (src
== stack_pointer_rtx
);
931 gcc_assert (seh
->cfa_reg
== stack_pointer_rtx
);
932 dest_regno
= REGNO (dest
);
934 if (dest_regno
== STACK_POINTER_REGNUM
)
935 seh_emit_stackalloc (f
, seh
, reg_offset
);
936 else if (dest_regno
== HARD_FRAME_POINTER_REGNUM
)
938 HOST_WIDE_INT offset
;
941 seh
->cfa_offset
-= reg_offset
;
943 offset
= seh
->sp_offset
- seh
->cfa_offset
;
945 gcc_assert ((offset
& 15) == 0);
946 gcc_assert (IN_RANGE (offset
, 0, 240));
948 fputs ("\t.seh_setframe\t", f
);
949 print_reg (seh
->cfa_reg
, 0, f
);
950 fprintf (f
, ", " HOST_WIDE_INT_PRINT_DEC
"\n", offset
);
956 /* Process REG_CFA_OFFSET for SEH. */
959 seh_cfa_offset (FILE *f
, struct seh_frame_state
*seh
, rtx pat
)
962 HOST_WIDE_INT reg_offset
;
964 dest
= SET_DEST (pat
);
967 gcc_assert (MEM_P (dest
));
968 dest
= XEXP (dest
, 0);
973 gcc_assert (GET_CODE (dest
) == PLUS
);
974 reg_offset
= INTVAL (XEXP (dest
, 1));
975 dest
= XEXP (dest
, 0);
977 gcc_assert (dest
== seh
->cfa_reg
);
979 seh_emit_save (f
, seh
, src
, seh
->cfa_offset
- reg_offset
);
982 /* Process a FRAME_RELATED_EXPR for SEH. */
985 seh_frame_related_expr (FILE *f
, struct seh_frame_state
*seh
, rtx pat
)
988 HOST_WIDE_INT addend
;
990 /* See the full loop in dwarf2out_frame_debug_expr. */
991 if (GET_CODE (pat
) == PARALLEL
|| GET_CODE (pat
) == SEQUENCE
)
993 int i
, n
= XVECLEN (pat
, 0), pass
, npass
;
995 npass
= (GET_CODE (pat
) == PARALLEL
? 2 : 1);
996 for (pass
= 0; pass
< npass
; ++pass
)
997 for (i
= 0; i
< n
; ++i
)
999 rtx ele
= XVECEXP (pat
, 0, i
);
1001 if (GET_CODE (ele
) != SET
)
1003 dest
= SET_DEST (ele
);
1005 /* Process each member of the PARALLEL independently. The first
1006 member is always processed; others only if they are marked. */
1007 if (i
== 0 || RTX_FRAME_RELATED_P (ele
))
1009 /* Evaluate all register saves in the first pass and all
1010 register updates in the second pass. */
1011 if ((MEM_P (dest
) ^ pass
) || npass
== 1)
1012 seh_frame_related_expr (f
, seh
, ele
);
1018 dest
= SET_DEST (pat
);
1019 src
= SET_SRC (pat
);
1021 switch (GET_CODE (dest
))
1024 switch (GET_CODE (src
))
1027 /* REG = REG: This should be establishing a frame pointer. */
1028 gcc_assert (src
== stack_pointer_rtx
);
1029 gcc_assert (dest
== hard_frame_pointer_rtx
);
1030 seh_cfa_adjust_cfa (f
, seh
, pat
);
1034 addend
= INTVAL (XEXP (src
, 1));
1035 src
= XEXP (src
, 0);
1036 if (dest
== hard_frame_pointer_rtx
)
1037 seh_cfa_adjust_cfa (f
, seh
, pat
);
1038 else if (dest
== stack_pointer_rtx
)
1040 gcc_assert (src
== stack_pointer_rtx
);
1041 seh_emit_stackalloc (f
, seh
, addend
);
1053 /* A save of some kind. */
1054 dest
= XEXP (dest
, 0);
1055 if (GET_CODE (dest
) == PRE_DEC
)
1057 gcc_checking_assert (GET_MODE (src
) == Pmode
);
1058 gcc_checking_assert (REG_P (src
));
1059 seh_emit_push (f
, seh
, src
);
1062 seh_cfa_offset (f
, seh
, pat
);
1070 /* This function looks at a single insn and emits any SEH directives
1071 required for unwind of this insn. */
1074 i386_pe_seh_unwind_emit (FILE *asm_out_file
, rtx insn
)
1077 bool handled_one
= false;
1078 struct seh_frame_state
*seh
;
1083 /* We free the SEH data once done with the prologue. Ignore those
1084 RTX_FRAME_RELATED_P insns that are associated with the epilogue. */
1085 seh
= cfun
->machine
->seh
;
1089 if (NOTE_P (insn
) || !RTX_FRAME_RELATED_P (insn
))
1092 for (note
= REG_NOTES (insn
); note
; note
= XEXP (note
, 1))
1094 pat
= XEXP (note
, 0);
1095 switch (REG_NOTE_KIND (note
))
1097 case REG_FRAME_RELATED_EXPR
:
1100 case REG_CFA_DEF_CFA
:
1101 case REG_CFA_EXPRESSION
:
1102 /* Only emitted with DRAP, which we disable. */
1106 case REG_CFA_REGISTER
:
1107 /* Only emitted in epilogues, which we skip. */
1110 case REG_CFA_ADJUST_CFA
:
1113 pat
= PATTERN (insn
);
1114 if (GET_CODE (pat
) == PARALLEL
)
1115 pat
= XVECEXP (pat
, 0, 0);
1117 seh_cfa_adjust_cfa (asm_out_file
, seh
, pat
);
1121 case REG_CFA_OFFSET
:
1123 pat
= single_set (insn
);
1124 seh_cfa_offset (asm_out_file
, seh
, pat
);
1134 pat
= PATTERN (insn
);
1136 seh_frame_related_expr (asm_out_file
, seh
, pat
);
1140 i386_pe_start_function (FILE *f
, const char *name
, tree decl
)
1142 i386_pe_maybe_record_exported_symbol (decl
, name
, 0);
1143 if (write_symbols
!= SDB_DEBUG
)
1144 i386_pe_declare_function_type (f
, name
, TREE_PUBLIC (decl
));
1145 /* In case section was altered by debugging output. */
1146 if (decl
!= NULL_TREE
)
1147 switch_to_section (function_section (decl
));
1148 ASM_OUTPUT_FUNCTION_LABEL (f
, name
, decl
);
1152 i386_pe_end_function (FILE *f
, const char *name ATTRIBUTE_UNUSED
,
1153 tree decl ATTRIBUTE_UNUSED
)
1155 i386_pe_seh_fini (f
);
1159 #include "gt-winnt.h"