1 /* Definitions of target machine for GNU compiler, for ARM with PE obj format.
2 Copyright (C) 1995, 1996, 1999, 2000, 2002 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, FIRST) \
106 arm_pe_encode_section_info (DECL, FIRST)
108 /* Define this macro if in some cases global symbols from one translation
109 unit may not be bound to undefined symbols in another translation unit
110 without user intervention. For instance, under Microsoft Windows
111 symbols must be explicitly imported from shared libraries (DLLs). */
112 #define MULTIPLE_SYMBOL_SPACES
114 #define TARGET_ASM_UNIQUE_SECTION arm_pe_unique_section
116 #define SUPPORTS_ONE_ONLY 1
118 /* Switch into a generic section. */
119 #undef TARGET_ASM_NAMED_SECTION
120 #define TARGET_ASM_NAMED_SECTION default_pe_asm_named_section
122 /* This outputs a lot of .req's to define alias for various registers.
123 Let's try to avoid this. */
124 #undef ASM_FILE_START
125 #define ASM_FILE_START(STREAM) \
128 asm_fprintf (STREAM, "%@ Generated by gcc %s for ARM/pe\n",\
130 output_file_directive ((STREAM), main_input_filename); \
134 /* Output a reference to a label. */
135 #undef ASM_OUTPUT_LABELREF
136 #define ASM_OUTPUT_LABELREF(STREAM, NAME) \
137 asm_fprintf (STREAM, "%U%s", arm_strip_name_encoding (NAME))
139 /* Output a function definition label. */
140 #undef ASM_DECLARE_FUNCTION_NAME
141 #define ASM_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL) \
144 if (arm_dllexport_name_p (NAME)) \
146 drectve_section (); \
147 fprintf (STREAM, "\t.ascii \" -export:%s\"\n", \
148 arm_strip_name_encoding (NAME)); \
149 function_section (DECL); \
151 ARM_DECLARE_FUNCTION_NAME (STREAM, NAME, DECL); \
153 fprintf (STREAM, "\t.code 16\n"); \
154 ASM_OUTPUT_LABEL (STREAM, NAME); \
158 /* Output a common block. */
159 #undef ASM_OUTPUT_COMMON
160 #define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
163 if (arm_dllexport_name_p (NAME)) \
165 drectve_section (); \
166 fprintf ((STREAM), "\t.ascii \" -export:%s\"\n",\
167 arm_strip_name_encoding (NAME)); \
169 if (! arm_dllimport_name_p (NAME)) \
171 fprintf ((STREAM), "\t.comm\t"); \
172 assemble_name ((STREAM), (NAME)); \
173 asm_fprintf ((STREAM), ", %d\t%@ %d\n", \
174 (ROUNDED), (SIZE)); \
179 /* Output the label for an initialized variable. */
180 #undef ASM_DECLARE_OBJECT_NAME
181 #define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL) \
184 if (arm_dllexport_name_p (NAME)) \
186 enum in_section save_section = in_section; \
187 drectve_section (); \
188 fprintf (STREAM, "\t.ascii \" -export:%s\"\n",\
189 arm_strip_name_encoding (NAME)); \
190 switch_to_section (save_section, (DECL)); \
192 ASM_OUTPUT_LABEL ((STREAM), (NAME)); \
196 /* Support the ctors/dtors and other sections. */
198 #define DRECTVE_SECTION_ASM_OP "\t.section .drectve"
200 /* A list of other sections which the compiler might be "in" at any
203 #undef SUBTARGET_EXTRA_SECTIONS
204 #define SUBTARGET_EXTRA_SECTIONS in_drectve,
206 /* A list of extra section function definitions. */
208 #undef SUBTARGET_EXTRA_SECTION_FUNCTIONS
209 #define SUBTARGET_EXTRA_SECTION_FUNCTIONS \
210 DRECTVE_SECTION_FUNCTION \
211 SWITCH_TO_SECTION_FUNCTION
213 #define DRECTVE_SECTION_FUNCTION \
217 if (in_section != in_drectve) \
219 fprintf (asm_out_file, "%s\n", DRECTVE_SECTION_ASM_OP); \
220 in_section = in_drectve; \
224 /* Switch to SECTION (an `enum in_section').
226 ??? This facility should be provided by GCC proper.
227 The problem is that we want to temporarily switch sections in
228 ASM_DECLARE_OBJECT_NAME and then switch back to the original section
230 #define SWITCH_TO_SECTION_FUNCTION \
231 static void switch_to_section PARAMS ((enum in_section, tree)); \
233 switch_to_section (section, decl) \
234 enum in_section section; \
239 case in_text: text_section (); break; \
240 case in_data: data_section (); break; \
241 case in_named: named_section (decl, NULL, 0); break; \
242 case in_rdata: rdata_section (); break; \
243 case in_ctors: ctors_section (); break; \
244 case in_dtors: dtors_section (); break; \
245 case in_drectve: drectve_section (); break; \
246 default: abort (); break; \