OSDN Git Service

* config/pa/som.h (NM_FLAGS): Define.
[pf3gnuchains/gcc-fork.git] / gcc / config / pa / som.h
1 /* Definitions for SOM assembler support.
2    Copyright (C) 1999 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
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.
10
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.
15
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.  */
20
21 /* So we can conditionalize small amounts of code in pa.c or pa.md.  */
22 #define OBJ_SOM
23
24 /* We do not use BINCL stabs in SOM.
25    ??? If it does not hurt, we probably should to avoid useless divergence
26    from other embedded stabs implementations.  */
27 #undef DBX_USE_BINCL
28
29 /* We make the first line stab special to avoid adding several
30    gross hacks to GAS.  */
31 #undef  ASM_OUTPUT_SOURCE_LINE
32 #define ASM_OUTPUT_SOURCE_LINE(file, line)              \
33   { static int sym_lineno = 1;                          \
34     static tree last_function_decl = NULL;              \
35     if (current_function_decl == last_function_decl)    \
36       fprintf (file, "\t.stabn 68,0,%d,L$M%d-%s\nL$M%d:\n",     \
37                line, sym_lineno,                        \
38                XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0) + 1, \
39                sym_lineno);                             \
40     else                                                \
41       fprintf (file, "\t.stabn 68,0,%d,0\n", line);     \
42     last_function_decl = current_function_decl;         \
43     sym_lineno += 1; }
44
45 /* gdb needs a null N_SO at the end of each file for scattered loading. */
46
47 #undef  DBX_OUTPUT_MAIN_SOURCE_FILE_END
48 #define DBX_OUTPUT_MAIN_SOURCE_FILE_END(FILE, FILENAME) \
49   text_section (); \
50   fputs ("\t.SPACE $TEXT$\n\t.NSUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY\n", FILE); \
51   fprintf (FILE,                                                        \
52            "\t.stabs \"\",%d,0,0,L$text_end0000\nL$text_end0000:\n", N_SO)
53
54 /* The HP supplied NM will print out the subspace names for each symbol it
55    finds, which can cause false matches when looking for ctors/dtors.  The
56    "-p" argument changes the output to not include subspace names.  */
57 #define NM_FLAGS "-p -n"
58
59 /* HPUX has a program 'chatr' to list the dependencies of dynamically
60    linked executables and shared libraries.  */
61 #define LDD_SUFFIX "chatr"
62 /* Look for lines like "dynamic   /usr/lib/X11R5/libX11.sl"
63    or "static    /usr/lib/X11R5/libX11.sl". 
64
65    HPUX 10.20 also has lines like "static branch prediction ..."
66    so we filter that out explicitly.
67
68    We also try to bound our search for libraries with marker
69    lines.  What a pain.  */
70 #define PARSE_LDD_OUTPUT(PTR)                                   \
71 do {                                                            \
72   static int in_shlib_list = 0;                                 \
73   while (*PTR == ' ') PTR++;                                    \
74   if (strncmp (PTR, "shared library list:",                     \
75                sizeof ("shared library list:") - 1) == 0)       \
76     {                                                           \
77       PTR = 0;                                                  \
78       in_shlib_list = 1;                                        \
79     }                                                           \
80   else if (strncmp (PTR, "shared library binding:",             \
81                     sizeof ("shared library binding:") - 1) == 0)\
82     {                                                           \
83       PTR = 0;                                                  \
84       in_shlib_list = 0;                                        \
85     }                                                           \
86   else if (strncmp (PTR, "static branch prediction disabled",   \
87                     sizeof ("static branch prediction disabled") - 1) == 0)\
88     {                                                           \
89       PTR = 0;                                                  \
90       in_shlib_list = 0;                                        \
91     }                                                           \
92   else if (in_shlib_list                                        \
93            &&  strncmp (PTR, "dynamic", sizeof ("dynamic") - 1) == 0) \
94     {                                                           \
95       PTR += sizeof ("dynamic") - 1;                            \
96       while (*p == ' ') PTR++;                                  \
97     }                                                           \
98   else if (in_shlib_list                                        \
99            && strncmp (PTR, "static", sizeof ("static") - 1) == 0) \
100     {                                                           \
101       PTR += sizeof ("static") - 1;                             \
102       while (*p == ' ') PTR++;                                  \
103     }                                                           \
104   else                                                          \
105     PTR = 0;                                                    \
106 } while (0)
107
108 /* Output the label for a function definition.  */
109 #ifndef HP_FP_ARG_DESCRIPTOR_REVERSED
110 #define ASM_DOUBLE_ARG_DESCRIPTORS(FILE, ARG0, ARG1)    \
111   do { fprintf (FILE, ",ARGW%d=FR", (ARG0));            \
112        fprintf (FILE, ",ARGW%d=FU", (ARG1));} while (0)
113 #define DFMODE_RETURN_STRING ",RTNVAL=FU"
114 #define SFMODE_RETURN_STRING ",RTNVAL=FR"
115 #else
116 #define ASM_DOUBLE_ARG_DESCRIPTORS(FILE, ARG0, ARG1)    \
117   do { fprintf (FILE, ",ARGW%d=FU", (ARG0));            \
118        fprintf (FILE, ",ARGW%d=FR", (ARG1));} while (0)
119 #define DFMODE_RETURN_STRING ",RTNVAL=FR"
120 #define SFMODE_RETURN_STRING ",RTNVAL=FU"
121 #endif
122
123 \f
124 /* NAME refers to the function's name.  If we are placing each function into
125    its own section, we need to switch to the section for this function.  Note
126    that the section name will have a "." prefix.  */
127 #define ASM_OUTPUT_FUNCTION_PREFIX(FILE, NAME) \
128   {                                                                     \
129     const char *name;                                                   \
130     STRIP_NAME_ENCODING (name, NAME);                                   \
131     if (TARGET_GAS && in_section == in_text)                            \
132       fputs ("\t.NSUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY\n", FILE); \
133     else if (TARGET_GAS)                                                \
134       fprintf (FILE,                                                    \
135                "\t.SUBSPA .%.30s\n", name);                             \
136   }
137     
138 #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
139     do { tree fntype = TREE_TYPE (TREE_TYPE (DECL));                    \
140          tree tree_type = TREE_TYPE (DECL);                             \
141          tree parm;                                                     \
142          int i;                                                         \
143          if (TREE_PUBLIC (DECL) || TARGET_GAS)                          \
144            {                                                            \
145              if (TREE_PUBLIC (DECL))                                    \
146                {                                                        \
147                  fputs ("\t.EXPORT ", FILE);                            \
148                  assemble_name (FILE, NAME);                            \
149                  fputs (",ENTRY,PRIV_LEV=3", FILE);                     \
150                }                                                        \
151              else                                                       \
152                {                                                        \
153                  fputs ("\t.PARAM ", FILE);                             \
154                  assemble_name (FILE, NAME);                            \
155                  fputs (",PRIV_LEV=3", FILE);                           \
156                }                                                        \
157              for (parm = DECL_ARGUMENTS (DECL), i = 0; parm && i < 4;   \
158                   parm = TREE_CHAIN (parm))                             \
159                {                                                        \
160                  if (TYPE_MODE (DECL_ARG_TYPE (parm)) == SFmode         \
161                      && ! TARGET_SOFT_FLOAT)                            \
162                    fprintf (FILE, ",ARGW%d=FR", i++);                   \
163                  else if (TYPE_MODE (DECL_ARG_TYPE (parm)) == DFmode    \
164                           && ! TARGET_SOFT_FLOAT)                       \
165                    {                                                    \
166                      if (i <= 2)                                        \
167                        {                                                \
168                          if (i == 1) i++;                               \
169                          ASM_DOUBLE_ARG_DESCRIPTORS (FILE, i++, i++);   \
170                        }                                                \
171                      else                                               \
172                        break;                                           \
173                    }                                                    \
174                  else                                                   \
175                    {                                                    \
176                      int arg_size =                                     \
177                        FUNCTION_ARG_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)),\
178                                           DECL_ARG_TYPE (parm));        \
179                      /* Passing structs by invisible reference uses     \
180                         one general register.  */                       \
181                      if (arg_size > 2                                   \
182                          || TREE_ADDRESSABLE (DECL_ARG_TYPE (parm)))    \
183                        arg_size = 1;                                    \
184                      if (arg_size == 2 && i <= 2)                       \
185                        {                                                \
186                          if (i == 1) i++;                               \
187                          fprintf (FILE, ",ARGW%d=GR", i++);             \
188                          fprintf (FILE, ",ARGW%d=GR", i++);             \
189                        }                                                \
190                      else if (arg_size == 1)                            \
191                        fprintf (FILE, ",ARGW%d=GR", i++);               \
192                      else                                               \
193                        i += arg_size;                                   \
194                    }                                                    \
195                }                                                        \
196              /* anonymous args */                                       \
197              if ((TYPE_ARG_TYPES (tree_type) != 0                       \
198                   && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (tree_type)))\
199                       != void_type_node))                               \
200                  || current_function_varargs)                           \
201                {                                                        \
202                  for (; i < 4; i++)                                     \
203                    fprintf (FILE, ",ARGW%d=GR", i);                     \
204                }                                                        \
205              if (TYPE_MODE (fntype) == DFmode && ! TARGET_SOFT_FLOAT)   \
206                fputs (DFMODE_RETURN_STRING, FILE);                      \
207              else if (TYPE_MODE (fntype) == SFmode && ! TARGET_SOFT_FLOAT) \
208                fputs (SFMODE_RETURN_STRING, FILE);                      \
209              else if (fntype != void_type_node)                         \
210                fputs (",RTNVAL=GR", FILE);                              \
211              fputs ("\n", FILE);                                        \
212            }} while (0)
213
214 /* Output at beginning of assembler file.  */
215
216 #define ASM_FILE_START(FILE) \
217 do {  \
218      if (TARGET_PA_20) \
219        fputs("\t.LEVEL 2.0\n", FILE); \
220      else if (TARGET_PA_11) \
221        fputs("\t.LEVEL 1.1\n", FILE); \
222      else \
223        fputs("\t.LEVEL 1.0\n", FILE); \
224      fputs ("\t.SPACE $PRIVATE$\n\
225 \t.SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31\n\
226 \t.SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82\n\
227 \t.SPACE $TEXT$\n\
228 \t.SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44\n\
229 \t.SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY\n\
230 \t.IMPORT $global$,DATA\n\
231 \t.IMPORT $$dyncall,MILLICODE\n", FILE);\
232      if (profile_flag)\
233        fprintf (FILE, "\t.IMPORT _mcount, CODE\n");\
234      if (write_symbols != NO_DEBUG) \
235        output_file_directive ((FILE), main_input_filename); \
236    } while (0)
237
238 /* Output before code.  */
239
240 /* Supposedly the assembler rejects the command if there is no tab!  */
241 #define TEXT_SECTION_ASM_OP "\t.SPACE $TEXT$\n\t.SUBSPA $CODE$\n"
242
243 /* Output before read-only data.  */
244
245 /* Supposedly the assembler rejects the command if there is no tab!  */
246 #define READONLY_DATA_ASM_OP "\t.SPACE $TEXT$\n\t.SUBSPA $LIT$\n"
247
248 #define READONLY_DATA_SECTION readonly_data
249
250 /* Output before writable data.  */
251
252 /* Supposedly the assembler rejects the command if there is no tab!  */
253 #define DATA_SECTION_ASM_OP "\t.SPACE $PRIVATE$\n\t.SUBSPA $DATA$\n"
254
255 /* Output before uninitialized data.  */
256
257 #define BSS_SECTION_ASM_OP "\t.SPACE $PRIVATE$\n\t.SUBSPA $BSS$\n"
258
259 /* Define the .bss section for ASM_OUTPUT_LOCAL to use. */
260
261 #ifndef CTORS_SECTION_FUNCTION
262 #define EXTRA_SECTIONS in_readonly_data
263 #define CTORS_SECTION_FUNCTION
264 #define DTORS_SECTION_FUNCTION
265 #else
266 #define EXTRA_SECTIONS in_readonly_data, in_ctors, in_dtors
267 #endif
268
269 /* Switch into a generic section.
270    This is currently only used to support section attributes.
271
272    We make the section read-only and executable for a function decl,
273    read-only for a const data decl, and writable for a non-const data decl.  */
274 #define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC) \
275   if (DECL && TREE_CODE (DECL) == FUNCTION_DECL)                \
276     {                                                           \
277       fputs ("\t.SPACE $TEXT$\n", FILE);                        \
278       if (TARGET_GAS)                                           \
279         fprintf (FILE,                                          \
280                "\t.NSUBSPA %.31s,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY,SORT=24\n", NAME);\
281       else                                                      \
282         fprintf (FILE,                                          \
283                "\t.NSUBSPA $%.29s$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY,SORT=24\n", NAME);\
284     }                                                           \
285   else if (!RELOC && DECL && DECL_READONLY_SECTION (DECL, RELOC))\
286     {                                                           \
287       fputs ("\t.SPACE $TEXT$\n", FILE);                        \
288       fprintf (FILE,                                            \
289                "\t.NSUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44,SORT=16\n");\
290     }                                                           \
291   else                                                          \
292     {                                                           \
293       fputs ("\t.SPACE $PRIVATE$\n", FILE);                     \
294       fprintf (FILE,                                            \
295                "\t.NSUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31,SORT=16\n");\
296     }
297
298 /* FIXME: HPUX ld generates incorrect GOT entries for "T" fixups
299    which reference data within the $TEXT$ space (for example constant
300    strings in the $LIT$ subspace).
301
302    The assemblers (GAS and HP as) both have problems with handling
303    the difference of two symbols which is the other correct way to
304    reference constant data during PIC code generation.
305
306    So, there's no way to reference constant data which is in the
307    $TEXT$ space during PIC generation.  Instead place all constant
308    data into the $PRIVATE$ subspace (this reduces sharing, but it
309    works correctly).  */
310
311 #define EXTRA_SECTION_FUNCTIONS                                         \
312 void                                                                    \
313 readonly_data ()                                                        \
314 {                                                                       \
315   if (in_section != in_readonly_data)                                   \
316     {                                                                   \
317       if (flag_pic)                                                     \
318         fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);            \
319       else                                                              \
320         fprintf (asm_out_file, "%s\n", READONLY_DATA_ASM_OP);           \
321       in_section = in_readonly_data;                                    \
322     }                                                                   \
323 }                                                                       \
324 CTORS_SECTION_FUNCTION                                                  \
325 DTORS_SECTION_FUNCTION
326
327 /* This is how to output a command to make the user-level label named NAME
328    defined for reference from other files.
329
330    We call assemble_name, which in turn sets TREE_SYMBOL_REFERENCED.  This
331    macro will restore the original value of TREE_SYMBOL_REFERENCED to avoid
332    placing useless function definitions in the output file.
333
334    Also note that the SOM based tools need the symbol imported as a CODE
335    symbol, while the ELF based tools require the symbol to be imported as
336    an ENTRY symbol.  What a crock.  */
337
338 #define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME)   \
339   do { int save_referenced;                                     \
340        save_referenced = TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (DECL)); \
341        fputs ("\t.IMPORT ", FILE);                                      \
342          assemble_name (FILE, NAME);                            \
343        if (FUNCTION_NAME_P (NAME))                              \
344          fputs (",CODE\n", FILE);                               \
345        else                                                     \
346          fputs (",DATA\n", FILE);                               \
347        TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (DECL)) = save_referenced; \
348      } while (0)
349
350 /* The bogus HP assembler requires ALL external references to be
351    "imported", even library calls. They look a bit different, so
352    here's this macro.
353
354    Also note not all libcall names are passed to ENCODE_SECTION_INFO
355    (__main for example).  To make sure all libcall names have section
356    info recorded in them, we do it here.  */
357
358 #define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, RTL) \
359   do { fputs ("\t.IMPORT ", FILE);                                      \
360        if (!function_label_operand (RTL, VOIDmode))                     \
361          hppa_encode_label (RTL);                                       \
362        assemble_name (FILE, XSTR ((RTL), 0));                           \
363        fputs (",CODE\n", FILE);                                         \
364      } while (0)
365
366 #define ASM_FILE_END(FILE) output_deferred_plabels (FILE)
367
368 /* We want __gcc_plt_call to appear in every program built by
369    gcc, so we make a reference to it out of __main.
370    We use the asm statement to fool the optimizer into not
371    removing the dead (but important) initialization of
372    REFERENCE.  */
373
374 #define DO_GLOBAL_DTORS_BODY                    \
375 do {                                            \
376   extern void __gcc_plt_call ();                \
377   void (*reference)() = &__gcc_plt_call;        \
378   func_ptr *p;                                  \
379   __asm__ ("" : : "r" (reference));             \
380   for (p = __DTOR_LIST__ + 1; *p; )             \
381     (*p++) ();                                  \
382 } while (0)
383
384 /* The .align directive in the HP assembler allows up to a 32 alignment.  */
385 #define MAX_OFILE_ALIGNMENT 32768
386
387 /* This has been disabled for now.  As best as I call tell we are not
388    following the proper conventions for secondary definitions as we
389    do not emit a duplicate symbol with '_' prefix for each secondary
390    definition.  This appears to be the cause of HP's tools core
391    dumping and the dynamic linker reporting undefined symbols.  */
392 #if 0
393 #ifdef HAVE_GAS_WEAK
394 #define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1)
395
396 /* This is how we tell the assembler that a symbol is weak.  */
397
398 #define ASM_WEAKEN_LABEL(FILE,NAME) \
399   do { fputs ("\t.weak\t", FILE); \
400        assemble_name (FILE, NAME); \
401        fputc ('\n', FILE); \
402        if (! FUNCTION_NAME_P (NAME)) \
403          { \
404            fputs ("\t.EXPORT ", FILE); \
405            assemble_name (FILE, NAME); \
406            fputs (",DATA\n", FILE); \
407          } \
408   } while (0)
409 #endif
410 #endif
411
412 /* SOM does not support the init_priority C++ attribute.  */
413 #undef SUPPORTS_INIT_PRIORITY
414 #define SUPPORTS_INIT_PRIORITY 0
415