OSDN Git Service

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