1 /* Definitions of target machine for GNU compiler,
2 for Thumb with PE object format.
3 Copyright (C) 1998, 1999 Free Software Foundation, Inc.
4 Derived from arm/coff.h and arm/pe.h originally by Doug Evans (evans@cygnus.com).
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 #include "arm/thumb.h"
27 /* Run-time Target Specification. */
29 #define TARGET_VERSION fputs (" (Thumb/pe)", stderr)
31 /* Support the __declspec keyword by turning them into attributes.
32 We currently only support: naked, dllimport, and dllexport.
33 Note that the current way we do this may result in a collision with
34 predefined attributes later on. This can be solved by using one attribute,
35 say __declspec__, and passing args to it. The problem with that approach
36 is that args are not accumulated: each new appearance would clobber any
39 #define CPP_PREDEFINES "\
40 -Dthumb -D__thumb -D__pe__ -Acpu(arm) -Amachine(arm) \
41 -D__declspec(x)=__attribute__((x)) \
44 /* Experimental addition for pr 7885.
45 Ignore dllimport for functions. */
46 #define ARM_FLAG_NOP_FUN_IMPORT 0x20000
47 #define TARGET_NOP_FUN_DLLIMPORT (target_flags & ARM_FLAG_NOP_FUN_IMPORT)
49 #undef SUBTARGET_SWITCHES
50 #define SUBTARGET_SWITCHES \
51 { "nop-fun-dllimport", ARM_FLAG_NOP_FUN_IMPORT, "Ignore dllimport attribute for functions" }, \
52 { "no-nop-fun-dllimport", -ARM_FLAG_NOP_FUN_IMPORT, "" },
55 #define TARGET_DEFAULT ARM_FLAG_NOP_FUN_IMPORT
58 #define WCHAR_TYPE "short unsigned int"
59 #undef WCHAR_TYPE_SIZE
60 #define WCHAR_TYPE_SIZE 16
62 /* Setting this to 32 produces more efficient code, but the value set in previous
63 versions of this toolchain was 8, which produces more compact structures. The
64 command line option -mstructure_size_boundary=<n> can be used to change this
66 #undef STRUCTURE_SIZE_BOUNDARY
67 #define STRUCTURE_SIZE_BOUNDARY arm_structure_size_boundary
69 extern int arm_structure_size_boundary;
71 /* This is COFF, but prefer stabs. */
72 #define SDB_DEBUGGING_INFO
74 #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
78 /* Note - it is important that these definitions match those in semi.h for the ARM port. */
79 #undef LOCAL_LABEL_PREFIX
80 #define LOCAL_LABEL_PREFIX "."
82 #undef USER_LABEL_PREFIX
83 #define USER_LABEL_PREFIX "_"
85 /* A C statement to output assembler commands which will identify the
86 object file as having been compiled with GNU CC (or another GNU
88 #define ASM_IDENTIFY_GCC(STREAM) \
89 fprintf (STREAM, "%sgcc2_compiled.:\n%s", LOCAL_LABEL_PREFIX, ASM_APP_OFF )
92 #define ASM_FILE_START(STREAM) \
94 extern char * version_string; \
95 fprintf ((STREAM), "%s Generated by gcc %s for Thumb/coff\n", \
96 ASM_COMMENT_START, version_string); \
97 fprintf ((STREAM), ASM_APP_OFF); \
100 /* A C statement to output something to the assembler file to switch to section
101 NAME for object DECL which is either a FUNCTION_DECL, a VAR_DECL or
102 NULL_TREE. Some target formats do not support arbitrary sections. Do not
103 define this macro in such cases. */
104 #define ASM_OUTPUT_SECTION_NAME(STREAM, DECL, NAME, RELOC) \
106 if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL) \
107 fprintf (STREAM, "\t.section %s,\"x\"\n", (NAME)); \
108 else if ((DECL) && DECL_READONLY_SECTION (DECL, RELOC)) \
109 fprintf (STREAM, "\t.section %s,\"\"\n", (NAME)); \
111 fprintf (STREAM, "\t.section %s,\"w\"\n", (NAME)); \
114 /* Support the ctors/dtors and other sections. */
116 #undef INIT_SECTION_ASM_OP
118 /* Define this macro if jump tables (for `tablejump' insns) should be
119 output in the text section, along with the assembler instructions.
120 Otherwise, the readonly data section is used. */
121 #define JUMP_TABLES_IN_TEXT_SECTION 1
123 #undef READONLY_DATA_SECTION
124 #define READONLY_DATA_SECTION rdata_section
125 #undef RDATA_SECTION_ASM_OP
126 #define RDATA_SECTION_ASM_OP "\t.section .rdata"
128 #undef CTORS_SECTION_ASM_OP
129 #define CTORS_SECTION_ASM_OP "\t.section .ctors,\"x\""
130 #undef DTORS_SECTION_ASM_OP
131 #define DTORS_SECTION_ASM_OP "\t.section .dtors,\"x\""
133 /* A list of other sections which the compiler might be "in" at any
136 #undef EXTRA_SECTIONS
137 #define EXTRA_SECTIONS SUBTARGET_EXTRA_SECTIONS in_rdata, in_ctors, in_dtors
139 #define SUBTARGET_EXTRA_SECTIONS
141 /* A list of extra section function definitions. */
143 #undef EXTRA_SECTION_FUNCTIONS
144 #define EXTRA_SECTION_FUNCTIONS \
145 RDATA_SECTION_FUNCTION \
146 CTORS_SECTION_FUNCTION \
147 DTORS_SECTION_FUNCTION \
148 SUBTARGET_EXTRA_SECTION_FUNCTIONS
150 #define SUBTARGET_EXTRA_SECTION_FUNCTIONS
152 #define RDATA_SECTION_FUNCTION \
156 if (in_section != in_rdata) \
158 fprintf (asm_out_file, "%s\n", RDATA_SECTION_ASM_OP); \
159 in_section = in_rdata; \
163 #define CTORS_SECTION_FUNCTION \
167 if (in_section != in_ctors) \
169 fprintf (asm_out_file, "%s\n", CTORS_SECTION_ASM_OP); \
170 in_section = in_ctors; \
174 #define DTORS_SECTION_FUNCTION \
178 if (in_section != in_dtors) \
180 fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP); \
181 in_section = in_dtors; \
185 /* Support the ctors/dtors sections for g++. */
187 #define INT_ASM_OP ".word"
189 /* A C statement (sans semicolon) to output an element in the table of
190 global constructors. */
191 #undef ASM_OUTPUT_CONSTRUCTOR
192 #define ASM_OUTPUT_CONSTRUCTOR(STREAM,NAME) \
195 fprintf (STREAM, "\t%s\t ", INT_ASM_OP); \
196 assemble_name (STREAM, NAME); \
197 fprintf (STREAM, "\n"); \
200 /* A C statement (sans semicolon) to output an element in the table of
201 global destructors. */
202 #undef ASM_OUTPUT_DESTRUCTOR
203 #define ASM_OUTPUT_DESTRUCTOR(STREAM,NAME) \
206 fprintf (STREAM, "\t%s\t ", INT_ASM_OP); \
207 assemble_name (STREAM, NAME); \
208 fprintf (STREAM, "\n"); \
211 /* __CTOR_LIST__ and __DTOR_LIST__ must be defined by the linker script. */
212 #define CTOR_LISTS_DEFINED_EXTERNALLY
214 #undef DO_GLOBAL_CTORS_BODY
215 #undef DO_GLOBAL_DTORS_BODY
217 /* The ARM development system has atexit and doesn't have _exit,
218 so define this for now. */
221 /* The ARM development system defines __main. */
222 #define NAME__MAIN "__gccmain"
223 #define SYMBOL__MAIN __gccmain
225 /* This is to better conform to the ARM PCS.
226 Richard Earnshaw hasn't put this into FSF sources yet so it's here. */
227 #undef RETURN_IN_MEMORY
228 #define RETURN_IN_MEMORY(TYPE) \
229 ((TYPE_MODE ((TYPE)) == BLKmode && ! TYPE_NO_FORCE_BLK (TYPE)) \
230 || (AGGREGATE_TYPE_P ((TYPE)) && arm_pe_return_in_memory ((TYPE))))
232 /* A C expression whose value is nonzero if IDENTIFIER with arguments ARGS
233 is a valid machine specific attribute for DECL.
234 The attributes in ATTRIBUTES have previously been assigned to DECL. */
235 extern int arm_pe_valid_machine_decl_attribute ();
236 #undef VALID_MACHINE_DECL_ATTRIBUTE
237 #define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \
238 arm_pe_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
240 extern union tree_node * arm_pe_merge_machine_decl_attributes ();
241 #define MERGE_MACHINE_DECL_ATTRIBUTES(OLD, NEW) \
242 arm_pe_merge_machine_decl_attributes ((OLD), (NEW))
244 /* In addition to the stuff done in arm.h, we must mark dll symbols specially.
245 Definitions of dllexport'd objects install some info in the .drectve
246 section. References to dllimport'd objects are fetched indirectly via
247 __imp_. If both are declared, dllexport overrides.
248 This is also needed to implement one-only vtables: they go into their own
249 section and we need to set DECL_SECTION_NAME so we do that here.
250 Note that we can be called twice on the same decl. */
251 extern void arm_pe_encode_section_info ();
252 #undef ENCODE_SECTION_INFO
253 #define ENCODE_SECTION_INFO(DECL) \
254 arm_pe_encode_section_info (DECL)
256 #define REDO_SECTION_INFO_P(DECL) 1
258 /* Utility used only in this file. */
259 #define ARM_STRIP_NAME_ENCODING(SYM_NAME) \
260 ((SYM_NAME) + ((SYM_NAME)[0] == '@' ? 3 : 0))
262 /* Strip any text from SYM_NAME added by ENCODE_SECTION_INFO and store
263 the result in VAR. */
264 #undef STRIP_NAME_ENCODING
265 #define STRIP_NAME_ENCODING(VAR, SYM_NAME) \
266 (VAR) = ARM_STRIP_NAME_ENCODING (SYM_NAME)
268 /* Define this macro if in some cases global symbols from one translation
269 unit may not be bound to undefined symbols in another translation unit
270 without user intervention. For instance, under Microsoft Windows
271 symbols must be explicitly imported from shared libraries (DLLs). */
272 #define MULTIPLE_SYMBOL_SPACES
274 #define UNIQUE_SECTION_P(DECL) DECL_ONE_ONLY (DECL)
275 extern void arm_pe_unique_section ();
276 #define UNIQUE_SECTION(DECL,RELOC) arm_pe_unique_section (DECL, RELOC)
278 #define SUPPORTS_ONE_ONLY 1
280 /* A C statement to output something to the assembler file to switch to section
281 NAME for object DECL which is either a FUNCTION_DECL, a VAR_DECL or
282 NULL_TREE. Some target formats do not support arbitrary sections. Do not
283 define this macro in such cases. */
284 #undef ASM_OUTPUT_SECTION_NAME
285 #define ASM_OUTPUT_SECTION_NAME(STREAM, DECL, NAME, RELOC) \
287 if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL) \
288 fprintf (STREAM, "\t.section %s,\"x\"\n", (NAME)); \
289 else if ((DECL) && DECL_READONLY_SECTION (DECL, RELOC)) \
290 fprintf (STREAM, "\t.section %s,\"\"\n", (NAME)); \
292 fprintf (STREAM, "\t.section %s,\"w\"\n", (NAME)); \
293 /* Functions may have been compiled at various levels of \
294 optimization so we can't use `same_size' here. Instead, \
295 have the linker pick one. */ \
296 if ((DECL) && DECL_ONE_ONLY (DECL)) \
297 fprintf (STREAM, "\t.linkonce %s\n", \
298 TREE_CODE (DECL) == FUNCTION_DECL \
299 ? "discard" : "same_size"); \
302 /* This outputs a lot of .req's to define alias for various registers.
303 Let's try to avoid this. */
304 #undef ASM_FILE_START
305 #define ASM_FILE_START(STREAM) \
307 extern char * version_string; \
308 fprintf (STREAM, "%s Generated by gcc %s for ARM/pe\n", \
309 ASM_COMMENT_START, version_string); \
310 output_file_directive ((STREAM), main_input_filename); \
313 /* Output a reference to a label. */
314 #undef ASM_OUTPUT_LABELREF
315 #define ASM_OUTPUT_LABELREF(STREAM, NAME) \
316 fprintf (STREAM, "%s%s", USER_LABEL_PREFIX, ARM_STRIP_NAME_ENCODING (NAME))
318 /* Output a function definition label. */
319 #undef ASM_DECLARE_FUNCTION_NAME
320 #define ASM_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL) \
322 if (arm_dllexport_name_p (NAME)) \
324 drectve_section (); \
325 fprintf (STREAM, "\t.ascii \" -export:%s\"\n", \
326 ARM_STRIP_NAME_ENCODING (NAME)); \
327 function_section (DECL); \
329 if (! is_called_in_ARM_mode (decl)) \
330 fprintf (STREAM, "\t.thumb_func\n") ; \
332 fprintf (STREAM, "\t.code\t32\n") ; \
333 ASM_OUTPUT_LABEL ((STREAM), (NAME)); \
336 /* Output a common block. */
337 #undef ASM_OUTPUT_COMMON
338 #define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
340 if (arm_dllexport_name_p (NAME)) \
342 drectve_section (); \
343 fprintf ((STREAM), "\t.ascii \" -export:%s\"\n", \
344 ARM_STRIP_NAME_ENCODING (NAME)); \
346 if (! arm_dllimport_name_p (NAME)) \
348 fprintf ((STREAM), "\t.comm\t"); \
349 assemble_name ((STREAM), (NAME)); \
350 fprintf ((STREAM), ", %d\t%s %d\n", \
351 (ROUNDED), ASM_COMMENT_START, (SIZE)); \
355 /* Output the label for an initialized variable. */
356 #undef ASM_DECLARE_OBJECT_NAME
357 #define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL) \
359 if (arm_dllexport_name_p (NAME)) \
361 enum in_section save_section = in_section; \
362 drectve_section (); \
363 fprintf (STREAM, "\t.ascii \" -export:%s\"\n", \
364 ARM_STRIP_NAME_ENCODING (NAME)); \
365 switch_to_section (save_section, (DECL)); \
367 ASM_OUTPUT_LABEL ((STREAM), (NAME)); \
370 /* Support the ctors/dtors and other sections. */
372 #define DRECTVE_SECTION_ASM_OP "\t.section .drectve"
374 /* A list of other sections which the compiler might be "in" at any
377 #undef SUBTARGET_EXTRA_SECTIONS
378 #define SUBTARGET_EXTRA_SECTIONS in_drectve,
380 /* A list of extra section function definitions. */
382 #undef SUBTARGET_EXTRA_SECTION_FUNCTIONS
383 #define SUBTARGET_EXTRA_SECTION_FUNCTIONS \
384 DRECTVE_SECTION_FUNCTION \
385 SWITCH_TO_SECTION_FUNCTION
387 #define DRECTVE_SECTION_FUNCTION \
391 if (in_section != in_drectve) \
393 fprintf (asm_out_file, "%s\n", DRECTVE_SECTION_ASM_OP); \
394 in_section = in_drectve; \
398 /* Switch to SECTION (an `enum in_section').
400 ??? This facility should be provided by GCC proper.
401 The problem is that we want to temporarily switch sections in
402 ASM_DECLARE_OBJECT_NAME and then switch back to the original section
404 #define SWITCH_TO_SECTION_FUNCTION \
406 switch_to_section (section, decl) \
407 enum in_section section; \
412 case in_text: text_section (); break; \
413 case in_data: data_section (); break; \
414 case in_named: named_section (decl, NULL, 0); break; \
415 case in_rdata: rdata_section (); break; \
416 case in_ctors: ctors_section (); break; \
417 case in_dtors: dtors_section (); break; \
418 case in_drectve: drectve_section (); break; \
419 default: abort (); break; \
425 extern int thumb_pe_valid_machine_decl_attribute ();