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 #define SUBTARGET_NAME_ENCODING_LENGTHS \
29 case ARM_PE_FLAG_CHAR: return 3;
33 #undef USER_LABEL_PREFIX
34 #define USER_LABEL_PREFIX "_"
37 /* Run-time Target Specification. */
39 #define TARGET_VERSION fputs (" (ARM/pe)", stderr)
41 /* Get tree.c to declare a target-specific specialization of
42 merge_decl_attributes. */
43 #define TARGET_DLLIMPORT_DECL_ATTRIBUTES
45 /* Support the __declspec keyword by turning them into attributes.
46 We currently only support: naked, dllimport, and dllexport.
47 Note that the current way we do this may result in a collision with
48 predefined attributes later on. This can be solved by using one attribute,
49 say __declspec__, and passing args to it. The problem with that approach
50 is that args are not accumulated: each new appearance would clobber any
52 #undef SUBTARGET_CPP_SPEC
53 #define SUBTARGET_CPP_SPEC "-D__pe__ -D__declspec(x)=__attribute__((x))"
56 /* Experimental addition for pr 7885.
57 Ignore dllimport for functions. */
58 #define TARGET_FLAG_NOP_FUN (1 << 24)
60 #undef TARGET_NOP_FUN_DLLIMPORT
61 #define TARGET_NOP_FUN_DLLIMPORT (target_flags & TARGET_FLAG_NOP_FUN)
63 #undef SUBTARGET_SWITCHES
64 #define SUBTARGET_SWITCHES \
65 { "nop-fun-dllimport", TARGET_FLAG_NOP_FUN, \
66 N_("Ignore dllimport attribute for functions") }, \
67 { "no-nop-fun-dllimport", - TARGET_FLAG_NOP_FUN, "" },
70 #define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | TARGET_FLAG_NOP_FUN)
74 #define WCHAR_TYPE "short unsigned int"
75 #undef WCHAR_TYPE_SIZE
76 #define WCHAR_TYPE_SIZE 16
78 /* Same as arm.h except r10 is call-saved, not fixed. */
79 #undef FIXED_REGISTERS
80 #define FIXED_REGISTERS \
88 /* Same as arm.h except r10 is call-saved, not fixed. */
89 #undef CALL_USED_REGISTERS
90 #define CALL_USED_REGISTERS \
98 /* In addition to the stuff done in arm.h, we must mark dll symbols specially.
99 Definitions of dllexport'd objects install some info in the .drectve
100 section. References to dllimport'd objects are fetched indirectly via
101 __imp_. If both are declared, dllexport overrides.
102 This is also needed to implement one-only vtables: they go into their own
103 section and we need to set DECL_SECTION_NAME so we do that here.
104 Note that we can be called twice on the same decl. */
105 #undef ENCODE_SECTION_INFO
106 #define ENCODE_SECTION_INFO(DECL) \
107 arm_pe_encode_section_info (DECL)
109 /* Used to implement dllexport overriding dllimport semantics. It's also used
110 to handle vtables - the first pass won't do anything because
111 DECL_CONTEXT (DECL) will be 0 so arm_dll{ex,im}port_p will return 0.
112 It's also used to handle dllimport override semantics. */
113 #define REDO_SECTION_INFO_P(DECL) 1
115 /* Define this macro if in some cases global symbols from one translation
116 unit may not be bound to undefined symbols in another translation unit
117 without user intervention. For instance, under Microsoft Windows
118 symbols must be explicitly imported from shared libraries (DLLs). */
119 #define MULTIPLE_SYMBOL_SPACES
121 #define UNIQUE_SECTION_P(DECL) DECL_ONE_ONLY (DECL)
123 #define UNIQUE_SECTION(DECL, RELOC) arm_pe_unique_section (DECL, RELOC)
125 #define SUPPORTS_ONE_ONLY 1
127 /* A C statement to output something to the assembler file to switch to section
128 NAME for object DECL which is either a FUNCTION_DECL, a VAR_DECL or
129 NULL_TREE. Some target formats do not support arbitrary sections. Do not
130 define this macro in such cases. */
131 #undef ASM_OUTPUT_SECTION_NAME
132 #define ASM_OUTPUT_SECTION_NAME(STREAM, DECL, NAME, RELOC) \
135 if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL) \
136 fprintf (STREAM, "\t.section %s,\"x\"\n", (NAME)); \
137 else if ((DECL) && DECL_READONLY_SECTION (DECL, RELOC)) \
138 fprintf (STREAM, "\t.section %s,\"\"\n", (NAME)); \
140 fprintf (STREAM, "\t.section %s,\"w\"\n", (NAME)); \
141 /* Functions may have been compiled at various levels of \
142 optimization so we can't use `same_size' here. \
143 Instead, have the linker pick one. */ \
144 if ((DECL) && DECL_ONE_ONLY (DECL)) \
145 fprintf (STREAM, "\t.linkonce %s\n", \
146 TREE_CODE (DECL) == FUNCTION_DECL \
147 ? "discard" : "same_size"); \
151 /* This outputs a lot of .req's to define alias for various registers.
152 Let's try to avoid this. */
153 #undef ASM_FILE_START
154 #define ASM_FILE_START(STREAM) \
157 asm_fprintf (STREAM, "%@ Generated by gcc %s for ARM/pe\n",\
159 output_file_directive ((STREAM), main_input_filename); \
163 /* Output a reference to a label. */
164 #undef ASM_OUTPUT_LABELREF
165 #define ASM_OUTPUT_LABELREF(STREAM, NAME) \
166 asm_fprintf (STREAM, "%U%s", arm_strip_name_encoding (NAME))
168 /* Output a function definition label. */
169 #undef ASM_DECLARE_FUNCTION_NAME
170 #define ASM_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL) \
173 if (arm_dllexport_name_p (NAME)) \
175 drectve_section (); \
176 fprintf (STREAM, "\t.ascii \" -export:%s\"\n", \
177 arm_strip_name_encoding (NAME)); \
178 function_section (DECL); \
180 ARM_DECLARE_FUNCTION_NAME (STREAM, NAME, DECL); \
182 fprintf (STREAM, "\t.code 16\n"); \
183 ASM_OUTPUT_LABEL (STREAM, NAME); \
187 /* Output a common block. */
188 #undef ASM_OUTPUT_COMMON
189 #define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
192 if (arm_dllexport_name_p (NAME)) \
194 drectve_section (); \
195 fprintf ((STREAM), "\t.ascii \" -export:%s\"\n",\
196 arm_strip_name_encoding (NAME)); \
198 if (! arm_dllimport_name_p (NAME)) \
200 fprintf ((STREAM), "\t.comm\t"); \
201 assemble_name ((STREAM), (NAME)); \
202 asm_fprintf ((STREAM), ", %d\t%@ %d\n", \
203 (ROUNDED), (SIZE)); \
208 /* Output the label for an initialized variable. */
209 #undef ASM_DECLARE_OBJECT_NAME
210 #define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL) \
213 if (arm_dllexport_name_p (NAME)) \
215 enum in_section save_section = in_section; \
216 drectve_section (); \
217 fprintf (STREAM, "\t.ascii \" -export:%s\"\n",\
218 arm_strip_name_encoding (NAME)); \
219 switch_to_section (save_section, (DECL)); \
221 ASM_OUTPUT_LABEL ((STREAM), (NAME)); \
225 /* Support the ctors/dtors and other sections. */
227 #define DRECTVE_SECTION_ASM_OP "\t.section .drectve"
229 /* A list of other sections which the compiler might be "in" at any
232 #undef SUBTARGET_EXTRA_SECTIONS
233 #define SUBTARGET_EXTRA_SECTIONS in_drectve,
235 /* A list of extra section function definitions. */
237 #undef SUBTARGET_EXTRA_SECTION_FUNCTIONS
238 #define SUBTARGET_EXTRA_SECTION_FUNCTIONS \
239 DRECTVE_SECTION_FUNCTION \
240 SWITCH_TO_SECTION_FUNCTION
242 #define DRECTVE_SECTION_FUNCTION \
246 if (in_section != in_drectve) \
248 fprintf (asm_out_file, "%s\n", DRECTVE_SECTION_ASM_OP); \
249 in_section = in_drectve; \
253 /* Switch to SECTION (an `enum in_section').
255 ??? This facility should be provided by GCC proper.
256 The problem is that we want to temporarily switch sections in
257 ASM_DECLARE_OBJECT_NAME and then switch back to the original section
259 #define SWITCH_TO_SECTION_FUNCTION \
261 switch_to_section (section, decl) \
262 enum in_section section; \
267 case in_text: text_section (); break; \
268 case in_data: data_section (); break; \
269 case in_named: named_section (decl, NULL, 0); break; \
270 case in_rdata: rdata_section (); break; \
271 case in_ctors: ctors_section (); break; \
272 case in_dtors: dtors_section (); break; \
273 case in_drectve: drectve_section (); break; \
274 default: abort (); break; \