OSDN Git Service

General tidyup of header files.
[pf3gnuchains/gcc-fork.git] / gcc / config / arm / tpe.h
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).
5
6 This file is part of GNU CC.
7
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)
11 any later version.
12
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.
17
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.  */
22
23 #include "arm/thumb.h"
24 \f
25 #define THUMB_PE 1
26
27 /* Run-time Target Specification.  */
28 #undef  TARGET_VERSION
29 #define TARGET_VERSION fputs (" (Thumb/pe)", stderr)
30 \f
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
37    existing args.  */
38 #undef  CPP_PREDEFINES
39 #define CPP_PREDEFINES "\
40 -Dthumb -D__thumb -D__pe__ -Acpu(arm) -Amachine(arm) \
41 -D__declspec(x)=__attribute__((x)) \
42 "
43
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)
48
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, "" }, 
53
54 #undef  TARGET_DEFAULT
55 #define TARGET_DEFAULT ARM_FLAG_NOP_FUN_IMPORT
56 \f
57 #undef  WCHAR_TYPE
58 #define WCHAR_TYPE "short unsigned int"
59 #undef  WCHAR_TYPE_SIZE
60 #define WCHAR_TYPE_SIZE 16
61 \f
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
65    value.  */
66 #undef  STRUCTURE_SIZE_BOUNDARY
67 #define STRUCTURE_SIZE_BOUNDARY arm_structure_size_boundary
68
69 extern int arm_structure_size_boundary;
70 \f
71 /* This is COFF, but prefer stabs.  */
72 #define SDB_DEBUGGING_INFO
73
74 #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
75
76 #include "dbxcoff.h"
77 \f
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 "."
81
82 #undef  USER_LABEL_PREFIX
83 #define USER_LABEL_PREFIX "_"
84
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
87    compiler).  */
88 #define ASM_IDENTIFY_GCC(STREAM)                                \
89      fprintf (STREAM, "%sgcc2_compiled.:\n%s", LOCAL_LABEL_PREFIX, ASM_APP_OFF )
90
91 #undef  ASM_FILE_START
92 #define ASM_FILE_START(STREAM) \
93 do {                                                            \
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);                              \
98 } while (0)
99
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) \
105 do {                                                            \
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));           \
110   else                                                          \
111     fprintf (STREAM, "\t.section %s,\"w\"\n", (NAME));          \
112 } while (0)
113 \f
114 /* Support the ctors/dtors and other sections.  */
115
116 #undef INIT_SECTION_ASM_OP
117
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
122
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"
127
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\""
132
133 /* A list of other sections which the compiler might be "in" at any
134    given time.  */
135
136 #undef  EXTRA_SECTIONS
137 #define EXTRA_SECTIONS SUBTARGET_EXTRA_SECTIONS in_rdata, in_ctors, in_dtors
138
139 #define SUBTARGET_EXTRA_SECTIONS
140
141 /* A list of extra section function definitions.  */
142
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
149
150 #define SUBTARGET_EXTRA_SECTION_FUNCTIONS
151
152 #define RDATA_SECTION_FUNCTION \
153 void                                                                    \
154 rdata_section ()                                                        \
155 {                                                                       \
156   if (in_section != in_rdata)                                           \
157     {                                                                   \
158       fprintf (asm_out_file, "%s\n", RDATA_SECTION_ASM_OP);             \
159       in_section = in_rdata;                                            \
160     }                                                                   \
161 }
162
163 #define CTORS_SECTION_FUNCTION \
164 void                                                                    \
165 ctors_section ()                                                        \
166 {                                                                       \
167   if (in_section != in_ctors)                                           \
168     {                                                                   \
169       fprintf (asm_out_file, "%s\n", CTORS_SECTION_ASM_OP);             \
170       in_section = in_ctors;                                            \
171     }                                                                   \
172 }
173
174 #define DTORS_SECTION_FUNCTION \
175 void                                                                    \
176 dtors_section ()                                                        \
177 {                                                                       \
178   if (in_section != in_dtors)                                           \
179     {                                                                   \
180       fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP);             \
181       in_section = in_dtors;                                            \
182     }                                                                   \
183 }
184 \f
185 /* Support the ctors/dtors sections for g++.  */
186
187 #define INT_ASM_OP ".word"
188
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) \
193 do {                                            \
194   ctors_section ();                             \
195   fprintf (STREAM, "\t%s\t ", INT_ASM_OP);      \
196   assemble_name (STREAM, NAME);                 \
197   fprintf (STREAM, "\n");                       \
198 } while (0)
199
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) \
204 do {                                            \
205   dtors_section ();                             \
206   fprintf (STREAM, "\t%s\t ", INT_ASM_OP);      \
207   assemble_name (STREAM, NAME);                 \
208   fprintf (STREAM, "\n");                       \
209 } while (0)
210
211 /* __CTOR_LIST__ and __DTOR_LIST__ must be defined by the linker script.  */
212 #define CTOR_LISTS_DEFINED_EXTERNALLY
213
214 #undef DO_GLOBAL_CTORS_BODY
215 #undef DO_GLOBAL_DTORS_BODY
216
217 /* The ARM development system has atexit and doesn't have _exit,
218    so define this for now.  */
219 #define HAVE_ATEXIT
220
221 /* The ARM development system defines __main.  */
222 #define NAME__MAIN "__gccmain"
223 #define SYMBOL__MAIN __gccmain
224 \f
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))))
231 \f
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)
239
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))
243
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)
255
256 #define REDO_SECTION_INFO_P(DECL) 1
257      
258      /* Utility used only in this file.  */
259 #define ARM_STRIP_NAME_ENCODING(SYM_NAME) \
260 ((SYM_NAME) + ((SYM_NAME)[0] == '@' ? 3 : 0))
261
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)
267
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
273
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)
277
278 #define SUPPORTS_ONE_ONLY 1
279
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)      \
286 do {                                                            \
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));           \
291   else                                                          \
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");                        \
300 } while (0)
301 \f
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) \
306 do {                                                            \
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);        \
311 } while (0)
312
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))
317
318 /* Output a function definition label.  */
319 #undef  ASM_DECLARE_FUNCTION_NAME
320 #define ASM_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL) \
321 do {                                                    \
322   if (arm_dllexport_name_p (NAME))                      \
323     {                                                   \
324       drectve_section ();                               \
325       fprintf (STREAM, "\t.ascii \" -export:%s\"\n",    \
326                ARM_STRIP_NAME_ENCODING (NAME));         \
327       function_section (DECL);                          \
328     }                                                   \
329   if (! is_called_in_ARM_mode (decl))                   \
330     fprintf (STREAM, "\t.thumb_func\n") ;               \
331   else                                                  \
332     fprintf (STREAM, "\t.code\t32\n") ;                 \
333   ASM_OUTPUT_LABEL ((STREAM), (NAME));                  \
334 } while (0)
335
336 /* Output a common block.  */
337 #undef  ASM_OUTPUT_COMMON
338 #define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
339 do {                                                    \
340   if (arm_dllexport_name_p (NAME))                      \
341     {                                                   \
342       drectve_section ();                               \
343       fprintf ((STREAM), "\t.ascii \" -export:%s\"\n",  \
344                ARM_STRIP_NAME_ENCODING (NAME));         \
345     }                                                   \
346   if (! arm_dllimport_name_p (NAME))                    \
347     {                                                   \
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));   \
352     }                                                   \
353 } while (0)
354
355 /* Output the label for an initialized variable.  */
356 #undef  ASM_DECLARE_OBJECT_NAME
357 #define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL) \
358 do {                                                    \
359   if (arm_dllexport_name_p (NAME))                      \
360     {                                                   \
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));         \
366     }                                                   \
367   ASM_OUTPUT_LABEL ((STREAM), (NAME));                  \
368 } while (0)
369 \f
370 /* Support the ctors/dtors and other sections.  */
371
372 #define DRECTVE_SECTION_ASM_OP  "\t.section .drectve"
373
374 /* A list of other sections which the compiler might be "in" at any
375    given time.  */
376
377 #undef  SUBTARGET_EXTRA_SECTIONS
378 #define SUBTARGET_EXTRA_SECTIONS in_drectve,
379
380 /* A list of extra section function definitions.  */
381
382 #undef  SUBTARGET_EXTRA_SECTION_FUNCTIONS
383 #define SUBTARGET_EXTRA_SECTION_FUNCTIONS \
384   DRECTVE_SECTION_FUNCTION      \
385   SWITCH_TO_SECTION_FUNCTION
386
387 #define DRECTVE_SECTION_FUNCTION \
388 void                                                                    \
389 drectve_section ()                                                      \
390 {                                                                       \
391   if (in_section != in_drectve)                                         \
392     {                                                                   \
393       fprintf (asm_out_file, "%s\n", DRECTVE_SECTION_ASM_OP);           \
394       in_section = in_drectve;                                          \
395     }                                                                   \
396 }
397
398 /* Switch to SECTION (an `enum in_section').
399
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
403    afterwards.  */
404 #define SWITCH_TO_SECTION_FUNCTION \
405 void \
406 switch_to_section (section, decl) \
407      enum in_section section; \
408      tree decl; \
409 { \
410   switch (section) \
411     { \
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; \
420     } \
421 }
422
423
424 \f
425 extern int thumb_pe_valid_machine_decl_attribute ();