Add support for arm-pe and thumb-pe
[official-gcc.git] / gcc / config / arm / pe.h
blob18281cd1d3851a084e75148e56b937380b8a904a
1 /* Definitions of target machine for GNU compiler, for ARM with PE obj format.
2 Copyright (C) 1995, 1996, 1999 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)
10 any later version.
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 #include "arm/coff.h"
24 #undef USER_LABEL_PREFIX
25 #define USER_LABEL_PREFIX "_"
28 /* Run-time Target Specification. */
29 #undef TARGET_VERSION
30 #define TARGET_VERSION fputs (" (ARM/pe)", stderr)
32 /* Support the __declspec keyword by turning them into attributes.
33 We currently only support: naked, dllimport, and dllexport.
34 Note that the current way we do this may result in a collision with
35 predefined attributes later on. This can be solved by using one attribute,
36 say __declspec__, and passing args to it. The problem with that approach
37 is that args are not accumulated: each new appearance would clobber any
38 existing args. */
39 #undef CPP_PREDEFINES
40 #define CPP_PREDEFINES "\
41 -Darm -D__pe__ -Acpu(arm) -Amachine(arm) \
42 -D__declspec(x)=__attribute__((x)) \
45 /* Experimental addition for pr 7885.
46 Ignore dllimport for functions. */
47 #define TARGET_NOP_FUN_DLLIMPORT (target_flags & 0x20000)
49 #undef SUBTARGET_SWITCHES
50 #define SUBTARGET_SWITCHES \
51 { "nop-fun-dllimport", 0x20000, "Ignore dllimport attribute for functions" }, \
52 { "no-nop-fun-dllimport", -0x20000, "" },
54 #undef TARGET_DEFAULT
55 #define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT + 0x20000)
57 #undef WCHAR_TYPE
58 #define WCHAR_TYPE "short unsigned int"
59 #undef WCHAR_TYPE_SIZE
60 #define WCHAR_TYPE_SIZE 16
62 /* Same as arm.h except r10 is call-saved, not fixed. */
63 #undef FIXED_REGISTERS
64 #define FIXED_REGISTERS \
65 { \
66 0,0,0,0,0,0,0,0, \
67 0,0,0,1,0,1,0,1, \
68 0,0,0,0,0,0,0,0, \
69 1,1,1 \
72 /* Same as arm.h except r10 is call-saved, not fixed. */
73 #undef CALL_USED_REGISTERS
74 #define CALL_USED_REGISTERS \
75 { \
76 1,1,1,1,0,0,0,0, \
77 0,0,0,1,1,1,1,1, \
78 1,1,1,1,0,0,0,0, \
79 1,1,1 \
82 /* This is to better conform to the ARM PCS.
83 Richard Earnshaw hasn't put this into FSF sources yet so it's here. */
84 #undef RETURN_IN_MEMORY
85 #define RETURN_IN_MEMORY(TYPE) \
86 ((TYPE_MODE ((TYPE)) == BLKmode && ! TYPE_NO_FORCE_BLK (TYPE)) \
87 || (AGGREGATE_TYPE_P ((TYPE)) && arm_pe_return_in_memory ((TYPE))))
89 /* A C expression whose value is nonzero if IDENTIFIER with arguments ARGS
90 is a valid machine specific attribute for DECL.
91 The attributes in ATTRIBUTES have previously been assigned to DECL. */
92 extern int arm_pe_valid_machine_decl_attribute ();
93 #undef VALID_MACHINE_DECL_ATTRIBUTE
94 #define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \
95 arm_pe_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
97 #if 0 /* Needed when we tried type attributes. */
98 /* A C expression whose value is zero if the attributes on
99 TYPE1 and TYPE2 are incompatible, one if they are compatible,
100 and two if they are nearly compatible (which causes a warning to be
101 generated). */
102 extern int arm_pe_comp_type_attributes ();
103 #define COMP_TYPE_ATTRIBUTES(TYPE1, TYPE2) \
104 arm_pe_comp_type_attributes ((TYPE1), (TYPE2))
105 #endif
107 extern union tree_node *arm_pe_merge_machine_decl_attributes ();
108 #define MERGE_MACHINE_DECL_ATTRIBUTES(OLD, NEW) \
109 arm_pe_merge_machine_decl_attributes ((OLD), (NEW))
111 /* In addition to the stuff done in arm.h, we must mark dll symbols specially.
112 Definitions of dllexport'd objects install some info in the .drectve
113 section. References to dllimport'd objects are fetched indirectly via
114 __imp_. If both are declared, dllexport overrides.
115 This is also needed to implement one-only vtables: they go into their own
116 section and we need to set DECL_SECTION_NAME so we do that here.
117 Note that we can be called twice on the same decl. */
118 extern void arm_pe_encode_section_info ();
119 #undef ENCODE_SECTION_INFO
120 #define ENCODE_SECTION_INFO(DECL) \
121 arm_pe_encode_section_info (DECL)
123 /* Used to implement dllexport overriding dllimport semantics. It's also used
124 to handle vtables - the first pass won't do anything because
125 DECL_CONTEXT (DECL) will be 0 so arm_dll{ex,im}port_p will return 0.
126 It's also used to handle dllimport override semantics. */
127 #if 0
128 #define REDO_SECTION_INFO_P(DECL) \
129 ((DECL_MACHINE_ATTRIBUTES (DECL) != NULL_TREE) \
130 || (TREE_CODE (DECL) == VAR_DECL && DECL_VIRTUAL_P (DECL)))
131 #else
132 #define REDO_SECTION_INFO_P(DECL) 1
133 #endif
135 /* Utility used only in this file. */
136 #define ARM_STRIP_NAME_ENCODING(SYM_NAME) \
137 ((SYM_NAME) + ((SYM_NAME)[0] == '@' ? 3 : 0))
139 /* Strip any text from SYM_NAME added by ENCODE_SECTION_INFO and store
140 the result in VAR. */
141 #undef STRIP_NAME_ENCODING
142 #define STRIP_NAME_ENCODING(VAR, SYM_NAME) \
143 (VAR) = ARM_STRIP_NAME_ENCODING (SYM_NAME)
145 /* Define this macro if in some cases global symbols from one translation
146 unit may not be bound to undefined symbols in another translation unit
147 without user intervention. For instance, under Microsoft Windows
148 symbols must be explicitly imported from shared libraries (DLLs). */
149 #define MULTIPLE_SYMBOL_SPACES
151 #define UNIQUE_SECTION_P(DECL) DECL_ONE_ONLY (DECL)
152 extern void arm_pe_unique_section ();
153 #define UNIQUE_SECTION(DECL,RELOC) arm_pe_unique_section (DECL, RELOC)
155 #define SUPPORTS_ONE_ONLY 1
157 /* A C statement to output something to the assembler file to switch to section
158 NAME for object DECL which is either a FUNCTION_DECL, a VAR_DECL or
159 NULL_TREE. Some target formats do not support arbitrary sections. Do not
160 define this macro in such cases. */
161 #undef ASM_OUTPUT_SECTION_NAME
162 #define ASM_OUTPUT_SECTION_NAME(STREAM, DECL, NAME, RELOC) \
163 do { \
164 if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL) \
165 fprintf (STREAM, "\t.section %s,\"x\"\n", (NAME)); \
166 else if ((DECL) && DECL_READONLY_SECTION (DECL, RELOC)) \
167 fprintf (STREAM, "\t.section %s,\"\"\n", (NAME)); \
168 else \
169 fprintf (STREAM, "\t.section %s,\"w\"\n", (NAME)); \
170 /* Functions may have been compiled at various levels of \
171 optimization so we can't use `same_size' here. Instead, \
172 have the linker pick one. */ \
173 if ((DECL) && DECL_ONE_ONLY (DECL)) \
174 fprintf (STREAM, "\t.linkonce %s\n", \
175 TREE_CODE (DECL) == FUNCTION_DECL \
176 ? "discard" : "same_size"); \
177 } while (0)
179 /* This outputs a lot of .req's to define alias for various registers.
180 Let's try to avoid this. */
181 #undef ASM_FILE_START
182 #define ASM_FILE_START(STREAM) \
183 do { \
184 extern char * version_string; \
185 fprintf (STREAM, "%s Generated by gcc %s for ARM/pe\n", \
186 ASM_COMMENT_START, version_string); \
187 output_file_directive ((STREAM), main_input_filename); \
188 } while (0)
190 /* Output a reference to a label. */
191 #undef ASM_OUTPUT_LABELREF
192 #define ASM_OUTPUT_LABELREF(STREAM, NAME) \
193 fprintf (STREAM, "%s%s", USER_LABEL_PREFIX, ARM_STRIP_NAME_ENCODING (NAME))
195 /* Output a function definition label. */
196 #undef ASM_DECLARE_FUNCTION_NAME
197 #define ASM_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL) \
198 do { \
199 if (arm_dllexport_name_p (NAME)) \
201 drectve_section (); \
202 fprintf (STREAM, "\t.ascii \" -export:%s\"\n", \
203 ARM_STRIP_NAME_ENCODING (NAME)); \
204 function_section (DECL); \
206 if (TARGET_POKE_FUNCTION_NAME) \
207 arm_poke_function_name ((STREAM), (NAME)); \
208 ASM_OUTPUT_LABEL ((STREAM), (NAME)); \
209 } while (0)
211 /* Output a common block. */
212 #undef ASM_OUTPUT_COMMON
213 #define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
214 do { \
215 if (arm_dllexport_name_p (NAME)) \
217 drectve_section (); \
218 fprintf ((STREAM), "\t.ascii \" -export:%s\"\n", \
219 ARM_STRIP_NAME_ENCODING (NAME)); \
221 if (! arm_dllimport_name_p (NAME)) \
223 fprintf ((STREAM), "\t.comm\t"); \
224 assemble_name ((STREAM), (NAME)); \
225 fprintf ((STREAM), ", %d\t%s %d\n", \
226 (ROUNDED), ASM_COMMENT_START, (SIZE)); \
228 } while (0)
230 /* Output the label for an initialized variable. */
231 #undef ASM_DECLARE_OBJECT_NAME
232 #define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL) \
233 do { \
234 if (arm_dllexport_name_p (NAME)) \
236 enum in_section save_section = in_section; \
237 drectve_section (); \
238 fprintf (STREAM, "\t.ascii \" -export:%s\"\n", \
239 ARM_STRIP_NAME_ENCODING (NAME)); \
240 switch_to_section (save_section, (DECL)); \
242 ASM_OUTPUT_LABEL ((STREAM), (NAME)); \
243 } while (0)
245 /* Support the ctors/dtors and other sections. */
247 #define DRECTVE_SECTION_ASM_OP "\t.section .drectve"
249 /* A list of other sections which the compiler might be "in" at any
250 given time. */
252 #undef SUBTARGET_EXTRA_SECTIONS
253 #define SUBTARGET_EXTRA_SECTIONS in_drectve,
255 /* A list of extra section function definitions. */
257 #undef SUBTARGET_EXTRA_SECTION_FUNCTIONS
258 #define SUBTARGET_EXTRA_SECTION_FUNCTIONS \
259 DRECTVE_SECTION_FUNCTION \
260 SWITCH_TO_SECTION_FUNCTION
262 #define DRECTVE_SECTION_FUNCTION \
263 void \
264 drectve_section () \
266 if (in_section != in_drectve) \
268 fprintf (asm_out_file, "%s\n", DRECTVE_SECTION_ASM_OP); \
269 in_section = in_drectve; \
273 /* Switch to SECTION (an `enum in_section').
275 ??? This facility should be provided by GCC proper.
276 The problem is that we want to temporarily switch sections in
277 ASM_DECLARE_OBJECT_NAME and then switch back to the original section
278 afterwards. */
279 #define SWITCH_TO_SECTION_FUNCTION \
280 void \
281 switch_to_section (section, decl) \
282 enum in_section section; \
283 tree decl; \
285 switch (section) \
287 case in_text: text_section (); break; \
288 case in_data: data_section (); break; \
289 case in_named: named_section (decl, NULL, 0); break; \
290 case in_rdata: rdata_section (); break; \
291 case in_ctors: ctors_section (); break; \
292 case in_dtors: dtors_section (); break; \
293 case in_drectve: drectve_section (); break; \
294 default: abort (); break; \