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