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