OSDN Git Service

* alpha.c (output_epilog [!VMS]): Don't tag global functions if
[pf3gnuchains/gcc-fork.git] / gcc / config / alpha / vms.h
1 /* Output variables, constants and external declarations, for GNU compiler.
2    Copyright (C) 1996, 1997 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 #define OPEN_VMS 1
22
23 /* This enables certain macros in alpha.h, which will make an indirect
24    reference to an external symbol an invalid address.  This needs to be
25    defined before we include alpha.h, since it determines which macros
26    are used for GO_IF_*.  */
27
28 #define NO_EXTERNAL_INDIRECT_ADDRESS
29
30 #include "alpha/alpha.h"
31
32 #undef CPP_PREDEFINES
33 #define CPP_PREDEFINES \
34 "-Dalpha -D__ALPHA -Dvms -DVMS -D__alpha__ -D__alpha -D__vms__ -D__VMS__\
35  -Asystem(vms) -Acpu(alpha) -Amachine(alpha)"
36
37 #undef CPP_SPEC
38 #define CPP_SPEC "\
39 %{mfloat-ieee:-D__IEEE_FLOAT} \
40 %{mfloat-vax:-D__G_FLOAT} \
41 %{!mfloat-vax:-D__IEEE_FLOAT} \
42 %{!.S:  -D__LANGUAGE_C__ -D__LANGUAGE_C %{!ansi:-DLANGUAGE_C}}  \
43 %{.S:   -D__LANGUAGE_ASSEMBLY__ -D__LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \
44 %{.cc:  -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS -D__cplusplus} \
45 %{.cxx: -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS -D__cplusplus} \
46 %{.C:   -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS -D__cplusplus} \
47 %{.m:   -D__LANGUAGE_OBJECTIVE_C__ -D__LANGUAGE_OBJECTIVE_C}"
48
49 /* Under OSF4, -p and -pg require -lprof1, and -lprof1 requires -lpdf.  */
50
51 #define LIB_SPEC "%{p:-lprof1 -lpdf} %{pg:-lprof1 -lpdf} %{a:-lprof2} -lc"
52
53 /* Pass "-G 8" to ld because Alpha's CC does.  Pass -O3 if we are
54    optimizing, -O1 if we are not.  Pass -shared, -non_shared or
55    -call_shared as appropriate.  Also pass -pg.  */
56 #define LINK_SPEC  \
57   "-G 8 %{O*:-O3} %{!O*:-O1} %{static:-non_shared} \
58    %{!static:%{shared:-shared} %{!shared:-call_shared}} %{pg} %{taso} \
59    %{rpath*}"
60
61 /* We allow $'s in identifiers unless -ansi is used .. */
62
63 #define DOLLARS_IN_IDENTIFIERS 2
64
65 /* These match the definitions used in DECCRTL, the VMS C run-time library
66
67 #define SIZE_TYPE       "unsigned int"
68 #define PTRDIFF_TYPE    "int"
69 */
70
71 /* Use memcpy for structure copying, and so forth.  */
72 #define TARGET_MEM_FUNCTIONS
73
74 /* By default, allow $ to be part of an identifier.  */
75 #define DOLLARS_IN_IDENTIFIERS 2
76
77 #undef TARGET_DEFAULT
78 #define TARGET_DEFAULT (MASK_FP|MASK_FPREGS|MASK_GAS|MASK_OPEN_VMS)
79 #undef TARGET_NAME   
80 #define TARGET_NAME "OpenVMS/Alpha"
81 #undef TARGET_VERSION
82 #define TARGET_VERSION fprintf (stderr, " (%s)", TARGET_NAME);           
83
84 /* The structure return address arrives as an "argument" on VMS.  */
85 #undef STRUCT_VALUE_REGNUM
86 #define STRUCT_VALUE 0
87 #undef PCC_STATIC_STRUCT_RETURN
88
89 /* no floating emulation.  */
90 #undef REAL_ARITHMETIC
91
92 /* "long" is 32 bits.  */
93 #undef LONG_TYPE_SIZE
94 #define LONG_TYPE_SIZE 32
95
96 /* Pointer is 32 bits but the hardware has 64-bit addresses, sign extended. */
97 #undef POINTER_SIZE
98 #define POINTER_SIZE 32
99 #define POINTERS_EXTEND_UNSIGNED 0
100
101 #define MAX_OFILE_ALIGNMENT 524288  /* 8 x 2^16 by DEC Ada Test CD40VRA */
102
103 #undef FIXED_REGISTERS
104 #define FIXED_REGISTERS  \
105  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
106   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, \
107   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
108   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }
109
110 #undef CALL_USED_REGISTERS
111 #define CALL_USED_REGISTERS  \
112  {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
113   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
114   1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, \
115   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
116
117 #undef HARD_FRAME_POINTER_REGNUM
118 #define HARD_FRAME_POINTER_REGNUM 29
119
120 #undef CAN_ELIMINATE
121 #define CAN_ELIMINATE(FROM, TO)  \
122 ((TO) != STACK_POINTER_REGNUM || ! alpha_using_fp ())
123
124 #undef INITIAL_ELIMINATION_OFFSET
125 #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)                    \
126 { if ((FROM) == FRAME_POINTER_REGNUM)                                   \
127     (OFFSET) = alpha_sa_size () + alpha_pv_save_size ();                \
128   else if ((FROM) == ARG_POINTER_REGNUM)                                \
129     (OFFSET) = (ALPHA_ROUND (alpha_sa_size () + alpha_pv_save_size ()   \
130                              + get_frame_size ()                        \
131                              + current_function_pretend_args_size)      \
132                 - current_function_pretend_args_size);                  \
133   if ((TO) == STACK_POINTER_REGNUM)                                     \
134     (OFFSET) += ALPHA_ROUND (current_function_outgoing_args_size);      \
135 }
136 \f
137 /* Define a data type for recording info about an argument list
138    during the scan of that argument list.  This data type should
139    hold all necessary information about the function itself
140    and about the args processed so far, enough to enable macros
141    such as FUNCTION_ARG to determine where the next arg should go.
142
143    On Alpha/VMS, this is a structure that contains the number of
144    arguments and, for each argument, the datatype of that argument.
145
146    The number of arguments is a number of words of arguments scanned so far.
147    Thus 6 or more means all following args should go on the stack.  */
148
149 enum avms_arg_type {I64, FF, FD, FG, FS, FT};
150 typedef struct {char num_args; enum avms_arg_type atypes[6];} avms_arg_info;
151
152 #undef CUMULATIVE_ARGS
153 #define CUMULATIVE_ARGS avms_arg_info
154
155 /* Initialize a variable CUM of type CUMULATIVE_ARGS
156    for a call to a function whose data type is FNTYPE.
157    For a library call, FNTYPE is 0.  */
158
159 #undef INIT_CUMULATIVE_ARGS
160 #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \
161   (CUM).num_args = 0;                                           \
162   (CUM).atypes[0] = (CUM).atypes[1] = (CUM).atypes[2] = I64;    \
163   (CUM).atypes[3] = (CUM).atypes[4] = (CUM).atypes[5] = I64;
164
165 /* Update the data in CUM to advance over an argument
166    of mode MODE and data type TYPE.
167    (TYPE is null for libcalls where that information may not be available.)  */
168
169 extern enum avms_arg_type alpha_arg_type ();
170
171 /* Determine where to put an argument to a function.
172    Value is zero to push the argument on the stack,
173    or a hard register in which to store the argument.
174
175    MODE is the argument's machine mode (or VOIDmode for no more args).
176    TYPE is the data type of the argument (as a tree).
177     This is null for libcalls where that information may
178     not be available.
179    CUM is a variable of type CUMULATIVE_ARGS which gives info about
180     the preceding args and about the function being called.
181    NAMED is nonzero if this argument is a named parameter
182     (otherwise it is an extra parameter matching an ellipsis).
183
184    On Alpha the first 6 words of args are normally in registers
185    and the rest are pushed.  */
186
187 extern struct rtx_def *alpha_arg_info_reg_val ();
188 #undef FUNCTION_ARG
189 #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED)    \
190 ((MODE) == VOIDmode ? alpha_arg_info_reg_val (CUM)              \
191  : ((CUM.num_args) < 6 && ! MUST_PASS_IN_STACK (MODE, TYPE)     \
192     ? gen_rtx(REG, (MODE),                                      \
193               ((CUM).num_args + 16                              \
194                + ((TARGET_FPREGS                                \
195                    && (GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT \
196                        || GET_MODE_CLASS (MODE) == MODE_FLOAT)) \
197                   * 32)))                       \
198     : 0))
199
200 #undef FUNCTION_ARG_ADVANCE
201 #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)                    \
202   if (MUST_PASS_IN_STACK (MODE, TYPE))                                  \
203     (CUM).num_args += 6;                                                \
204   else                                                                  \
205     {                                                                   \
206       if ((CUM).num_args < 6)                                           \
207         (CUM).atypes[(CUM).num_args] = alpha_arg_type (MODE);           \
208                                                                         \
209      (CUM).num_args += ALPHA_ARG_SIZE (MODE, TYPE, NAMED);              \
210     }
211
212 /* For an arg passed partly in registers and partly in memory,
213    this is the number of registers used.
214    For args passed entirely in registers or entirely in memory, zero.  */
215
216 #undef FUNCTION_ARG_PARTIAL_NREGS
217 #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED)              \
218 ((CUM).num_args < 6 && 6 < (CUM).num_args                               \
219    + ALPHA_ARG_SIZE (MODE, TYPE, NAMED)                                 \
220  ? 6 - (CUM).num_args : 0)
221
222 /* Perform any needed actions needed for a function that is receiving a
223    variable number of arguments. 
224
225    CUM is as for INIT_CUMULATIVE_ARGS.
226
227    MODE and TYPE are the mode and type of the current parameter.
228
229    PRETEND_SIZE is a variable that should be set to the amount of stack
230    that must be pushed by the prolog to pretend that our caller pushed
231    it.
232
233    Normally, this macro will push all remaining incoming registers on the
234    stack and set PRETEND_SIZE to the length of the registers pushed. 
235
236    For VMS, we allocate space for all 6 arg registers plus a count.
237
238    However, if NO registers need to be saved, don't allocate any space.
239    This is not only because we won't need the space, but because AP includes
240    the current_pretend_args_size and we don't want to mess up any
241    ap-relative addresses already made.   */
242
243 #undef SETUP_INCOMING_VARARGS
244 #define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL)       \
245 { if ((CUM).num_args < 6)                               \
246     {                                                   \
247       if (! (NO_RTL))                                   \
248         {                                               \
249           emit_move_insn (gen_rtx (REG, DImode, 1),     \
250                           virtual_incoming_args_rtx);   \
251           emit_insn (gen_arg_home ());                  \
252         }                                               \
253                                                         \
254       PRETEND_SIZE = 7 * UNITS_PER_WORD;                \
255     }                                                   \
256 }
257
258 #undef ASM_FILE_START
259 #define ASM_FILE_START(FILE)                                    \
260 {                                                               \
261   alpha_write_verstamp (FILE);                                  \
262   fprintf (FILE, "\t.set noreorder\n");                         \
263   fprintf (FILE, "\t.set volatile\n");                          \
264   ASM_OUTPUT_SOURCE_FILENAME (FILE, main_input_filename);       \
265 }
266
267 #undef ASM_OUTPUT_FLOAT
268 #define ASM_OUTPUT_FLOAT(FILE,VALUE)                                    \
269   {                                                                     \
270     if (REAL_VALUE_ISINF (VALUE)                                        \
271         || REAL_VALUE_ISNAN (VALUE)                                     \
272         || REAL_VALUE_MINUS_ZERO (VALUE))                               \
273       {                                                                 \
274         long t;                                                         \
275         REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t);                       \
276         fprintf (FILE, "\t.long 0x%lx\n", t & 0xffffffff);              \
277       }                                                                 \
278     else                                                                \
279       {                                                                 \
280         char str[30];                                                   \
281         REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", str);                  \
282         fprintf (FILE, "\t.%c_floating %s\n", (TARGET_FLOAT_VAX)?'f':'s', str); \
283       }                                                                 \
284   }
285
286 #define LINK_SECTION_ASM_OP ".link"
287 #define READONLY_SECTION_ASM_OP ".rdata"
288 #define LITERALS_SECTION_ASM_OP ".literals"
289
290 #undef EXTRA_SECTIONS
291 #define EXTRA_SECTIONS  in_link, in_rdata, in_literals
292
293 #undef EXTRA_SECTION_FUNCTIONS
294 #define EXTRA_SECTION_FUNCTIONS                                 \
295 void                                                            \
296 readonly_section ()                                             \
297 {                                                               \
298   if (in_section != in_rdata)                           \
299     {                                                           \
300       fprintf (asm_out_file, "%s\n", READONLY_SECTION_ASM_OP);  \
301       in_section = in_rdata;                            \
302     }                                                           \
303 }                                                               \
304 void                                                            \
305 link_section ()                                                 \
306 {                                                               \
307   if (in_section != in_link)                                    \
308     {                                                           \
309       fprintf (asm_out_file, "%s\n", LINK_SECTION_ASM_OP);      \
310       in_section = in_link;                                     \
311     }                                                           \
312 }                                                               \
313 void                                                            \
314 literals_section ()                                             \
315 {                                                               \
316   if (in_section != in_literals)                                \
317     {                                                           \
318       fprintf (asm_out_file, "%s\n", LITERALS_SECTION_ASM_OP);  \
319       in_section = in_literals;                                 \
320     }                                                           \
321 }
322
323 #undef ASM_OUTPUT_ADDR_DIFF_ELT
324 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) abort ()
325
326 #undef ASM_OUTPUT_ADDR_VEC_ELT
327 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
328   fprintf (FILE, "\t.quad $L%d\n", (VALUE))
329
330 #undef READONLY_DATA_SECTION
331 #define READONLY_DATA_SECTION readonly_section
332
333 #define ASM_FILE_END(FILE) alpha_write_linkage (FILE);
334
335 #undef CASE_VECTOR_MODE
336 #define CASE_VECTOR_MODE DImode
337 #undef CASE_VECTOR_PC_RELATIVE
338
339 #undef ASM_OUTPUT_CASE_LABEL
340 #define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN)        \
341 { ASM_OUTPUT_ALIGN (FILE, 3); ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); }
342
343 #define NO_MD_PROTOTYPES
344 \f
345 /* Output assembler code for a block containing the constant parts
346    of a trampoline, leaving space for the variable parts.
347
348    The trampoline should set the static chain pointer to value placed
349    into the trampoline and should branch to the specified routine.  
350    Note that $27 has been set to the address of the trampoline, so we can
351    use it for addressability of the two data items.  Trampolines are always
352    aligned to FUNCTION_BOUNDARY, which is 64 bits.  */
353
354 #undef TRAMPOLINE_TEMPLATE
355 #define TRAMPOLINE_TEMPLATE(FILE)               \
356 {                                               \
357   fprintf (FILE, "\t.quad 0\n");                \
358   fprintf (FILE, "\t.linkage __tramp\n");       \
359   fprintf (FILE, "\t.quad 0\n");                \
360 }
361
362 /* Length in units of the trampoline for entering a nested function.  */
363
364 #undef TRAMPOLINE_SIZE
365 #define TRAMPOLINE_SIZE    32
366
367 /* Emit RTL insns to initialize the variable parts of a trampoline.
368    FNADDR is an RTX for the address of the function's pure code.
369    CXT is an RTX for the static chain value for the function.  */
370
371 #undef INITIALIZE_TRAMPOLINE
372 #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT)                         \
373 {                                                                         \
374   emit_move_insn (gen_rtx (MEM, Pmode,                                    \
375                            memory_address (Pmode,                         \
376                                            plus_constant ((TRAMP), 16))), \
377                   (FNADDR));                                              \
378   emit_move_insn (gen_rtx (MEM, Pmode,                                    \
379                            memory_address (Pmode,                         \
380                                            plus_constant ((TRAMP), 24))), \
381                   (CXT));                                                 \
382 }
383
384 #undef TRANSFER_FROM_TRAMPOLINE
385
386 #define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, NAME, ARGS) \
387   (vms_valid_decl_attribute_p (DECL, ATTRIBUTES, NAME, ARGS))
388 extern int vms_valid_decl_attribute_p ();
389
390 #undef SDB_DEBUGGING_INFO
391 #undef MIPS_DEBUGGING_INFO
392 #undef DBX_DEBUGGING_INFO
393
394 #define DWARF2_DEBUGGING_INFO
395
396 /* This is how to output an assembler line
397    that says to advance the location counter
398    to a multiple of 2**LOG bytes.  */
399
400 #undef ASM_OUTPUT_ALIGN
401 #define ASM_OUTPUT_ALIGN(FILE,LOG)      \
402     fprintf (FILE, "\t.align %d\n", LOG);
403
404 #define UNALIGNED_SHORT_ASM_OP  ".word"
405 #define UNALIGNED_INT_ASM_OP    ".long"
406 #define UNALIGNED_DOUBLE_INT_ASM_OP     ".quad"
407
408 #undef ASM_OUTPUT_ALIGNED_COMMON
409 #define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN)              \
410 do {                                                                    \
411   fprintf ((FILE), "\t.comm\t");                                        \
412   assemble_name ((FILE), (NAME));                                       \
413   fprintf ((FILE), ",%u,%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT);        \
414 } while (0)
415
416 #define ASM_OUTPUT_SECTION(FILE,SECTION)                        \
417    (strcmp (SECTION, ".text") == 0)                             \
418      ? text_section ()                                          \
419      : named_section (NULL_TREE, SECTION, 0),                   \
420        ASM_OUTPUT_ALIGN (FILE, 0)                               \
421
422 #define ASM_OUTPUT_SECTION_NAME(FILE,DECL,NAME,RELOC)           \
423   do                                                            \
424     {                                                           \
425       char *flags;                                              \
426       int ovr = 0;                                              \
427       if (DECL && DECL_MACHINE_ATTRIBUTES (DECL)                \
428           && lookup_attribute                                   \
429               ("overlaid", DECL_MACHINE_ATTRIBUTES (DECL)))     \
430         flags = ",OVR", ovr = 1;                                \
431       else if (strncmp (NAME,".debug", 6) == 0)                 \
432         flags = ",NOWRT";                                       \
433       else                                                      \
434         flags = "";                                             \
435       fputc ('\n', (FILE));                                     \
436       fprintf (FILE, ".section\t%s%s\n", NAME, flags);          \
437       if (ovr)                                                  \
438         (NAME) = "";                                            \
439     } while (0)
440
441 #define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2)                              \
442   do {  literals_section();                                             \
443         fprintf ((FILE), "\t");                                         \
444         assemble_name (FILE, LABEL1);                                   \
445         fprintf (FILE, " = ");                                          \
446         assemble_name (FILE, LABEL2);                                   \
447         fprintf (FILE, "\n");                                           \
448   } while (0)
449
450 #undef PREFERRED_DEBUGGING_TYPE
451 #define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
452
453 #undef ASM_FORMAT_PRIVATE_NAME
454 #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO)  \
455 ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 12),    \
456   sprintf ((OUTPUT), "%s___%d", (NAME), (LABELNO)))
457
458 /* ??? VMS uses different linkage.  */
459 #undef ASM_OUTPUT_MI_THUNK
460
461 #undef ASM_SPEC
462 #undef ASM_FINAL_SPEC
463 #undef LINK_SPEC
464 #undef STARTFILE_SPEC
465 #define ASM_SPEC "-nocpp %{pg}"
466 #define LINK_SPEC "%{g3:-g3} %{g0:-g0} %{shared:-shared} %{v:-v}"
467
468 /* Define the names of the division and modulus functions.  */
469 #define DIVSI3_LIBCALL "OTS$DIV_I"
470 #define DIVDI3_LIBCALL "OTS$DIV_L"
471 #define UDIVSI3_LIBCALL "OTS$DIV_UI"
472 #define UDIVDI3_LIBCALL "OTS$DIV_UL"
473 #define MODSI3_LIBCALL "OTS$REM_I"
474 #define MODDI3_LIBCALL "OTS$REM_L"
475 #define UMODSI3_LIBCALL "OTS$REM_UI"
476 #define UMODDI3_LIBCALL "OTS$REM_UL"
477
478 #define DIR_SEPARATOR ']'