1 /* Definitions of target machine for GNU compiler, for ARM with PE obj format.
2 Copyright (C) 1995, 1996, 1999, 2000 Free Software Foundation, Inc.
3 Contributed by Doug Evans (dje@cygnus.com).
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* Enable PE specific code. */
25 #define ARM_PE_FLAG_CHAR '@'
27 /* Ensure that @x. will be stripped from the function name. */
28 #undef SUBTARGET_NAME_ENCODING_LENGTHS
29 #define SUBTARGET_NAME_ENCODING_LENGTHS \
30 case ARM_PE_FLAG_CHAR: return 3;
32 #undef USER_LABEL_PREFIX
33 #define USER_LABEL_PREFIX "_"
36 /* Run-time Target Specification. */
38 #define TARGET_VERSION fputs (" (ARM/pe)", stderr)
40 /* Get tree.c to declare a target-specific specialization of
41 merge_decl_attributes. */
42 #define TARGET_DLLIMPORT_DECL_ATTRIBUTES
44 /* Support the __declspec keyword by turning them into attributes.
45 We currently only support: naked, dllimport, and dllexport.
46 Note that the current way we do this may result in a collision with
47 predefined attributes later on. This can be solved by using one attribute,
48 say __declspec__, and passing args to it. The problem with that approach
49 is that args are not accumulated: each new appearance would clobber any
51 #undef SUBTARGET_CPP_SPEC
52 #define SUBTARGET_CPP_SPEC "-D__pe__ -D__declspec(x)=__attribute__((x))"
55 /* Experimental addition for pr 7885.
56 Ignore dllimport for functions. */
57 #define TARGET_FLAG_NOP_FUN (1 << 24)
59 #undef TARGET_NOP_FUN_DLLIMPORT
60 #define TARGET_NOP_FUN_DLLIMPORT (target_flags & TARGET_FLAG_NOP_FUN)
62 #undef SUBTARGET_SWITCHES
63 #define SUBTARGET_SWITCHES \
64 { "nop-fun-dllimport", TARGET_FLAG_NOP_FUN, \
65 N_("Ignore dllimport attribute for functions") }, \
66 { "no-nop-fun-dllimport", - TARGET_FLAG_NOP_FUN, "" },
69 #define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | TARGET_FLAG_NOP_FUN)
73 #define WCHAR_TYPE "short unsigned int"
74 #undef WCHAR_TYPE_SIZE
75 #define WCHAR_TYPE_SIZE 16
77 /* Same as arm.h except r10 is call-saved, not fixed. */
78 #undef FIXED_REGISTERS
79 #define FIXED_REGISTERS \
87 /* Same as arm.h except r10 is call-saved, not fixed. */
88 #undef CALL_USED_REGISTERS
89 #define CALL_USED_REGISTERS \
97 /* In addition to the stuff done in arm.h, we must mark dll symbols specially.
98 Definitions of dllexport'd objects install some info in the .drectve
99 section. References to dllimport'd objects are fetched indirectly via
100 __imp_. If both are declared, dllexport overrides.
101 This is also needed to implement one-only vtables: they go into their own
102 section and we need to set DECL_SECTION_NAME so we do that here.
103 Note that we can be called twice on the same decl. */
104 #undef ENCODE_SECTION_INFO
105 #define ENCODE_SECTION_INFO(DECL) \
106 arm_pe_encode_section_info (DECL)
108 /* Used to implement dllexport overriding dllimport semantics. It's also used
109 to handle vtables - the first pass won't do anything because
110 DECL_CONTEXT (DECL) will be 0 so arm_dll{ex,im}port_p will return 0.
111 It's also used to handle dllimport override semantics. */
112 #define REDO_SECTION_INFO_P(DECL) 1
114 /* Define this macro if in some cases global symbols from one translation
115 unit may not be bound to undefined symbols in another translation unit
116 without user intervention. For instance, under Microsoft Windows
117 symbols must be explicitly imported from shared libraries (DLLs). */
118 #define MULTIPLE_SYMBOL_SPACES
120 #define UNIQUE_SECTION(DECL, RELOC) arm_pe_unique_section (DECL, RELOC)
122 #define SUPPORTS_ONE_ONLY 1
124 /* Switch into a generic section. */
125 #undef TARGET_ASM_NAMED_SECTION
126 #define TARGET_ASM_NAMED_SECTION default_pe_asm_named_section
128 /* This outputs a lot of .req's to define alias for various registers.
129 Let's try to avoid this. */
130 #undef ASM_FILE_START
131 #define ASM_FILE_START(STREAM) \
134 asm_fprintf (STREAM, "%@ Generated by gcc %s for ARM/pe\n",\
136 output_file_directive ((STREAM), main_input_filename); \
140 /* Output a reference to a label. */
141 #undef ASM_OUTPUT_LABELREF
142 #define ASM_OUTPUT_LABELREF(STREAM, NAME) \
143 asm_fprintf (STREAM, "%U%s", arm_strip_name_encoding (NAME))
145 /* Output a function definition label. */
146 #undef ASM_DECLARE_FUNCTION_NAME
147 #define ASM_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL) \
150 if (arm_dllexport_name_p (NAME)) \
152 drectve_section (); \
153 fprintf (STREAM, "\t.ascii \" -export:%s\"\n", \
154 arm_strip_name_encoding (NAME)); \
155 function_section (DECL); \
157 ARM_DECLARE_FUNCTION_NAME (STREAM, NAME, DECL); \
159 fprintf (STREAM, "\t.code 16\n"); \
160 ASM_OUTPUT_LABEL (STREAM, NAME); \
164 /* Output a common block. */
165 #undef ASM_OUTPUT_COMMON
166 #define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
169 if (arm_dllexport_name_p (NAME)) \
171 drectve_section (); \
172 fprintf ((STREAM), "\t.ascii \" -export:%s\"\n",\
173 arm_strip_name_encoding (NAME)); \
175 if (! arm_dllimport_name_p (NAME)) \
177 fprintf ((STREAM), "\t.comm\t"); \
178 assemble_name ((STREAM), (NAME)); \
179 asm_fprintf ((STREAM), ", %d\t%@ %d\n", \
180 (ROUNDED), (SIZE)); \
185 /* Output the label for an initialized variable. */
186 #undef ASM_DECLARE_OBJECT_NAME
187 #define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL) \
190 if (arm_dllexport_name_p (NAME)) \
192 enum in_section save_section = in_section; \
193 drectve_section (); \
194 fprintf (STREAM, "\t.ascii \" -export:%s\"\n",\
195 arm_strip_name_encoding (NAME)); \
196 switch_to_section (save_section, (DECL)); \
198 ASM_OUTPUT_LABEL ((STREAM), (NAME)); \
202 /* Support the ctors/dtors and other sections. */
204 #define DRECTVE_SECTION_ASM_OP "\t.section .drectve"
206 /* A list of other sections which the compiler might be "in" at any
209 #undef SUBTARGET_EXTRA_SECTIONS
210 #define SUBTARGET_EXTRA_SECTIONS in_drectve,
212 /* A list of extra section function definitions. */
214 #undef SUBTARGET_EXTRA_SECTION_FUNCTIONS
215 #define SUBTARGET_EXTRA_SECTION_FUNCTIONS \
216 DRECTVE_SECTION_FUNCTION \
217 SWITCH_TO_SECTION_FUNCTION
219 #define DRECTVE_SECTION_FUNCTION \
223 if (in_section != in_drectve) \
225 fprintf (asm_out_file, "%s\n", DRECTVE_SECTION_ASM_OP); \
226 in_section = in_drectve; \
230 /* Switch to SECTION (an `enum in_section').
232 ??? This facility should be provided by GCC proper.
233 The problem is that we want to temporarily switch sections in
234 ASM_DECLARE_OBJECT_NAME and then switch back to the original section
236 #define SWITCH_TO_SECTION_FUNCTION \
237 static void switch_to_section PARAMS ((enum in_section, tree)); \
239 switch_to_section (section, decl) \
240 enum in_section section; \
245 case in_text: text_section (); break; \
246 case in_data: data_section (); break; \
247 case in_named: named_section (decl, NULL, 0); break; \
248 case in_rdata: rdata_section (); break; \
249 case in_ctors: ctors_section (); break; \
250 case in_dtors: dtors_section (); break; \
251 case in_drectve: drectve_section (); break; \
252 default: abort (); break; \