OSDN Git Service

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