f4550b682dbde696e1cbd4cce1af39a6a307e220
[platform/upstream/gcc.git] / gcc / config / ia64 / sysv4.h
1 /* Override definitions in elfos.h/svr4.h to be correct for IA64.  */
2
3 /* We want DWARF2 as specified by the IA64 ABI.  */
4 #undef PREFERRED_DEBUGGING_TYPE
5 #define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
6
7 /* Stabs does not work properly for 64-bit targets.  */
8 #undef DBX_DEBUGGING_INFO
9
10 /* Various pseudo-ops for which the Intel assembler uses non-standard
11    definitions.  */
12
13 #undef STRING_ASM_OP
14 #define STRING_ASM_OP "\tstringz\t"
15
16 #undef SKIP_ASM_OP
17 #define SKIP_ASM_OP "\t.skip\t"
18
19 #undef COMMON_ASM_OP
20 #define COMMON_ASM_OP "\t.common\t"
21
22 #undef ASCII_DATA_ASM_OP
23 #define ASCII_DATA_ASM_OP "\tstring\t"
24
25 /* ia64-specific options for gas
26    ??? ia64 gas doesn't accept standard svr4 assembler options?  */
27 #undef ASM_SPEC
28 #define ASM_SPEC "-x %{mconstant-gp} %{mauto-pic} %(asm_extra)"
29
30 /* ??? Unfortunately, .lcomm doesn't work, because it puts things in either
31    .bss or .sbss, and we can't control the decision of which is used.  When
32    I use .lcomm, I get a cryptic "Section group has no member" error from
33    the Intel simulator.  So we must explicitly put variables in .bss
34    instead.  This matters only if we care about the Intel assembler.  */
35
36 /* This is asm_output_aligned_bss from varasm.c without the ASM_GLOBALIZE_LABEL
37    call at the beginning.  */
38
39 /* This is for final.c, because it is used by ASM_DECLARE_OBJECT_NAME.  */
40 extern int size_directive_output;
41
42 #undef ASM_OUTPUT_ALIGNED_LOCAL
43 #define ASM_OUTPUT_ALIGNED_DECL_LOCAL(FILE, DECL, NAME, SIZE, ALIGN) \
44 do {                                                                    \
45   if ((DECL)                                                            \
46       && XSTR (XEXP (DECL_RTL (DECL), 0), 0)[0] == SDATA_NAME_FLAG_CHAR) \
47     sbss_section ();                                                    \
48   else                                                                  \
49     bss_section ();                                                     \
50   ASM_OUTPUT_ALIGN (FILE, floor_log2 ((ALIGN) / BITS_PER_UNIT));        \
51   ASM_DECLARE_OBJECT_NAME (FILE, NAME, DECL);                           \
52   ASM_OUTPUT_SKIP (FILE, SIZE ? SIZE : 1);                              \
53 } while (0)
54
55 /* The # tells the Intel assembler that this is not a register name.
56    However, we can't emit the # in a label definition, so we set a variable
57    in ASM_OUTPUT_LABEL to control whether we want the postfix here or not.
58    We append the # to the label name, but since NAME can be an expression
59    we have to scan it for a non-label character and insert the # there.  */
60
61 #undef ASM_OUTPUT_LABELREF
62 #define ASM_OUTPUT_LABELREF(STREAM, NAME)       \
63 do {                                            \
64   const char *name_ = NAME;                     \
65   if (*name_ == SDATA_NAME_FLAG_CHAR)           \
66     name_++;                                    \
67   if (*name_ == '*')                            \
68     name_++;                                    \
69   else                                          \
70     fputs (user_label_prefix, STREAM);          \
71   fputs (name_, STREAM);                        \
72   if (!ia64_asm_output_label)                   \
73     fputc ('#', STREAM);                        \
74 } while (0)
75
76 /* Intel assembler requires both flags and type if declaring a non-predefined
77    section.  */
78 #undef INIT_SECTION_ASM_OP
79 #define INIT_SECTION_ASM_OP     "\t.section\t.init,\"ax\",\"progbits\""
80 #undef FINI_SECTION_ASM_OP
81 #define FINI_SECTION_ASM_OP     "\t.section\t.fini,\"ax\",\"progbits\""
82
83 /* svr4.h undefines this, so we need to define it here.  */
84 #define DBX_REGISTER_NUMBER(REGNO) \
85   ia64_dbx_register_number(REGNO)
86
87 /* Things that svr4.h defines to the wrong type, because it assumes 32 bit
88    ints and 32 bit longs.  */
89
90 #undef SIZE_TYPE
91 #define SIZE_TYPE "long unsigned int"
92
93 #undef PTRDIFF_TYPE
94 #define PTRDIFF_TYPE "long int"
95
96 #undef WCHAR_TYPE
97 #define WCHAR_TYPE "int"
98
99 #undef WCHAR_TYPE_SIZE
100 #define WCHAR_TYPE_SIZE 32
101
102 /* We redefine this to use the ia64 .proc pseudo-op.  */
103
104 #undef ASM_DECLARE_FUNCTION_NAME
105 #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
106 do {                                                                    \
107   fputs ("\t.proc ", FILE);                                             \
108   assemble_name (FILE, NAME);                                           \
109   fputc ('\n', FILE);                                                   \
110   ASM_OUTPUT_LABEL (FILE, NAME);                                        \
111 } while (0)
112
113 /* We redefine this to use the ia64 .endp pseudo-op.  */
114
115 #undef ASM_DECLARE_FUNCTION_SIZE
116 #define ASM_DECLARE_FUNCTION_SIZE(FILE, NAME, DECL) \
117 do {                                                                    \
118   fputs ("\t.endp ", FILE);                                             \
119   assemble_name (FILE, NAME);                                           \
120   fputc ('\n', FILE);                                                   \
121 } while (0)
122
123 /* A C expression which outputs to the stdio stream STREAM some appropriate
124    text to go at the start of an assembler file.  */
125
126 /* ??? Looks like almost every port, except for a few original ones, get this
127    wrong.  Must emit #NO_APP as first line of file to turn of special assembler
128    preprocessing of files.  */
129
130 /* ??? Even worse, it doesn't work, because gas does not accept the tab chars
131    that dwarf2out.c emits when #NO_APP.  */
132
133 /* ??? Unrelated, but dwarf2out.c emits unnecessary newlines after strings,
134    may as well fix at the same time.  */
135
136 #undef ASM_FILE_START
137 #define ASM_FILE_START(STREAM) \
138 do {                                                                    \
139   output_file_directive (STREAM, main_input_filename);                  \
140   emit_safe_across_calls (STREAM);                                      \
141 } while (0)
142
143 /* A C statement or statements to switch to the appropriate
144    section for output of DECL.  DECL is either a `VAR_DECL' node
145    or a constant of some sort.  RELOC indicates whether forming
146    the initial value of DECL requires link-time relocations.
147
148    Set SECNUM to:
149         0       .text
150         1       .rodata
151         2       .data
152         3       .sdata
153         4       .bss
154         5       .sbss
155 */
156 #define DO_SELECT_SECTION(SECNUM, DECL, RELOC)                          \
157   do                                                                    \
158     {                                                                   \
159       if (TREE_CODE (DECL) == STRING_CST)                               \
160         {                                                               \
161           if (! flag_writable_strings)                                  \
162             SECNUM = 0x101;                                             \
163           else                                                          \
164             SECNUM = 2;                                                 \
165         }                                                               \
166       else if (TREE_CODE (DECL) == VAR_DECL)                            \
167         {                                                               \
168           if (XSTR (XEXP (DECL_RTL (DECL), 0), 0)[0]                    \
169               == SDATA_NAME_FLAG_CHAR)                                  \
170             SECNUM = 3;                                                 \
171           /* ??? We need the extra RELOC check, because the default     \
172              is to only check RELOC if flag_pic is set, and we don't    \
173              set flag_pic (yet?).  */                                   \
174           else if (!DECL_READONLY_SECTION (DECL, RELOC) || (RELOC))     \
175             SECNUM = 2;                                                 \
176           else if (flag_merge_constants < 2)                            \
177             /* C and C++ don't allow different variables to share       \
178                the same location.  -fmerge-all-constants allows         \
179                even that (at the expense of not conforming).  */        \
180             SECNUM = 1;                                                 \
181           else if (TREE_CODE (DECL_INITIAL (DECL)) == STRING_CST)       \
182             SECNUM = 0x201;                                             \
183           else                                                          \
184             SECNUM = 0x301;                                             \
185         }                                                               \
186       /* This could be a CONSTRUCTOR containing ADDR_EXPR of a VAR_DECL, \
187          in which case we can't put it in a shared library rodata.  */  \
188       else if (flag_pic && (RELOC))                                     \
189         SECNUM = 3;                                                     \
190       else                                                              \
191         SECNUM = 2;                                                     \
192     }                                                                   \
193   while (0)
194
195 /* We override svr4.h so that we can support the sdata section.  */
196
197 #undef SELECT_SECTION
198 #define SELECT_SECTION(DECL,RELOC,ALIGN)                                \
199   do                                                                    \
200     {                                                                   \
201       typedef void (*sec_fn) PARAMS ((void));                           \
202       static sec_fn const sec_functions[6] =                            \
203       {                                                                 \
204         text_section,                                                   \
205         const_section,                                                  \
206         data_section,                                                   \
207         sdata_section,                                                  \
208         bss_section,                                                    \
209         sbss_section                                                    \
210       };                                                                \
211                                                                         \
212       int sec;                                                          \
213                                                                         \
214       DO_SELECT_SECTION (sec, DECL, RELOC);                             \
215                                                                         \
216       switch (sec)                                                      \
217         {                                                               \
218         case 0x101:                                                     \
219           mergeable_string_section (DECL, ALIGN, 0);                    \
220           break;                                                        \
221         case 0x201:                                                     \
222           mergeable_string_section (DECL_INITIAL (DECL),                \
223                                     ALIGN, 0);                          \
224           break;                                                        \
225         case 0x301:                                                     \
226           mergeable_constant_section (DECL_MODE (DECL),                 \
227                                       ALIGN, 0);                        \
228           break;                                                        \
229         default:                                                        \
230           (*sec_functions[sec]) ();                                     \
231           break;                                                        \
232         }                                                               \
233     }                                                                   \
234   while (0)
235
236 #undef  UNIQUE_SECTION
237 #define UNIQUE_SECTION(DECL, RELOC)                                     \
238   do                                                                    \
239     {                                                                   \
240       static const char * const prefixes[6][2] =                        \
241       {                                                                 \
242         { ".text.",   ".gnu.linkonce.t." },                             \
243         { ".rodata.", ".gnu.linkonce.r." },                             \
244         { ".data.",   ".gnu.linkonce.d." },                             \
245         { ".sdata.",  ".gnu.linkonce.s." },                             \
246         { ".bss.",    ".gnu.linkonce.b." },                             \
247         { ".sbss.",   ".gnu.linkonce.sb." }                             \
248       };                                                                \
249                                                                         \
250       int nlen, plen, sec;                                              \
251       const char *name, *prefix;                                        \
252       char *string;                                                     \
253                                                                         \
254       DO_SELECT_SECTION (sec, DECL, RELOC);                             \
255                                                                         \
256       name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL));           \
257       STRIP_NAME_ENCODING (name, name);                                 \
258       nlen = strlen (name);                                             \
259                                                                         \
260       prefix = prefixes[sec & 0xff][DECL_ONE_ONLY(DECL)];               \
261       plen = strlen (prefix);                                           \
262                                                                         \
263       string = alloca (nlen + plen + 1);                                \
264                                                                         \
265       memcpy (string, prefix, plen);                                    \
266       memcpy (string + plen, name, nlen + 1);                           \
267                                                                         \
268       DECL_SECTION_NAME (DECL) = build_string (nlen + plen, string);    \
269     }                                                                   \
270   while (0)
271
272 /* Similarly for constant pool data.  */
273
274 extern unsigned int ia64_section_threshold;
275 #undef SELECT_RTX_SECTION
276 #define SELECT_RTX_SECTION(MODE, RTX, ALIGN)                            \
277 {                                                                       \
278   if (GET_MODE_SIZE (MODE) > 0                                          \
279       && GET_MODE_SIZE (MODE) <= ia64_section_threshold)                \
280     sdata_section ();                                                   \
281   else if (flag_pic && symbolic_operand ((RTX), (MODE)))                \
282     data_section ();                                                    \
283   else                                                                  \
284     mergeable_constant_section ((MODE), (ALIGN), 0);                    \
285 }
286
287 #undef EXTRA_SECTIONS
288 #define EXTRA_SECTIONS in_const, in_sdata, in_sbss
289
290 #undef EXTRA_SECTION_FUNCTIONS
291 #define EXTRA_SECTION_FUNCTIONS                                         \
292   CONST_SECTION_FUNCTION                                                \
293   SDATA_SECTION_FUNCTION                                                \
294   SBSS_SECTION_FUNCTION
295
296 #define SDATA_SECTION_ASM_OP "\t.sdata"
297
298 #define SDATA_SECTION_FUNCTION                                          \
299 void                                                                    \
300 sdata_section ()                                                        \
301 {                                                                       \
302   if (in_section != in_sdata)                                           \
303     {                                                                   \
304       fprintf (asm_out_file, "%s\n", SDATA_SECTION_ASM_OP);             \
305       in_section = in_sdata;                                            \
306     }                                                                   \
307 }
308
309 #define SBSS_SECTION_ASM_OP "\t.sbss"
310
311 #define SBSS_SECTION_FUNCTION                                           \
312 void                                                                    \
313 sbss_section ()                                                         \
314 {                                                                       \
315   if (in_section != in_sbss)                                            \
316     {                                                                   \
317       fprintf (asm_out_file, "%s\n", SBSS_SECTION_ASM_OP);              \
318       in_section = in_sbss;                                             \
319     }                                                                   \
320 }