OSDN Git Service

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