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