* final.c (HAVE_READONLY_DATA_SECTION): New.
[official-gcc.git] / gcc / config / pa / som.h
blob062fff756f700d7d45356d46e3bead3bb7adae41
1 /* Definitions for SOM assembler support.
2 Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* So we can conditionalize small amounts of code in pa.c or pa.md. */
22 #undef TARGET_SOM
23 #define TARGET_SOM 1
25 /* We do not use BINCL stabs in SOM.
26 ??? If it does not hurt, we probably should to avoid useless divergence
27 from other embedded stabs implementations. */
28 #undef DBX_USE_BINCL
30 /* We make the first line stab special to avoid adding several
31 gross hacks to GAS. */
32 #undef ASM_OUTPUT_SOURCE_LINE
33 #define ASM_OUTPUT_SOURCE_LINE(file, line) \
34 { static int sym_lineno = 1; \
35 static tree last_function_decl = NULL; \
36 if (current_function_decl == last_function_decl) \
37 fprintf (file, "\t.stabn 68,0,%d,L$M%d-%s\nL$M%d:\n", \
38 line, sym_lineno, \
39 XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0) + 1, \
40 sym_lineno); \
41 else \
42 fprintf (file, "\t.stabn 68,0,%d,0\n", line); \
43 last_function_decl = current_function_decl; \
44 sym_lineno += 1; }
46 /* gdb needs a null N_SO at the end of each file for scattered loading. */
48 #undef DBX_OUTPUT_MAIN_SOURCE_FILE_END
49 #define DBX_OUTPUT_MAIN_SOURCE_FILE_END(FILE, FILENAME) \
50 text_section (); \
51 fputs ("\t.SPACE $TEXT$\n\t.NSUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY\n", FILE); \
52 fprintf (FILE, \
53 "\t.stabs \"\",%d,0,0,L$text_end0000\nL$text_end0000:\n", N_SO)
55 /* Select a format to encode pointers in exception handling data. CODE
56 is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is
57 true if the symbol may be affected by dynamic relocations. Because
58 the HP assembler does auto alignment, it is necessary to use
59 DW_EH_PE_aligned instead of the default DW_EH_PE_absptr. */
61 #define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
62 (TARGET_GAS ? DW_EH_PE_absptr : DW_EH_PE_aligned)
64 /* HPUX has a program 'chatr' to list the dependencies of dynamically
65 linked executables and shared libraries. */
66 #define LDD_SUFFIX "chatr"
67 /* Look for lines like "dynamic /usr/lib/X11R5/libX11.sl"
68 or "static /usr/lib/X11R5/libX11.sl".
70 HPUX 10.20 also has lines like "static branch prediction ..."
71 so we filter that out explicitly.
73 We also try to bound our search for libraries with marker
74 lines. What a pain. */
75 #define PARSE_LDD_OUTPUT(PTR) \
76 do { \
77 static int in_shlib_list = 0; \
78 while (*PTR == ' ') PTR++; \
79 if (strncmp (PTR, "shared library list:", \
80 sizeof ("shared library list:") - 1) == 0) \
81 { \
82 PTR = 0; \
83 in_shlib_list = 1; \
84 } \
85 else if (strncmp (PTR, "shared library binding:", \
86 sizeof ("shared library binding:") - 1) == 0)\
87 { \
88 PTR = 0; \
89 in_shlib_list = 0; \
90 } \
91 else if (strncmp (PTR, "static branch prediction disabled", \
92 sizeof ("static branch prediction disabled") - 1) == 0)\
93 { \
94 PTR = 0; \
95 in_shlib_list = 0; \
96 } \
97 else if (in_shlib_list \
98 && strncmp (PTR, "dynamic", sizeof ("dynamic") - 1) == 0) \
99 { \
100 PTR += sizeof ("dynamic") - 1; \
101 while (*p == ' ') PTR++; \
103 else if (in_shlib_list \
104 && strncmp (PTR, "static", sizeof ("static") - 1) == 0) \
106 PTR += sizeof ("static") - 1; \
107 while (*p == ' ') PTR++; \
109 else \
110 PTR = 0; \
111 } while (0)
113 /* Output the label for a function definition. */
114 #ifndef HP_FP_ARG_DESCRIPTOR_REVERSED
115 #define ASM_DOUBLE_ARG_DESCRIPTORS(FILE, ARG0, ARG1) \
116 do { fprintf (FILE, ",ARGW%d=FR", (ARG0)); \
117 fprintf (FILE, ",ARGW%d=FU", (ARG1));} while (0)
118 #define DFMODE_RETURN_STRING ",RTNVAL=FU"
119 #define SFMODE_RETURN_STRING ",RTNVAL=FR"
120 #else
121 #define ASM_DOUBLE_ARG_DESCRIPTORS(FILE, ARG0, ARG1) \
122 do { fprintf (FILE, ",ARGW%d=FU", (ARG0)); \
123 fprintf (FILE, ",ARGW%d=FR", (ARG1));} while (0)
124 #define DFMODE_RETURN_STRING ",RTNVAL=FR"
125 #define SFMODE_RETURN_STRING ",RTNVAL=FU"
126 #endif
129 /* NAME refers to the function's name. If we are placing each function into
130 its own section, we need to switch to the section for this function. Note
131 that the section name will have a "." prefix. */
132 #define ASM_OUTPUT_FUNCTION_PREFIX(FILE, NAME) \
134 const char *name; \
135 STRIP_NAME_ENCODING (name, NAME); \
136 if (TARGET_GAS && in_section == in_text) \
137 fputs ("\t.NSUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY\n", FILE); \
138 else if (TARGET_GAS) \
139 fprintf (FILE, \
140 "\t.SUBSPA .%s\n", name); \
143 #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
144 do { tree fntype = TREE_TYPE (TREE_TYPE (DECL)); \
145 tree tree_type = TREE_TYPE (DECL); \
146 tree parm; \
147 int i; \
148 if (TREE_PUBLIC (DECL) || TARGET_GAS) \
150 if (TREE_PUBLIC (DECL)) \
152 fputs ("\t.EXPORT ", FILE); \
153 assemble_name (FILE, NAME); \
154 fputs (",ENTRY,PRIV_LEV=3", FILE); \
156 else \
158 fputs ("\t.PARAM ", FILE); \
159 assemble_name (FILE, NAME); \
160 fputs (",PRIV_LEV=3", FILE); \
162 for (parm = DECL_ARGUMENTS (DECL), i = 0; parm && i < 4; \
163 parm = TREE_CHAIN (parm)) \
165 if (TYPE_MODE (DECL_ARG_TYPE (parm)) == SFmode \
166 && ! TARGET_SOFT_FLOAT) \
167 fprintf (FILE, ",ARGW%d=FR", i++); \
168 else if (TYPE_MODE (DECL_ARG_TYPE (parm)) == DFmode \
169 && ! TARGET_SOFT_FLOAT) \
171 if (i <= 2) \
173 if (i == 1) i++; \
174 ASM_DOUBLE_ARG_DESCRIPTORS (FILE, i++, i++); \
176 else \
177 break; \
179 else \
181 int arg_size = \
182 FUNCTION_ARG_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)),\
183 DECL_ARG_TYPE (parm)); \
184 /* Passing structs by invisible reference uses \
185 one general register. */ \
186 if (arg_size > 2 \
187 || TREE_ADDRESSABLE (DECL_ARG_TYPE (parm))) \
188 arg_size = 1; \
189 if (arg_size == 2 && i <= 2) \
191 if (i == 1) i++; \
192 fprintf (FILE, ",ARGW%d=GR", i++); \
193 fprintf (FILE, ",ARGW%d=GR", i++); \
195 else if (arg_size == 1) \
196 fprintf (FILE, ",ARGW%d=GR", i++); \
197 else \
198 i += arg_size; \
201 /* anonymous args */ \
202 if ((TYPE_ARG_TYPES (tree_type) != 0 \
203 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (tree_type)))\
204 != void_type_node)) \
205 || current_function_varargs) \
207 for (; i < 4; i++) \
208 fprintf (FILE, ",ARGW%d=GR", i); \
210 if (TYPE_MODE (fntype) == DFmode && ! TARGET_SOFT_FLOAT) \
211 fputs (DFMODE_RETURN_STRING, FILE); \
212 else if (TYPE_MODE (fntype) == SFmode && ! TARGET_SOFT_FLOAT) \
213 fputs (SFMODE_RETURN_STRING, FILE); \
214 else if (fntype != void_type_node) \
215 fputs (",RTNVAL=GR", FILE); \
216 fputs ("\n", FILE); \
217 }} while (0)
219 /* Output at beginning of assembler file. */
221 #define ASM_FILE_START(FILE) \
222 do { \
223 if (TARGET_PA_20) \
224 fputs("\t.LEVEL 2.0\n", FILE); \
225 else if (TARGET_PA_11) \
226 fputs("\t.LEVEL 1.1\n", FILE); \
227 else \
228 fputs("\t.LEVEL 1.0\n", FILE); \
229 fputs ("\t.SPACE $PRIVATE$\n\
230 \t.SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31\n\
231 \t.SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82\n\
232 \t.SPACE $TEXT$\n\
233 \t.SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44\n\
234 \t.SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY\n\
235 \t.IMPORT $global$,DATA\n\
236 \t.IMPORT $$dyncall,MILLICODE\n", FILE);\
237 if (profile_flag)\
238 fprintf (FILE, "\t.IMPORT _mcount, CODE\n");\
239 if (write_symbols != NO_DEBUG) \
240 output_file_directive ((FILE), main_input_filename); \
241 } while (0)
243 /* Output before code. */
245 /* Supposedly the assembler rejects the command if there is no tab! */
246 #define TEXT_SECTION_ASM_OP "\t.SPACE $TEXT$\n\t.SUBSPA $CODE$\n"
248 /* Output before read-only data. */
250 /* Supposedly the assembler rejects the command if there is no tab! */
251 #define READONLY_DATA_ASM_OP "\t.SPACE $TEXT$\n\t.SUBSPA $LIT$\n"
253 #define EXTRA_SECTIONS in_readonly_data
255 #define EXTRA_SECTION_FUNCTIONS \
256 extern void readonly_data PARAMS ((void)); \
257 void \
258 readonly_data () \
260 if (in_section != in_readonly_data) \
262 in_section = in_readonly_data; \
263 fprintf (asm_out_file, "%s\n", READONLY_DATA_ASM_OP); \
267 /* FIXME: HPUX ld generates incorrect GOT entries for "T" fixups
268 which reference data within the $TEXT$ space (for example constant
269 strings in the $LIT$ subspace).
271 The assemblers (GAS and HP as) both have problems with handling
272 the difference of two symbols which is the other correct way to
273 reference constant data during PIC code generation.
275 So, there's no way to reference constant data which is in the
276 $TEXT$ space during PIC generation. Instead place all constant
277 data into the $PRIVATE$ subspace (this reduces sharing, but it
278 works correctly). */
280 #define READONLY_DATA_SECTION (flag_pic ? data_section : readonly_data)
282 /* Output before writable data. */
284 /* Supposedly the assembler rejects the command if there is no tab! */
285 #define DATA_SECTION_ASM_OP "\t.SPACE $PRIVATE$\n\t.SUBSPA $DATA$\n"
287 /* Output before uninitialized data. */
289 #define BSS_SECTION_ASM_OP "\t.SPACE $PRIVATE$\n\t.SUBSPA $BSS$\n"
291 /* We must not have a reference to an external symbol defined in a
292 shared library in a readonly section, else the SOM linker will
293 complain.
295 So, we force exception information into the data section. */
296 #define TARGET_ASM_EXCEPTION_SECTION data_section
298 /* This is how to output a command to make the user-level label named NAME
299 defined for reference from other files.
301 We call assemble_name, which in turn sets TREE_SYMBOL_REFERENCED. This
302 macro will restore the original value of TREE_SYMBOL_REFERENCED to avoid
303 placing useless function definitions in the output file.
305 Also note that the SOM based tools need the symbol imported as a CODE
306 symbol, while the ELF based tools require the symbol to be imported as
307 an ENTRY symbol. What a crock. */
309 #define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
310 do { int save_referenced; \
311 save_referenced = TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (DECL)); \
312 fputs ("\t.IMPORT ", FILE); \
313 assemble_name (FILE, NAME); \
314 if (FUNCTION_NAME_P (NAME)) \
315 fputs (",CODE\n", FILE); \
316 else \
317 fputs (",DATA\n", FILE); \
318 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (DECL)) = save_referenced; \
319 } while (0)
321 /* The bogus HP assembler requires ALL external references to be
322 "imported", even library calls. They look a bit different, so
323 here's this macro.
325 Also note not all libcall names are passed to ENCODE_SECTION_INFO
326 (__main for example). To make sure all libcall names have section
327 info recorded in them, we do it here. We must also ensure that
328 we don't import a libcall that has been previously exported since
329 the HP assembler may change an ENTRY symbol to a CODE symbol. */
331 #define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, RTL) \
332 do { const char *name; \
333 tree id; \
335 if (!function_label_operand (RTL, VOIDmode)) \
336 hppa_encode_label (RTL); \
338 STRIP_NAME_ENCODING (name, XSTR ((RTL), 0)); \
339 id = maybe_get_identifier (name); \
340 if (! id || ! TREE_SYMBOL_REFERENCED (id)) \
342 fputs ("\t.IMPORT ", FILE); \
343 assemble_name (FILE, XSTR ((RTL), 0)); \
344 fputs (",CODE\n", FILE); \
346 } while (0)
348 /* We want __gcc_plt_call to appear in every program built by
349 gcc, so we make a reference to it out of __main.
350 We use the asm statement to fool the optimizer into not
351 removing the dead (but important) initialization of
352 REFERENCE. */
354 #define DO_GLOBAL_DTORS_BODY \
355 do { \
356 extern void __gcc_plt_call (); \
357 void (*reference)() = &__gcc_plt_call; \
358 func_ptr *p; \
359 __asm__ ("" : : "r" (reference)); \
360 for (p = __DTOR_LIST__ + 1; *p; ) \
361 (*p++) (); \
362 } while (0)
364 /* The .align directive in the HP assembler allows up to a 32 alignment. */
365 #define MAX_OFILE_ALIGNMENT 32768
367 /* SOM does not support the init_priority C++ attribute. */
368 #undef SUPPORTS_INIT_PRIORITY
369 #define SUPPORTS_INIT_PRIORITY 0