vms.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. /* Definitions of target machine GNU compiler. 32bit VMS version.
  2. Copyright (C) 2009-2015 Free Software Foundation, Inc.
  3. Contributed by Douglas B Rupp (rupp@gnat.com).
  4. This file is part of GCC.
  5. GCC is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3, or (at your option)
  8. any later version.
  9. GCC is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with GCC; see the file COPYING3. If not see
  15. <http://www.gnu.org/licenses/>. */
  16. #include "config.h"
  17. #include "system.h"
  18. #include "coretypes.h"
  19. #include "hash-set.h"
  20. #include "machmode.h"
  21. #include "vec.h"
  22. #include "double-int.h"
  23. #include "input.h"
  24. #include "alias.h"
  25. #include "symtab.h"
  26. #include "options.h"
  27. #include "wide-int.h"
  28. #include "inchash.h"
  29. #include "tree.h"
  30. #include "stringpool.h"
  31. #include "vms-protos.h"
  32. #include "ggc.h"
  33. #include "target.h"
  34. #include "output.h"
  35. #include "tm.h"
  36. #include "dwarf2out.h"
  37. /* Correlation of standard CRTL names with DECCRTL function names. */
  38. /* Name is for a function that allocate memory. Use the 64bit version
  39. if -mmalloc64. */
  40. #define VMS_CRTL_MALLOC (1 << 0)
  41. /* If long pointer are enabled, use _NAME64 instead. */
  42. #define VMS_CRTL_64 (1 << 1)
  43. /* Prepend s/f before the name. To be applied after the previous rule.
  44. use 's' for S float, 'f' for IEEE 32. */
  45. #define VMS_CRTL_FLOAT32 (1 << 2)
  46. /* Prepend t/g/d before the name. To be applied after the previous rule.
  47. use 'g' for VAX G float, 'd' for VAX D float, 't' for IEEE 64. */
  48. #define VMS_CRTL_FLOAT64 (1 << 3)
  49. /* Prepend d before the name, only if using VAX fp. */
  50. #define VMS_CRTL_FLOAT64_VAXD (1 << 4)
  51. /* Prepend x before the name for if 128 bit long doubles are enabled. This
  52. concern mostly 'printf'-like functions. */
  53. #define VMS_CRTL_FLOAT128 (1 << 5)
  54. /* From xxx, create xxx, xxxf, xxxl using MATH$XXX_T, MATH$XXX_S
  55. and MATH$XXX{_X} if DPML is used. */
  56. #define VMS_CRTL_DPML (1 << 6)
  57. /* Together with DPML, it means that all variant (ie xxx, xxxf and xxxl) are
  58. overridden by decc. Without DPML, it means this is a variant (ie xxxf
  59. or xxxl) of a function. */
  60. #define VMS_CRTL_NODPML (1 << 7)
  61. /* Prepend __bsd44_ before the name. To be applied after the P64
  62. rule. */
  63. #define VMS_CRTL_BSD44 (1 << 8)
  64. /* Define only in 32 bits mode, as this has no 64 bit variants.
  65. Concerns getopt/getarg. */
  66. #define VMS_CRTL_32ONLY (1 << 9)
  67. /* GLobal data prefix (ga_, gl_...) */
  68. #define VMS_CRTL_G_MASK (7 << 10)
  69. #define VMS_CRTL_G_NONE (0 << 10)
  70. #define VMS_CRTL_GA (1 << 10)
  71. #define VMS_CRTL_GL (2 << 10)
  72. /* Append '_2'. Not compatible with 64. */
  73. #define VMS_CRTL_FLOATV2 (1 << 13)
  74. struct vms_crtl_name
  75. {
  76. /* The standard C name. */
  77. const char *const name;
  78. /* Flags to drive the translation. */
  79. unsigned int flags;
  80. };
  81. /* Map for the translation. */
  82. static const struct vms_crtl_name vms_crtl_names[] =
  83. {
  84. #include "vms-crtlmap.h"
  85. };
  86. /* Number of entires in the above array. */
  87. #define NBR_CRTL_NAMES (sizeof (vms_crtl_names) / sizeof (*vms_crtl_names))
  88. /* List of aliased identifiers. They must be persistent across gc. */
  89. static GTY(()) vec<tree, va_gc> *aliases_id;
  90. /* Add a CRTL translation. This simply use the transparent alias
  91. mechanism, which is platform independent and works with the
  92. #pragma extern_prefix (which set the assembler name). */
  93. static void
  94. vms_add_crtl_xlat (const char *name, size_t nlen,
  95. const char *id_str, size_t id_len)
  96. {
  97. tree targ;
  98. /* printf ("vms crtl: %.*s -> %.*s\n", nlen, name, id_len, id_str); */
  99. targ = get_identifier_with_length (name, nlen);
  100. gcc_assert (!IDENTIFIER_TRANSPARENT_ALIAS (targ));
  101. IDENTIFIER_TRANSPARENT_ALIAS (targ) = 1;
  102. TREE_CHAIN (targ) = get_identifier_with_length (id_str, id_len);
  103. vec_safe_push (aliases_id, targ);
  104. }
  105. /* Do VMS specific stuff on builtins: disable the ones that are not
  106. standard, mangle names. */
  107. void
  108. vms_patch_builtins (void)
  109. {
  110. /* enum built_in_function bi; */
  111. unsigned int i;
  112. /* Fwrite on VMS is non-standard. */
  113. if (builtin_decl_implicit_p (BUILT_IN_FWRITE))
  114. set_builtin_decl_implicit_p (BUILT_IN_FWRITE, false);
  115. if (builtin_decl_implicit_p (BUILT_IN_FWRITE_UNLOCKED))
  116. set_builtin_decl_implicit_p (BUILT_IN_FWRITE_UNLOCKED, false);
  117. /* Define aliases for names. */
  118. for (i = 0; i < NBR_CRTL_NAMES; i++)
  119. {
  120. const struct vms_crtl_name *n = &vms_crtl_names[i];
  121. char res[VMS_CRTL_MAXLEN + 3 + 9 + 1 + 1];
  122. int rlen;
  123. int nlen = strlen (n->name);
  124. /* Discard 32ONLY if using 64 bit pointers. */
  125. if ((n->flags & VMS_CRTL_32ONLY)
  126. && flag_vms_pointer_size == VMS_POINTER_SIZE_64)
  127. continue;
  128. /* Handle DPML unless overridden by decc. */
  129. if ((n->flags & VMS_CRTL_DPML)
  130. && !(n->flags & VMS_CRTL_NODPML))
  131. {
  132. const char *p;
  133. char alt[VMS_CRTL_MAXLEN + 3];
  134. memcpy (res, "MATH$", 5);
  135. rlen = 5;
  136. for (p = n->name; *p; p++)
  137. res[rlen++] = TOUPPER (*p);
  138. res[rlen++] = '_';
  139. res[rlen++] = 'T';
  140. /* Double version. */
  141. if (!(n->flags & VMS_CRTL_FLOAT64))
  142. vms_add_crtl_xlat (n->name, nlen, res, rlen);
  143. /* Float version. */
  144. res[rlen - 1] = 'S';
  145. memcpy (alt, n->name, nlen);
  146. alt[nlen] = 'f';
  147. vms_add_crtl_xlat (alt, nlen + 1, res, rlen);
  148. /* Long double version. */
  149. res[rlen - 1] = (LONG_DOUBLE_TYPE_SIZE == 128 ? 'X' : 'T');
  150. alt[nlen] = 'l';
  151. vms_add_crtl_xlat (alt, nlen + 1, res, rlen);
  152. if (!(n->flags & (VMS_CRTL_FLOAT32 | VMS_CRTL_FLOAT64)))
  153. continue;
  154. }
  155. if (n->flags & VMS_CRTL_FLOAT64_VAXD)
  156. continue;
  157. /* Add the dec-c prefix. */
  158. memcpy (res, "decc$", 5);
  159. rlen = 5;
  160. if (n->flags & VMS_CRTL_BSD44)
  161. {
  162. memcpy (res + rlen, "__bsd44_", 8);
  163. rlen += 8;
  164. }
  165. if ((n->flags & VMS_CRTL_G_MASK) != VMS_CRTL_G_NONE)
  166. {
  167. res[rlen++] = 'g';
  168. switch (n->flags & VMS_CRTL_G_MASK)
  169. {
  170. case VMS_CRTL_GA:
  171. res[rlen++] = 'a';
  172. break;
  173. case VMS_CRTL_GL:
  174. res[rlen++] = 'l';
  175. break;
  176. default:
  177. gcc_unreachable ();
  178. }
  179. res[rlen++] = '_';
  180. }
  181. if (n->flags & VMS_CRTL_FLOAT32)
  182. res[rlen++] = 'f';
  183. if (n->flags & VMS_CRTL_FLOAT64)
  184. res[rlen++] = 't';
  185. if ((n->flags & VMS_CRTL_FLOAT128) && LONG_DOUBLE_TYPE_SIZE == 128)
  186. res[rlen++] = 'x';
  187. memcpy (res + rlen, n->name, nlen);
  188. if ((n->flags & VMS_CRTL_64) == 0)
  189. {
  190. rlen += nlen;
  191. if (n->flags & VMS_CRTL_FLOATV2)
  192. {
  193. res[rlen++] = '_';
  194. res[rlen++] = '2';
  195. }
  196. vms_add_crtl_xlat (n->name, nlen, res, rlen);
  197. }
  198. else
  199. {
  200. char alt[VMS_CRTL_MAXLEN + 3];
  201. bool use_64;
  202. /* Add three translations:
  203. _X32 -> X
  204. _X64 -> _X64
  205. X -> X if short, _X64 if long. */
  206. alt[0] = '_';
  207. memcpy (alt + 1, n->name, nlen);
  208. alt[1 + nlen + 0] = '3';
  209. alt[1 + nlen + 1] = '2';
  210. alt[1 + nlen + 2] = 0;
  211. vms_add_crtl_xlat (alt, nlen + 3, res, rlen + nlen);
  212. use_64 = (((n->flags & VMS_CRTL_64)
  213. && flag_vms_pointer_size == VMS_POINTER_SIZE_64)
  214. || ((n->flags & VMS_CRTL_MALLOC)
  215. && flag_vms_malloc64
  216. && flag_vms_pointer_size != VMS_POINTER_SIZE_NONE));
  217. if (!use_64)
  218. vms_add_crtl_xlat (n->name, nlen, res, rlen + nlen);
  219. res[rlen++] = '_';
  220. memcpy (res + rlen, n->name, nlen);
  221. res[rlen + nlen + 0] = '6';
  222. res[rlen + nlen + 1] = '4';
  223. if (use_64)
  224. vms_add_crtl_xlat (n->name, nlen, res, rlen + nlen + 2);
  225. alt[1 + nlen + 0] = '6';
  226. alt[1 + nlen + 1] = '4';
  227. vms_add_crtl_xlat (alt, nlen + 3, res, rlen + nlen + 2);
  228. }
  229. }
  230. }
  231. /* Always default to .text section. */
  232. section *
  233. vms_function_section (tree decl ATTRIBUTE_UNUSED,
  234. enum node_frequency freq ATTRIBUTE_UNUSED,
  235. bool startup ATTRIBUTE_UNUSED,
  236. bool exit ATTRIBUTE_UNUSED)
  237. {
  238. return NULL;
  239. }
  240. /* Additionnal VMS specific code for start_function. */
  241. /* Must be kept in sync with libgcc/config/vms/vms-ucrt0.c */
  242. #define VMS_MAIN_FLAGS_SYMBOL "__gcc_main_flags"
  243. #define MAIN_FLAG_64BIT (1 << 0)
  244. #define MAIN_FLAG_POSIX (1 << 1)
  245. void
  246. vms_start_function (const char *fnname)
  247. {
  248. #if VMS_DEBUGGING_INFO
  249. if (vms_debug_main
  250. && debug_info_level > DINFO_LEVEL_NONE
  251. && strncmp (vms_debug_main, fnname, strlen (vms_debug_main)) == 0)
  252. {
  253. targetm.asm_out.globalize_label (asm_out_file, VMS_DEBUG_MAIN_POINTER);
  254. ASM_OUTPUT_DEF (asm_out_file, VMS_DEBUG_MAIN_POINTER, fnname);
  255. dwarf2out_vms_debug_main_pointer ();
  256. vms_debug_main = 0;
  257. }
  258. #endif
  259. /* Registers flags used for function main. This is necessary for
  260. crt0 code. */
  261. if (strcmp (fnname, "main") == 0)
  262. {
  263. unsigned int flags = 0;
  264. if (flag_vms_pointer_size == VMS_POINTER_SIZE_64)
  265. flags |= MAIN_FLAG_64BIT;
  266. if (!flag_vms_return_codes)
  267. flags |= MAIN_FLAG_POSIX;
  268. targetm.asm_out.globalize_label (asm_out_file, VMS_MAIN_FLAGS_SYMBOL);
  269. assemble_name (asm_out_file, VMS_MAIN_FLAGS_SYMBOL);
  270. fprintf (asm_out_file, " = %u\n", flags);
  271. }
  272. }
  273. #include "gt-vms.h"