]>
Commit | Line | Data |
---|---|---|
db8b22ef TG |
1 | /* Definitions of target machine GNU compiler. 32bit VMS version. |
2 | Copyright (C) 2009, 2010 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 "tree.h" | |
25 | #include "vms-protos.h" | |
db8b22ef | 26 | #include "ggc.h" |
4b12e93d TG |
27 | #include "target.h" |
28 | #include "output.h" | |
b9268e55 TG |
29 | #include "tm.h" |
30 | #include "dwarf2out.h" | |
db8b22ef TG |
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 | ||
b9268e55 TG |
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) | |
db8b22ef | 44 | |
b9268e55 TG |
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) | |
db8b22ef | 51 | |
17a27c59 TG |
52 | /* Prepend x before the name for if 128 bit long doubles are enabled. This |
53 | concern mostly 'printf'-like functions. */ | |
b9268e55 TG |
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) | |
db8b22ef | 59 | |
b9268e55 TG |
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) | |
7481209d | 81 | |
db8b22ef TG |
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 | ||
073a8998 | 102 | /* List of aliased identifiers. They must be persistent across gc. */ |
db8b22ef TG |
103 | |
104 | static GTY(()) VEC(tree,gc) *aliases_id; | |
105 | ||
106 | /* Add a CRTL translation. This simply use the transparent alias | |
073a8998 | 107 | mechanism, which is platform independent and works with the |
db8b22ef TG |
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 | ||
b9268e55 TG |
116 | /* printf ("vms crtl: %.*s -> %.*s\n", nlen, name, id_len, id_str); */ |
117 | ||
db8b22ef TG |
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 (tree, gc, aliases_id, targ); | |
db8b22ef TG |
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. */ | |
2acb1a01 TG |
136 | if (builtin_decl_implicit_p (BUILT_IN_FWRITE)) |
137 | set_builtin_decl_implicit_p (BUILT_IN_FWRITE, false); | |
e79983f4 | 138 | |
2acb1a01 TG |
139 | if (builtin_decl_implicit_p (BUILT_IN_FWRITE_UNLOCKED)) |
140 | set_builtin_decl_implicit_p (BUILT_IN_FWRITE_UNLOCKED, false); | |
db8b22ef TG |
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; | |
b9268e55 TG |
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; | |
db8b22ef TG |
190 | |
191 | /* Add the dec-c prefix. */ | |
192 | memcpy (res, "decc$", 5); | |
193 | rlen = 5; | |
194 | ||
195 | if (n->flags & VMS_CRTL_BSD44) | |
196 | { | |
b9268e55 TG |
197 | memcpy (res + rlen, "__bsd44_", 8); |
198 | rlen += 8; | |
db8b22ef TG |
199 | } |
200 | ||
b9268e55 | 201 | if ((n->flags & VMS_CRTL_G_MASK) != VMS_CRTL_G_NONE) |
7481209d | 202 | { |
b9268e55 TG |
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++] = '_'; | |
7481209d TG |
216 | } |
217 | ||
b9268e55 TG |
218 | if (n->flags & VMS_CRTL_FLOAT32) |
219 | res[rlen++] = 'f'; | |
220 | ||
221 | if (n->flags & VMS_CRTL_FLOAT64) | |
db8b22ef TG |
222 | res[rlen++] = 't'; |
223 | ||
b9268e55 | 224 | if ((n->flags & VMS_CRTL_FLOAT128) && LONG_DOUBLE_TYPE_SIZE == 128) |
db8b22ef TG |
225 | res[rlen++] = 'x'; |
226 | ||
db8b22ef TG |
227 | memcpy (res + rlen, n->name, nlen); |
228 | ||
229 | if ((n->flags & VMS_CRTL_64) == 0) | |
b9268e55 TG |
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 | } | |
db8b22ef TG |
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 | ||
d8aba32a TG |
256 | use_64 = (((n->flags & VMS_CRTL_64) |
257 | && flag_vms_pointer_size == VMS_POINTER_SIZE_64) | |
db8b22ef | 258 | || ((n->flags & VMS_CRTL_MALLOC) |
d8aba32a TG |
259 | && flag_vms_malloc64 |
260 | && flag_vms_pointer_size != VMS_POINTER_SIZE_NONE)); | |
db8b22ef TG |
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 | ||
916e8d27 TG |
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 | ||
4b12e93d TG |
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 | ||
db8b22ef | 329 | #include "gt-vms.h" |