1  /* Output variables, constants and external declarations, for GNU compiler.
       2     Copyright (C) 1996-2023 Free Software Foundation, Inc.
       3  
       4  This file is part of GCC.
       5  
       6  GCC 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 3, or (at your option)
       9  any later version.
      10  
      11  GCC 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 GCC; see the file COPYING3.  If not see
      18  <http://www.gnu.org/licenses/>.  */
      19  
      20  /* Alpha/VMS object format is not really Elf, but this makes compiling
      21     crtstuff.c and dealing with shared library initialization much easier.  */
      22  #define OBJECT_FORMAT_ELF
      23  
      24  /* Do not use TM clone registry as it currently doesn't work.  Alpha/VMS
      25     object is too far from ELF for supporting TM out of the box.  */
      26  #define USE_TM_CLONE_REGISTRY 0
      27  
      28  /* This enables certain macros in alpha.h, which will make an indirect
      29     reference to an external symbol an invalid address.  This needs to be
      30     defined before we include alpha.h, since it determines which macros
      31     are used for GO_IF_*.  */
      32  
      33  #define NO_EXTERNAL_INDIRECT_ADDRESS
      34  
      35  #define SUBTARGET_OS_CPP_BUILTINS()		\
      36      do {					\
      37        builtin_define ("__ALPHA");		\
      38        if (TARGET_FLOAT_VAX)			\
      39          builtin_define ("__G_FLOAT");		\
      40        else					\
      41          builtin_define ("__IEEE_FLOAT");	\
      42      } while (0)
      43  
      44  #undef PCC_STATIC_STRUCT_RETURN
      45  
      46  #define MAX_OFILE_ALIGNMENT 524288  /* 8 x 2^16 by DEC Ada Test CD40VRA */
      47  
      48  /* The maximum alignment 'malloc' honors.  */
      49  #undef  MALLOC_ABI_ALIGNMENT
      50  #define MALLOC_ABI_ALIGNMENT \
      51    ((flag_vms_malloc64 && flag_vms_pointer_size != VMS_POINTER_SIZE_NONE \
      52     ? 16 : 8) * BITS_PER_UNIT)
      53  
      54  #undef FIXED_REGISTERS
      55  #define FIXED_REGISTERS  \
      56   {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
      57    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, \
      58    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
      59    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }
      60  
      61  #undef CALL_USED_REGISTERS
      62  #define CALL_USED_REGISTERS  \
      63   {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
      64    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
      65    1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, \
      66    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
      67  
      68  /* List the order in which to allocate registers.  Each register must be
      69     listed once, even those in FIXED_REGISTERS.
      70  
      71     We allocate in the following order:
      72     $f1			(nonsaved floating-point register)
      73     $f10-$f15		(likewise)
      74     $f22-$f30		(likewise)
      75     $f21-$f16		(likewise, but input args)
      76     $f0			(nonsaved, but return value)
      77     $f2-$f9		(saved floating-point registers)
      78     $1			(nonsaved integer registers)
      79     $22-$25		(likewise)
      80     $28			(likewise)
      81     $0			(likewise, but return value)
      82     $21-$16		(likewise, but input args)
      83     $27			(procedure value in OSF, nonsaved in NT)
      84     $2-$8		(saved integer registers)
      85     $9-$14		(saved integer registers)
      86     $26			(return PC)
      87     $15			(frame pointer)
      88     $29			(global pointer)
      89     $30, $31, $f31	(stack pointer and always zero/ap & fp)  */
      90  
      91  #undef REG_ALLOC_ORDER
      92  #define REG_ALLOC_ORDER		\
      93    {33,					\
      94     42, 43, 44, 45, 46, 47,		\
      95     54, 55, 56, 57, 58, 59, 60, 61, 62,	\
      96     53, 52, 51, 50, 49, 48,		\
      97     32,					\
      98     34, 35, 36, 37, 38, 39, 40, 41,	\
      99     1,					\
     100     22, 23, 24, 25,			\
     101     28,					\
     102     0,					\
     103     21, 20, 19, 18, 17, 16,		\
     104     27,					\
     105     2, 3, 4, 5, 6, 7, 8,			\
     106     9, 10, 11, 12, 13, 14,		\
     107     26,					\
     108     15,					\
     109     29,					\
     110     30, 31, 63 }
     111  
     112  #undef HARD_FRAME_POINTER_REGNUM
     113  #define HARD_FRAME_POINTER_REGNUM 29
     114  
     115  /* Define registers used by the epilogue and return instruction.  */
     116  #undef EPILOGUE_USES
     117  #define EPILOGUE_USES(REGNO)    ((REGNO) == 26 || (REGNO) == 29)
     118  
     119  #undef INITIAL_ELIMINATION_OFFSET
     120  #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)			\
     121    ((OFFSET) = alpha_vms_initial_elimination_offset(FROM, TO))
     122  
     123  
     124  /* Define a data type for recording info about an argument list
     125     during the scan of that argument list.  This data type should
     126     hold all necessary information about the function itself
     127     and about the args processed so far, enough to enable macros
     128     such as FUNCTION_ARG to determine where the next arg should go.
     129  
     130     On Alpha/VMS, this is a structure that contains the number of
     131     arguments and, for each argument, the datatype of that argument.
     132  
     133     The number of arguments is a number of words of arguments scanned so far.
     134     Thus 6 or more means all following args should go on the stack.  */
     135  
     136  enum avms_arg_type {I64, FF, FD, FG, FS, FT};
     137  typedef struct {int num_args; enum avms_arg_type atypes[6];} avms_arg_info;
     138  
     139  #undef CUMULATIVE_ARGS
     140  #define CUMULATIVE_ARGS avms_arg_info
     141  
     142  /* Initialize a variable CUM of type CUMULATIVE_ARGS
     143     for a call to a function whose data type is FNTYPE.
     144     For a library call, FNTYPE is 0.  */
     145  
     146  #undef INIT_CUMULATIVE_ARGS
     147  #define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
     148    do                                                                       \
     149      {                                                                      \
     150        (CUM).num_args = 0;                                                  \
     151        (CUM).atypes[0] = (CUM).atypes[1] = (CUM).atypes[2] = I64;           \
     152        (CUM).atypes[3] = (CUM).atypes[4] = (CUM).atypes[5] = I64;           \
     153      }                                                                      \
     154    while (0)
     155  
     156  #define DEFAULT_PCC_STRUCT_RETURN 0
     157  
     158  /* Even though pointers are 64bits, only 32bit ever remain significant in code
     159     addresses.  */
     160  #define MASK_RETURN_ADDR                                \
     161    (flag_vms_pointer_size == VMS_POINTER_SIZE_NONE       \
     162     ? constm1_rtx                                        \
     163     : GEN_INT (0xffffffff))
     164  
     165  #undef  ASM_WEAKEN_LABEL
     166  #define ASM_WEAKEN_LABEL(FILE, NAME)                            \
     167     do { fputs ("\t.weak\t", FILE); assemble_name (FILE, NAME);  \
     168          fputc ('\n', FILE); } while (0)
     169  
     170  #define READONLY_DATA_SECTION_ASM_OP "\t.rdata"
     171  #define CTORS_SECTION_ASM_OP "\t.ctors"
     172  #define DTORS_SECTION_ASM_OP "\t.dtors"
     173  #define SDATA_SECTION_ASM_OP "\t.sdata"
     174  #define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC)              \
     175     asm (SECTION_OP "\n\t.long " #FUNC"\n");
     176  
     177  #undef ASM_OUTPUT_ADDR_DIFF_ELT
     178  
     179  #undef ASM_OUTPUT_ADDR_VEC_ELT
     180  #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
     181    fprintf (FILE, "\t.quad $L%d\n", (VALUE))
     182  
     183  #undef CASE_VECTOR_MODE
     184  #define CASE_VECTOR_MODE DImode
     185  #undef CASE_VECTOR_PC_RELATIVE
     186  
     187  #undef ASM_OUTPUT_CASE_LABEL
     188  #define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN)	\
     189  { ASM_OUTPUT_ALIGN (FILE, 3); (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM); }
     190  
     191  /* This says how to output assembler code to declare an                
     192     uninitialized external linkage data object.  */ 
     193  
     194  #define COMMON_ASM_OP "\t.comm\t"
     195  
     196  #undef ASM_OUTPUT_ALIGNED_DECL_COMMON
     197  #define ASM_OUTPUT_ALIGNED_DECL_COMMON(FILE, DECL, NAME, SIZE, ALIGN) \
     198    vms_output_aligned_decl_common (FILE, DECL, NAME, SIZE, ALIGN)
     199  
     200  /* Control how constructors and destructors are emitted.  */
     201  #define TARGET_ASM_CONSTRUCTOR  vms_asm_out_constructor
     202  #define TARGET_ASM_DESTRUCTOR   vms_asm_out_destructor
     203  
     204  #define DWARF2_DEBUGGING_INFO 1
     205  #define VMS_DEBUGGING_INFO 1
     206  
     207  #define DWARF2_UNWIND_INFO 1
     208  
     209  #undef EH_RETURN_HANDLER_RTX
     210  #define EH_RETURN_HANDLER_RTX \
     211    gen_rtx_MEM (Pmode, plus_constant (Pmode, stack_pointer_rtx, 8))
     212  
     213  #define LINK_EH_SPEC "vms-dwarf2eh.o%s "
     214  #define LINK_GCC_C_SEQUENCE_SPEC "%G"
     215  
     216  /* This is how to output an assembler line
     217     that says to advance the location counter
     218     to a multiple of 2**LOG bytes.  */
     219  
     220  #define ASM_OUTPUT_ALIGN(FILE,LOG)	\
     221      fprintf (FILE, "\t.align %d\n", LOG);
     222  
     223  /* This is how to advance the location counter by SIZE bytes.  */
     224  
     225  #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
     226    fprintf (FILE, "\t.space " HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE))
     227  
     228  /* This says how to output an assembler line
     229     to define a global common symbol.  */
     230  
     231  #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE,ROUNDED)	\
     232  ( fputs ("\t.lcomm ", (FILE)),				\
     233    assemble_name ((FILE), (NAME)),			\
     234    fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE)))
     235  
     236  /* Switch into a generic section.  */
     237  #define TARGET_ASM_NAMED_SECTION vms_asm_named_section
     238  
     239  #define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2)      \
     240    do                                            \
     241      {                                           \
     242        fprintf ((FILE), "\t");                   \
     243        assemble_name (FILE, LABEL1);             \
     244        fprintf (FILE, " = ");                    \
     245        assemble_name (FILE, LABEL2);             \
     246        fprintf (FILE, "\n");                     \
     247      }                                           \
     248   while (0)
     249  
     250  #undef PREFERRED_DEBUGGING_TYPE
     251  #define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
     252  
     253  #define ASM_PN_FORMAT "%s___%lu"
     254  
     255  /* ??? VMS uses different linkage.  */
     256  #undef TARGET_ASM_OUTPUT_MI_THUNK
     257  
     258  #undef ASM_SPEC
     259  #undef ASM_FINAL_SPEC
     260  
     261  /* The VMS convention is to always provide minimal debug info
     262     for a traceback unless specifically overridden.
     263  
     264     Because ASM_OUTPUT_ADDR_DIFF_ELT is not defined for alpha-vms,
     265     jump tables cannot be output for PIC code, because you can't put
     266     an absolute address in a readonly section.  Putting the table in
     267     a writable section is a security hole.  Therefore, we unset the
     268     flag_jump_tables flag, forcing switch statements to be expanded
     269     using decision trees.  There are probably other ways to address
     270     this issue, but using a decision tree is clearly safe.  */
     271  
     272  #undef SUBTARGET_OVERRIDE_OPTIONS
     273  #define SUBTARGET_OVERRIDE_OPTIONS                  \
     274  do {                                                \
     275    if (write_symbols == NO_DEBUG                     \
     276        && debug_info_level == DINFO_LEVEL_NONE)      \
     277      {                                               \
     278        write_symbols = VMS_DEBUG;                    \
     279        debug_info_level = DINFO_LEVEL_TERSE;         \
     280      }                                               \
     281    if (flag_pic)                                     \
     282      flag_jump_tables = 0;                           \
     283  } while (0)
     284  
     285  #undef LINK_SPEC
     286  #if HAVE_GNU_LD
     287  /* GNU-ld built-in linker script already handles the dwarf2 debug sections.  */
     288  #define LINK_SPEC "%{shared} %{v}"
     289  #else
     290  /* Link with vms-dwarf2.o if -g (except -g0). This causes the
     291     VMS link to pull all the dwarf2 debug sections together.  */
     292  #define LINK_SPEC "%{g0} %{g*:-g vms-dwarf2.o%s} %{shared} %{v} %{map}"
     293  #endif
     294  
     295  #undef STARTFILE_SPEC
     296  #define STARTFILE_SPEC "%{!shared:crt0.o%s crtbegin.o%s} \
     297   %{!static:%{shared:crtbeginS.o%s}}"
     298  
     299  #define ENDFILE_SPEC "%{!shared:crtend.o%s} %{!static:%{shared:crtendS.o%s}}"
     300  
     301  #define INIT_SECTION_ASM_OP "\t.section LIB$INITIALIZE,GBL,NOWRT"
     302  
     303  #define LONGLONG_STANDALONE 1
     304  
     305  #undef TARGET_VALID_POINTER_MODE
     306  #define TARGET_VALID_POINTER_MODE vms_valid_pointer_mode
     307  
     308  /* Default values for _CRTL_VER and _VMS_VER.  */
     309  #define VMS_DEFAULT_CRTL_VER 70320000
     310  #define VMS_DEFAULT_VMS_VER 70320000