Mercurial > hg > CbC > CbC_gcc
diff gcc/config/vms/vms.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | |
children | 84e7813d76e9 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gcc/config/vms/vms.c Fri Oct 27 22:46:09 2017 +0900 @@ -0,0 +1,329 @@ +/* Definitions of target machine GNU compiler. 32bit VMS version. + Copyright (C) 2009-2017 Free Software Foundation, Inc. + Contributed by Douglas B Rupp (rupp@gnat.com). + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "target.h" +#include "tree.h" +#include "stringpool.h" +#include "alias.h" +#include "vms-protos.h" +#include "output.h" +#include "dwarf2out.h" + +/* Correlation of standard CRTL names with DECCRTL function names. */ + +/* Name is for a function that allocate memory. Use the 64bit version + if -mmalloc64. */ +#define VMS_CRTL_MALLOC (1 << 0) + +/* If long pointer are enabled, use _NAME64 instead. */ +#define VMS_CRTL_64 (1 << 1) + +/* Prepend s/f before the name. To be applied after the previous rule. + use 's' for S float, 'f' for IEEE 32. */ +#define VMS_CRTL_FLOAT32 (1 << 2) + +/* Prepend t/g/d before the name. To be applied after the previous rule. + use 'g' for VAX G float, 'd' for VAX D float, 't' for IEEE 64. */ +#define VMS_CRTL_FLOAT64 (1 << 3) + +/* Prepend d before the name, only if using VAX fp. */ +#define VMS_CRTL_FLOAT64_VAXD (1 << 4) + +/* Prepend x before the name for if 128 bit long doubles are enabled. This + concern mostly 'printf'-like functions. */ +#define VMS_CRTL_FLOAT128 (1 << 5) + +/* From xxx, create xxx, xxxf, xxxl using MATH$XXX_T, MATH$XXX_S + and MATH$XXX{_X} if DPML is used. */ +#define VMS_CRTL_DPML (1 << 6) + +/* Together with DPML, it means that all variant (ie xxx, xxxf and xxxl) are + overridden by decc. Without DPML, it means this is a variant (ie xxxf + or xxxl) of a function. */ +#define VMS_CRTL_NODPML (1 << 7) + +/* Prepend __bsd44_ before the name. To be applied after the P64 + rule. */ +#define VMS_CRTL_BSD44 (1 << 8) + +/* Define only in 32 bits mode, as this has no 64 bit variants. + Concerns getopt/getarg. */ +#define VMS_CRTL_32ONLY (1 << 9) + +/* GLobal data prefix (ga_, gl_...) */ +#define VMS_CRTL_G_MASK (7 << 10) +#define VMS_CRTL_G_NONE (0 << 10) +#define VMS_CRTL_GA (1 << 10) +#define VMS_CRTL_GL (2 << 10) + +/* Append '_2'. Not compatible with 64. */ +#define VMS_CRTL_FLOATV2 (1 << 13) + +struct vms_crtl_name +{ + /* The standard C name. */ + const char *const name; + + /* Flags to drive the translation. */ + unsigned int flags; +}; + +/* Map for the translation. */ + +static const struct vms_crtl_name vms_crtl_names[] = + { +#include "vms-crtlmap.h" + }; + +/* Number of entires in the above array. */ + +#define NBR_CRTL_NAMES (sizeof (vms_crtl_names) / sizeof (*vms_crtl_names)) + +/* List of aliased identifiers. They must be persistent across gc. */ + +static GTY(()) vec<tree, va_gc> *aliases_id; + +/* Add a CRTL translation. This simply use the transparent alias + mechanism, which is platform independent and works with the + #pragma extern_prefix (which set the assembler name). */ + +static void +vms_add_crtl_xlat (const char *name, size_t nlen, + const char *id_str, size_t id_len) +{ + tree targ; + + /* printf ("vms crtl: %.*s -> %.*s\n", nlen, name, id_len, id_str); */ + + targ = get_identifier_with_length (name, nlen); + gcc_assert (!IDENTIFIER_TRANSPARENT_ALIAS (targ)); + IDENTIFIER_TRANSPARENT_ALIAS (targ) = 1; + TREE_CHAIN (targ) = get_identifier_with_length (id_str, id_len); + + vec_safe_push (aliases_id, targ); +} + +/* Do VMS specific stuff on builtins: disable the ones that are not + standard, mangle names. */ + +void +vms_patch_builtins (void) +{ + /* enum built_in_function bi; */ + unsigned int i; + + /* Fwrite on VMS is non-standard. */ + if (builtin_decl_implicit_p (BUILT_IN_FWRITE)) + set_builtin_decl_implicit_p (BUILT_IN_FWRITE, false); + + if (builtin_decl_implicit_p (BUILT_IN_FWRITE_UNLOCKED)) + set_builtin_decl_implicit_p (BUILT_IN_FWRITE_UNLOCKED, false); + + /* Define aliases for names. */ + for (i = 0; i < NBR_CRTL_NAMES; i++) + { + const struct vms_crtl_name *n = &vms_crtl_names[i]; + char res[VMS_CRTL_MAXLEN + 3 + 9 + 1 + 1]; + int rlen; + int nlen = strlen (n->name); + + /* Discard 32ONLY if using 64 bit pointers. */ + if ((n->flags & VMS_CRTL_32ONLY) + && flag_vms_pointer_size == VMS_POINTER_SIZE_64) + continue; + + /* Handle DPML unless overridden by decc. */ + if ((n->flags & VMS_CRTL_DPML) + && !(n->flags & VMS_CRTL_NODPML)) + { + const char *p; + char alt[VMS_CRTL_MAXLEN + 3]; + + memcpy (res, "MATH$", 5); + rlen = 5; + for (p = n->name; *p; p++) + res[rlen++] = TOUPPER (*p); + res[rlen++] = '_'; + res[rlen++] = 'T'; + + /* Double version. */ + if (!(n->flags & VMS_CRTL_FLOAT64)) + vms_add_crtl_xlat (n->name, nlen, res, rlen); + + /* Float version. */ + res[rlen - 1] = 'S'; + memcpy (alt, n->name, nlen); + alt[nlen] = 'f'; + vms_add_crtl_xlat (alt, nlen + 1, res, rlen); + + /* Long double version. */ + res[rlen - 1] = (LONG_DOUBLE_TYPE_SIZE == 128 ? 'X' : 'T'); + alt[nlen] = 'l'; + vms_add_crtl_xlat (alt, nlen + 1, res, rlen); + + if (!(n->flags & (VMS_CRTL_FLOAT32 | VMS_CRTL_FLOAT64))) + continue; + } + + if (n->flags & VMS_CRTL_FLOAT64_VAXD) + continue; + + /* Add the dec-c prefix. */ + memcpy (res, "decc$", 5); + rlen = 5; + + if (n->flags & VMS_CRTL_BSD44) + { + memcpy (res + rlen, "__bsd44_", 8); + rlen += 8; + } + + if ((n->flags & VMS_CRTL_G_MASK) != VMS_CRTL_G_NONE) + { + res[rlen++] = 'g'; + switch (n->flags & VMS_CRTL_G_MASK) + { + case VMS_CRTL_GA: + res[rlen++] = 'a'; + break; + case VMS_CRTL_GL: + res[rlen++] = 'l'; + break; + default: + gcc_unreachable (); + } + res[rlen++] = '_'; + } + + if (n->flags & VMS_CRTL_FLOAT32) + res[rlen++] = 'f'; + + if (n->flags & VMS_CRTL_FLOAT64) + res[rlen++] = 't'; + + if ((n->flags & VMS_CRTL_FLOAT128) && LONG_DOUBLE_TYPE_SIZE == 128) + res[rlen++] = 'x'; + + memcpy (res + rlen, n->name, nlen); + + if ((n->flags & VMS_CRTL_64) == 0) + { + rlen += nlen; + + if (n->flags & VMS_CRTL_FLOATV2) + { + res[rlen++] = '_'; + res[rlen++] = '2'; + } + vms_add_crtl_xlat (n->name, nlen, res, rlen); + } + else + { + char alt[VMS_CRTL_MAXLEN + 3]; + bool use_64; + + /* Add three translations: + _X32 -> X + _X64 -> _X64 + X -> X if short, _X64 if long. */ + alt[0] = '_'; + memcpy (alt + 1, n->name, nlen); + alt[1 + nlen + 0] = '3'; + alt[1 + nlen + 1] = '2'; + alt[1 + nlen + 2] = 0; + vms_add_crtl_xlat (alt, nlen + 3, res, rlen + nlen); + + use_64 = (((n->flags & VMS_CRTL_64) + && flag_vms_pointer_size == VMS_POINTER_SIZE_64) + || ((n->flags & VMS_CRTL_MALLOC) + && flag_vms_malloc64 + && flag_vms_pointer_size != VMS_POINTER_SIZE_NONE)); + if (!use_64) + vms_add_crtl_xlat (n->name, nlen, res, rlen + nlen); + + res[rlen++] = '_'; + memcpy (res + rlen, n->name, nlen); + res[rlen + nlen + 0] = '6'; + res[rlen + nlen + 1] = '4'; + + if (use_64) + vms_add_crtl_xlat (n->name, nlen, res, rlen + nlen + 2); + + alt[1 + nlen + 0] = '6'; + alt[1 + nlen + 1] = '4'; + vms_add_crtl_xlat (alt, nlen + 3, res, rlen + nlen + 2); + } + } +} + +/* Always default to .text section. */ + +section * +vms_function_section (tree decl ATTRIBUTE_UNUSED, + enum node_frequency freq ATTRIBUTE_UNUSED, + bool startup ATTRIBUTE_UNUSED, + bool exit ATTRIBUTE_UNUSED) +{ + return NULL; +} + +/* Additionnal VMS specific code for start_function. */ + +/* Must be kept in sync with libgcc/config/vms/vms-ucrt0.c */ +#define VMS_MAIN_FLAGS_SYMBOL "__gcc_main_flags" +#define MAIN_FLAG_64BIT (1 << 0) +#define MAIN_FLAG_POSIX (1 << 1) + +void +vms_start_function (const char *fnname) +{ +#if VMS_DEBUGGING_INFO + if (vms_debug_main + && debug_info_level > DINFO_LEVEL_NONE + && strncmp (vms_debug_main, fnname, strlen (vms_debug_main)) == 0) + { + targetm.asm_out.globalize_label (asm_out_file, VMS_DEBUG_MAIN_POINTER); + ASM_OUTPUT_DEF (asm_out_file, VMS_DEBUG_MAIN_POINTER, fnname); + dwarf2out_vms_debug_main_pointer (); + vms_debug_main = 0; + } +#endif + + /* Registers flags used for function main. This is necessary for + crt0 code. */ + if (strcmp (fnname, "main") == 0) + { + unsigned int flags = 0; + + if (flag_vms_pointer_size == VMS_POINTER_SIZE_64) + flags |= MAIN_FLAG_64BIT; + if (!flag_vms_return_codes) + flags |= MAIN_FLAG_POSIX; + + targetm.asm_out.globalize_label (asm_out_file, VMS_MAIN_FLAGS_SYMBOL); + assemble_name (asm_out_file, VMS_MAIN_FLAGS_SYMBOL); + fprintf (asm_out_file, " = %u\n", flags); + } +} + +#include "gt-vms.h"