[BRIGFE] Changed pure attributes to const for the brig-builtins
[official-gcc.git] / gcc / brig / brig-lang.c
blob970214b3a3fb2193b1253dc02f5cc57ddf24ece9
1 /* brig-lang.c -- brig (HSAIL) input gcc interface.
2 Copyright (C) 2016-2017 Free Software Foundation, Inc.
3 Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
4 for General Processor Tech.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 #include "config.h"
23 #include "system.h"
24 #include "ansidecl.h"
25 #include "coretypes.h"
26 #include "opts.h"
27 #include "tree.h"
28 #include "tree-iterator.h"
29 #include "print-tree.h"
30 #include "stringpool.h"
31 #include "basic-block.h"
32 #include "gimple-expr.h"
33 #include "gimplify.h"
34 #include "dumpfile.h"
35 #include "stor-layout.h"
36 #include "toplev.h"
37 #include "debug.h"
38 #include "options.h"
39 #include "flags.h"
40 #include "convert.h"
41 #include "diagnostic.h"
42 #include "langhooks.h"
43 #include "langhooks-def.h"
44 #include "target.h"
45 #include "vec.h"
46 #include "brigfrontend/brig-to-generic.h"
47 #include "machmode.h"
48 #include "fold-const.h"
49 #include "common/common-target.h"
50 #include <mpfr.h>
51 #include "brig-c.h"
52 #include "brig-builtins.h"
54 static tree handle_leaf_attribute (tree *, tree, tree, int, bool *);
55 static tree handle_const_attribute (tree *, tree, tree, int, bool *);
56 static tree handle_pure_attribute (tree *, tree, tree, int, bool *);
57 static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *);
58 static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *);
60 /* This file is based on Go frontent'd go-lang.c and gogo-tree.cc. */
62 /* If -v set. */
64 int gccbrig_verbose = 0;
66 /* Language-dependent contents of a type. */
68 struct GTY (()) lang_type
70 char dummy;
73 /* Language-dependent contents of a decl. */
75 struct GTY ((variable_size)) lang_decl
77 char dummy;
80 /* Language-dependent contents of an identifier. This must include a
81 tree_identifier. */
83 struct GTY (()) lang_identifier
85 struct tree_identifier common;
88 /* The resulting tree type. */
90 union GTY ((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
91 chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), "
92 "TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN "
93 "(&%h.generic)) : NULL"))) lang_tree_node
95 union tree_node GTY ((tag ("0"), desc ("tree_node_structure (&%h)"))) generic;
96 struct lang_identifier GTY ((tag ("1"))) identifier;
99 /* We don't use language_function. */
101 struct GTY (()) language_function
103 int dummy;
107 /* The option mask. */
109 static unsigned int
110 brig_langhook_option_lang_mask (void)
112 return CL_BRIG;
115 /* Initialize the options structure. */
117 static void
118 brig_langhook_init_options_struct (struct gcc_options *opts)
120 /* Signed overflow is precisely defined. */
121 opts->x_flag_wrapv = 1;
123 /* If we set this to one, the whole program optimizations internalize
124 all global variables, making them invisible to the dyn loader (and
125 thus the HSA runtime implementation). */
126 opts->x_flag_whole_program = 0;
128 /* The builtin math functions should not set errno. */
129 opts->x_flag_errno_math = 0;
130 opts->frontend_set_flag_errno_math = false;
132 opts->x_flag_exceptions = 0;
133 opts->x_flag_non_call_exceptions = 0;
135 opts->x_flag_finite_math_only = 0;
136 opts->x_flag_signed_zeros = 1;
138 opts->x_optimize = 3;
141 /* Handle Brig specific options. Return 0 if we didn't do anything. */
143 static bool
144 brig_langhook_handle_option
145 (size_t scode, const char *arg ATTRIBUTE_UNUSED,
146 int value ATTRIBUTE_UNUSED, int kind ATTRIBUTE_UNUSED,
147 location_t loc ATTRIBUTE_UNUSED,
148 const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
150 enum opt_code code = (enum opt_code) scode;
151 switch (code)
153 case OPT_v:
154 gccbrig_verbose = 1;
155 break;
156 default:
157 break;
159 return 1;
162 /* Run after parsing options. */
164 static bool
165 brig_langhook_post_options (const char **pfilename ATTRIBUTE_UNUSED)
167 if (flag_excess_precision_cmdline == EXCESS_PRECISION_DEFAULT)
168 flag_excess_precision_cmdline = EXCESS_PRECISION_STANDARD;
170 /* gccbrig casts pointers around like crazy, TBAA produces
171 broken code if not force disabling it. */
172 flag_strict_aliasing = 0;
174 /* Returning false means that the backend should be used. */
175 return false;
178 static size_t
179 get_file_size (FILE *file)
181 size_t size;
182 fseek (file, 0, SEEK_END);
183 size = (size_t) ftell (file);
184 fseek (file, 0, SEEK_SET);
185 return size;
188 static void
189 brig_langhook_parse_file (void)
191 brig_to_generic brig_to_gen;
193 std::vector <char*> brig_blobs;
195 for (unsigned int i = 0; i < num_in_fnames; ++i)
198 FILE *f;
199 f = fopen (in_fnames[i], "r");
200 size_t fsize = get_file_size (f);
201 char *brig_blob = new char[fsize];
202 if (fread (brig_blob, 1, fsize, f) != fsize)
204 error ("could not read the BRIG file");
205 exit (1);
207 fclose (f);
209 brig_to_gen.analyze (brig_blob);
210 brig_blobs.push_back (brig_blob);
213 for (size_t i = 0; i < brig_blobs.size(); ++i)
215 char *brig_blob = brig_blobs.at(i);
216 brig_to_gen.parse (brig_blob);
219 brig_to_gen.write_globals ();
221 for (size_t i = 0; i < brig_blobs.size (); ++i)
222 delete brig_blobs[i];
225 static tree
226 brig_langhook_type_for_size (unsigned int bits,
227 int unsignedp)
229 /* Copied from go-lang.c */
230 tree type;
231 if (unsignedp)
233 if (bits == INT_TYPE_SIZE)
234 type = unsigned_type_node;
235 else if (bits == CHAR_TYPE_SIZE)
236 type = unsigned_char_type_node;
237 else if (bits == SHORT_TYPE_SIZE)
238 type = short_unsigned_type_node;
239 else if (bits == LONG_TYPE_SIZE)
240 type = long_unsigned_type_node;
241 else if (bits == LONG_LONG_TYPE_SIZE)
242 type = long_long_unsigned_type_node;
243 else
244 type = make_unsigned_type(bits);
246 else
248 if (bits == INT_TYPE_SIZE)
249 type = integer_type_node;
250 else if (bits == CHAR_TYPE_SIZE)
251 type = signed_char_type_node;
252 else if (bits == SHORT_TYPE_SIZE)
253 type = short_integer_type_node;
254 else if (bits == LONG_TYPE_SIZE)
255 type = long_integer_type_node;
256 else if (bits == LONG_LONG_TYPE_SIZE)
257 type = long_long_integer_type_node;
258 else
259 type = make_signed_type(bits);
261 return type;
264 static tree
265 brig_langhook_type_for_mode (machine_mode mode, int unsignedp)
267 if (mode == TYPE_MODE (void_type_node))
268 return void_type_node;
270 if (VECTOR_MODE_P (mode))
272 tree inner;
274 inner = brig_langhook_type_for_mode (GET_MODE_INNER (mode), unsignedp);
275 if (inner != NULL_TREE)
276 return build_vector_type_for_mode (inner, mode);
277 gcc_unreachable ();
278 return NULL_TREE;
281 enum mode_class mc = GET_MODE_CLASS (mode);
282 if (mc == MODE_FLOAT)
284 switch (GET_MODE_BITSIZE (mode))
286 case 32:
287 return float_type_node;
288 case 64:
289 return double_type_node;
290 default:
291 /* We have to check for long double in order to support
292 i386 excess precision. */
293 if (mode == TYPE_MODE (long_double_type_node))
294 return long_double_type_node;
296 gcc_unreachable ();
297 return NULL_TREE;
300 else if (mc == MODE_INT)
301 return brig_langhook_type_for_size(GET_MODE_BITSIZE(mode), unsignedp);
302 else
304 /* E.g., build_common_builtin_nodes () asks for modes/builtins
305 we do not generate or need. Just ignore them silently for now.
307 return NULL_TREE;
309 return NULL_TREE;
312 static tree
313 brig_langhook_builtin_function (tree decl)
315 return decl;
318 static GTY(()) tree registered_builtin_types;
320 static void
321 brig_langhook_register_builtin_type (tree type, const char *name)
323 tree decl;
325 if (!TYPE_NAME (type))
327 decl = build_decl (UNKNOWN_LOCATION, TYPE_DECL,
328 get_identifier (name), type);
329 DECL_ARTIFICIAL (decl) = 1;
330 TYPE_NAME (type) = decl;
333 registered_builtin_types = tree_cons (0, type, registered_builtin_types);
337 /* Return true if we are in the global binding level. */
339 static bool
340 brig_langhook_global_bindings_p (void)
342 return current_function_decl == NULL_TREE;
345 /* Push a declaration into the current binding level. From Go: We can't
346 usefully implement this since we don't want to convert from tree
347 back to one of our internal data structures. I think the only way
348 this is used is to record a decl which is to be returned by
349 getdecls, and we could implement it for that purpose if
350 necessary. */
352 static tree
353 brig_langhook_pushdecl (tree decl ATTRIBUTE_UNUSED)
355 gcc_unreachable ();
358 /* This hook is used to get the current list of declarations as trees.
359 From Go: We don't support that; instead we use the write_globals hook.
360 This can't simply crash because it is called by -gstabs. */
362 static tree
363 brig_langhook_getdecls (void)
365 return NULL;
368 static int
369 brig_langhook_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
370 gimple_seq *post_p ATTRIBUTE_UNUSED)
373 /* Strip off the static chain info that appears to function
374 calls for some strange reason even though we don't add
375 nested functions. Maybe something wrong with the function
376 declaration contexts? */
377 if (TREE_CODE (*expr_p) == CALL_EXPR
378 && CALL_EXPR_STATIC_CHAIN (*expr_p) != NULL_TREE)
379 CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL_TREE;
380 return GS_UNHANDLED;
383 static tree
384 brig_langhook_eh_personality (void)
386 gcc_unreachable ();
389 /* Functions called directly by the generic backend.
390 Adapted from go-lang.c. */
392 tree
393 convert (tree type, tree expr)
395 if (type == error_mark_node || expr == error_mark_node
396 || TREE_TYPE (expr) == error_mark_node)
397 return error_mark_node;
399 if (type == TREE_TYPE (expr))
400 return expr;
402 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
403 return fold_convert (type, expr);
405 switch (TREE_CODE (type))
407 case VOID_TYPE:
408 case BOOLEAN_TYPE:
409 return fold_convert (type, expr);
410 case INTEGER_TYPE:
411 return fold (convert_to_integer (type, expr));
412 case REAL_TYPE:
413 return fold (convert_to_real (type, expr));
414 case VECTOR_TYPE:
415 return fold (convert_to_vector (type, expr));
416 case POINTER_TYPE:
417 return build1 (VIEW_CONVERT_EXPR, type, convert (size_type_node, expr));
418 default:
419 break;
422 gcc_unreachable ();
425 static GTY (()) tree brig_gc_root;
427 /* Preserve trees that we create from the garbage collector. */
429 void
430 brig_preserve_from_gc (tree t)
432 brig_gc_root = tree_cons (NULL_TREE, t, brig_gc_root);
435 /* Convert an identifier for use in an error message. */
437 const char *
438 brig_localize_identifier (const char *ident)
440 return identifier_to_locale (ident);
443 /* Define supported attributes and their handlers. Code copied from
444 lto-lang.c */
446 /* Table of machine-independent attributes supported in GIMPLE. */
447 const struct attribute_spec brig_attribute_table[] =
449 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
450 do_diagnostic } */
451 { "leaf", 0, 0, true, false, false,
452 handle_leaf_attribute, false },
453 { "const", 0, 0, true, false, false,
454 handle_const_attribute, false },
455 { "pure", 0, 0, true, false, false,
456 handle_pure_attribute, false },
457 { "nothrow", 0, 0, true, false, false,
458 handle_nothrow_attribute, false },
459 { "returns_twice", 0, 0, true, false, false,
460 handle_returns_twice_attribute, false },
461 { NULL, 0, 0, false, false, false, NULL, false }
464 /* Attribute handlers. */
465 /* Handle a "leaf" attribute; arguments as in
466 struct attribute_spec.handler. */
468 static tree
469 handle_leaf_attribute (tree *node, tree name,
470 tree ARG_UNUSED (args),
471 int ARG_UNUSED (flags), bool *no_add_attrs)
473 if (TREE_CODE (*node) != FUNCTION_DECL)
475 warning (OPT_Wattributes, "%qE attribute ignored", name);
476 *no_add_attrs = true;
478 if (!TREE_PUBLIC (*node))
480 warning (OPT_Wattributes,
481 "%qE attribute has no effect on unit local functions", name);
482 *no_add_attrs = true;
485 return NULL_TREE;
488 /* Handle a "const" attribute; arguments as in
489 struct attribute_spec.handler. */
491 static tree
492 handle_const_attribute (tree *node, tree ARG_UNUSED (name),
493 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
494 bool * ARG_UNUSED (no_add_attrs))
496 tree type = TREE_TYPE (*node);
498 /* See FIXME comment on noreturn in c_common_attribute_table. */
499 if (TREE_CODE (*node) == FUNCTION_DECL)
500 TREE_READONLY (*node) = 1;
501 else if (TREE_CODE (type) == POINTER_TYPE
502 && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
503 TREE_TYPE (*node)
504 = build_pointer_type
505 (build_type_variant (TREE_TYPE (type), 1,
506 TREE_THIS_VOLATILE (TREE_TYPE (type))));
507 else
508 gcc_unreachable ();
510 return NULL_TREE;
513 /* Handle a "pure" attribute; arguments as in
514 struct attribute_spec.handler. */
516 static tree
517 handle_pure_attribute (tree *node, tree ARG_UNUSED (name),
518 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
519 bool * ARG_UNUSED (no_add_attrs))
521 if (TREE_CODE (*node) == FUNCTION_DECL)
522 DECL_PURE_P (*node) = 1;
523 else
524 gcc_unreachable ();
526 return NULL_TREE;
529 /* Handle a "nothrow" attribute; arguments as in
530 struct attribute_spec.handler. */
532 static tree
533 handle_nothrow_attribute (tree *node, tree ARG_UNUSED (name),
534 tree ARG_UNUSED (args), int ARG_UNUSED (flags),
535 bool * ARG_UNUSED (no_add_attrs))
537 if (TREE_CODE (*node) == FUNCTION_DECL)
538 TREE_NOTHROW (*node) = 1;
539 else
540 gcc_unreachable ();
542 return NULL_TREE;
545 /* Handle a "returns_twice" attribute. */
547 static tree
548 handle_returns_twice_attribute (tree *node, tree ARG_UNUSED (name),
549 tree ARG_UNUSED (args),
550 int ARG_UNUSED (flags),
551 bool * ARG_UNUSED (no_add_attrs))
553 gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
555 DECL_IS_RETURNS_TWICE (*node) = 1;
557 return NULL_TREE;
561 /* Built-in initialization code cribbed from lto-lang.c which cribbed it
562 from c-common.c. */
565 static GTY(()) tree built_in_attributes[(int) ATTR_LAST];
568 static GTY(()) tree builtin_types[(int) BT_LAST + 1];
570 static GTY(()) tree string_type_node;
571 static GTY(()) tree const_string_type_node;
572 static GTY(()) tree wint_type_node;
573 static GTY(()) tree intmax_type_node;
574 static GTY(()) tree uintmax_type_node;
575 static GTY(()) tree signed_size_type_node;
577 /* Flags needed to process builtins.def. */
578 int flag_isoc94;
579 int flag_isoc99;
580 int flag_isoc11;
582 static void
583 def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
585 tree t;
586 tree *args = XALLOCAVEC (tree, n);
587 va_list list;
588 int i;
589 bool err = false;
591 va_start (list, n);
592 for (i = 0; i < n; ++i)
594 builtin_type a = (builtin_type) va_arg (list, int);
595 t = builtin_types[a];
596 if (t == error_mark_node)
597 err = true;
598 args[i] = t;
600 va_end (list);
602 t = builtin_types[ret];
603 if (err)
604 t = error_mark_node;
605 if (t == error_mark_node)
607 else if (var)
608 t = build_varargs_function_type_array (t, n, args);
609 else
610 t = build_function_type_array (t, n, args);
612 builtin_types[def] = t;
615 /* Used to help initialize the builtin-types.def table. When a type of
616 the correct size doesn't exist, use error_mark_node instead of NULL.
617 The later results in segfaults even when a decl using the type doesn't
618 get invoked. */
620 static tree
621 builtin_type_for_size (int size, bool unsignedp)
623 tree type = brig_langhook_type_for_size (size, unsignedp);
624 return type ? type : error_mark_node;
627 /* Support for DEF_BUILTIN. */
629 static void
630 def_builtin_1 (enum built_in_function fncode, const char *name,
631 enum built_in_class fnclass, tree fntype, tree libtype,
632 bool both_p, bool fallback_p, bool nonansi_p,
633 tree fnattrs, bool implicit_p)
635 tree decl;
636 const char *libname;
638 if (fntype == error_mark_node)
639 return;
641 libname = name + strlen ("__builtin_");
642 decl = add_builtin_function (name, fntype, fncode, fnclass,
643 (fallback_p ? libname : NULL),
644 fnattrs);
646 if (both_p
647 && !flag_no_builtin
648 && !(nonansi_p && flag_no_nonansi_builtin))
649 add_builtin_function (libname, libtype, fncode, fnclass,
650 NULL, fnattrs);
652 set_builtin_decl (fncode, decl, implicit_p);
656 /* Initialize the attribute table for all the supported builtins. */
658 static void
659 brig_init_attributes (void)
661 /* Fill in the built_in_attributes array. */
662 #define DEF_ATTR_NULL_TREE(ENUM) \
663 built_in_attributes[(int) ENUM] = NULL_TREE;
664 #define DEF_ATTR_INT(ENUM, VALUE) \
665 built_in_attributes[(int) ENUM] = build_int_cst (NULL_TREE, VALUE);
666 #define DEF_ATTR_STRING(ENUM, VALUE) \
667 built_in_attributes[(int) ENUM] = build_string (strlen (VALUE), VALUE);
668 #define DEF_ATTR_IDENT(ENUM, STRING) \
669 built_in_attributes[(int) ENUM] = get_identifier (STRING);
670 #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) \
671 built_in_attributes[(int) ENUM] \
672 = tree_cons (built_in_attributes[(int) PURPOSE], \
673 built_in_attributes[(int) VALUE], \
674 built_in_attributes[(int) CHAIN]);
675 #include "builtin-attrs.def"
676 #undef DEF_ATTR_NULL_TREE
677 #undef DEF_ATTR_INT
678 #undef DEF_ATTR_STRING
679 #undef DEF_ATTR_IDENT
680 #undef DEF_ATTR_TREE_LIST
683 /* Create builtin types and functions. VA_LIST_REF_TYPE_NODE and
684 VA_LIST_ARG_TYPE_NODE are used in builtin-types.def. */
686 static void
687 brig_define_builtins (tree va_list_ref_type_node ATTRIBUTE_UNUSED,
688 tree va_list_arg_type_node ATTRIBUTE_UNUSED)
690 #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
691 builtin_types[ENUM] = VALUE;
692 #define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
693 def_fn_type (ENUM, RETURN, 0, 0);
694 #define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
695 def_fn_type (ENUM, RETURN, 0, 1, ARG1);
696 #define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
697 def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2);
698 #define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
699 def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3);
700 #define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
701 def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4);
702 #define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
703 def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
704 #define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
705 ARG6) \
706 def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
707 #define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
708 ARG6, ARG7) \
709 def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
710 #define DEF_FUNCTION_TYPE_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
711 ARG6, ARG7, ARG8) \
712 def_fn_type (ENUM, RETURN, 0, 8, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
713 ARG7, ARG8);
714 #define DEF_FUNCTION_TYPE_9(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
715 ARG6, ARG7, ARG8, ARG9) \
716 def_fn_type (ENUM, RETURN, 0, 9, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
717 ARG7, ARG8, ARG9);
718 #define DEF_FUNCTION_TYPE_10(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
719 ARG6, ARG7, ARG8, ARG9, ARG10) \
720 def_fn_type (ENUM, RETURN, 0, 10, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
721 ARG7, ARG8, ARG9, ARG10);
722 #define DEF_FUNCTION_TYPE_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
723 ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) \
724 def_fn_type (ENUM, RETURN, 0, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
725 ARG7, ARG8, ARG9, ARG10, ARG11);
726 #define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
727 def_fn_type (ENUM, RETURN, 1, 0);
728 #define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
729 def_fn_type (ENUM, RETURN, 1, 1, ARG1);
730 #define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
731 def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2);
732 #define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
733 def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3);
734 #define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
735 def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
736 #define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
737 def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
738 #define DEF_FUNCTION_TYPE_VAR_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
739 ARG6) \
740 def_fn_type (ENUM, RETURN, 1, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
741 #define DEF_FUNCTION_TYPE_VAR_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
742 ARG6, ARG7) \
743 def_fn_type (ENUM, RETURN, 1, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
744 #define DEF_POINTER_TYPE(ENUM, TYPE) \
745 builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
747 #include "builtin-types.def"
749 #undef DEF_PRIMITIVE_TYPE
750 #undef DEF_FUNCTION_TYPE_0
751 #undef DEF_FUNCTION_TYPE_1
752 #undef DEF_FUNCTION_TYPE_2
753 #undef DEF_FUNCTION_TYPE_3
754 #undef DEF_FUNCTION_TYPE_4
755 #undef DEF_FUNCTION_TYPE_5
756 #undef DEF_FUNCTION_TYPE_6
757 #undef DEF_FUNCTION_TYPE_7
758 #undef DEF_FUNCTION_TYPE_8
759 #undef DEF_FUNCTION_TYPE_9
760 #undef DEF_FUNCTION_TYPE_10
761 #undef DEF_FUNCTION_TYPE_11
762 #undef DEF_FUNCTION_TYPE_VAR_0
763 #undef DEF_FUNCTION_TYPE_VAR_1
764 #undef DEF_FUNCTION_TYPE_VAR_2
765 #undef DEF_FUNCTION_TYPE_VAR_3
766 #undef DEF_FUNCTION_TYPE_VAR_4
767 #undef DEF_FUNCTION_TYPE_VAR_5
768 #undef DEF_FUNCTION_TYPE_VAR_6
769 #undef DEF_FUNCTION_TYPE_VAR_7
770 #undef DEF_POINTER_TYPE
771 builtin_types[(int) BT_LAST] = NULL_TREE;
773 brig_init_attributes ();
775 #define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P,\
776 NONANSI_P, ATTRS, IMPLICIT, COND) \
777 if (NAME && COND) \
778 def_builtin_1 (ENUM, NAME, CLASS, builtin_types[(int) TYPE], \
779 builtin_types[(int) LIBTYPE], BOTH_P, FALLBACK_P, \
780 NONANSI_P, built_in_attributes[(int) ATTRS], IMPLICIT);
782 #undef DEF_HSAIL_BUILTIN
783 #define DEF_HSAIL_BUILTIN(ENUM, HSAIL_OPCODE, HSAIL_TYPE, NAME, TYPE, ATTRS) \
784 DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
785 false, true, true, ATTRS, false, true)
787 /* HSAIL atomic builtins do not have separate identifying opcodes. */
789 #undef DEF_HSAIL_ATOMIC_BUILTIN
790 #define DEF_HSAIL_ATOMIC_BUILTIN(ENUM, ATOMIC_OPCODE, HSAIL_TYPE, NAME, \
791 TYPE, ATTRS) \
792 DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
793 false, true, true, ATTRS, false, true)
795 /* HSAIL saturating arithmetics builtins. */
797 #undef DEF_HSAIL_SAT_BUILTIN
798 #define DEF_HSAIL_SAT_BUILTIN(ENUM, BRIG_OPCODE, HSAIL_TYPE, NAME, \
799 TYPE, ATTRS) \
800 DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
801 false, true, true, ATTRS, false, true)
803 /* HSAIL builtins used internally by the frontend. */
805 #undef DEF_HSAIL_INTR_BUILTIN
806 #define DEF_HSAIL_INTR_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
807 DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
808 false, true, true, ATTRS, false, true)
810 /* HSAIL saturated conversions. */
812 #undef DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN
813 #define DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN(ENUM, HSAIL_DEST_TYPE, HSAIL_SRC_TYPE, \
814 NAME, TYPE, ATTRS) \
815 DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
816 false, true, true, ATTRS, false, true)
818 #include "builtins.def"
821 /* Build nodes that would have be created by the C front-end; necessary
822 for including builtin-types.def and ultimately builtins.def. Borrowed
823 from lto-lang.c. */
825 static void
826 brig_build_c_type_nodes (void)
828 gcc_assert (void_type_node);
830 void_list_node = build_tree_list (NULL_TREE, void_type_node);
831 string_type_node = build_pointer_type (char_type_node);
832 const_string_type_node
833 = build_pointer_type (build_qualified_type (char_type_node,
834 TYPE_QUAL_CONST));
836 if (strcmp (SIZE_TYPE, "unsigned int") == 0)
838 intmax_type_node = integer_type_node;
839 uintmax_type_node = unsigned_type_node;
840 signed_size_type_node = integer_type_node;
842 else if (strcmp (SIZE_TYPE, "long unsigned int") == 0)
844 intmax_type_node = long_integer_type_node;
845 uintmax_type_node = long_unsigned_type_node;
846 signed_size_type_node = long_integer_type_node;
848 else if (strcmp (SIZE_TYPE, "long long unsigned int") == 0)
850 intmax_type_node = long_long_integer_type_node;
851 uintmax_type_node = long_long_unsigned_type_node;
852 signed_size_type_node = long_long_integer_type_node;
854 else
856 int i;
858 signed_size_type_node = NULL_TREE;
859 for (i = 0; i < NUM_INT_N_ENTS; i++)
860 if (int_n_enabled_p[i])
862 char name[50];
863 sprintf (name, "__int%d unsigned", int_n_data[i].bitsize);
865 if (strcmp (name, SIZE_TYPE) == 0)
867 intmax_type_node = int_n_trees[i].signed_type;
868 uintmax_type_node = int_n_trees[i].unsigned_type;
869 signed_size_type_node = int_n_trees[i].signed_type;
872 if (signed_size_type_node == NULL_TREE)
873 gcc_unreachable ();
876 wint_type_node = unsigned_type_node;
877 pid_type_node = integer_type_node;
881 static bool
882 brig_langhook_init (void)
884 build_common_tree_nodes (false);
886 /* Builtin initialization related code borrowed from lto-lang.c. */
887 void_list_node = build_tree_list (NULL_TREE, void_type_node);
889 brig_build_c_type_nodes ();
891 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
893 tree x = build_pointer_type (TREE_TYPE (va_list_type_node));
894 brig_define_builtins (x, x);
896 else
898 brig_define_builtins (build_reference_type (va_list_type_node),
899 va_list_type_node);
902 targetm.init_builtins ();
903 build_common_builtin_nodes ();
905 return true;
908 #undef LANG_HOOKS_NAME
909 #undef LANG_HOOKS_INIT
910 #undef LANG_HOOKS_OPTION_LANG_MASK
911 #undef LANG_HOOKS_INIT_OPTIONS_STRUCT
912 #undef LANG_HOOKS_HANDLE_OPTION
913 #undef LANG_HOOKS_POST_OPTIONS
914 #undef LANG_HOOKS_PARSE_FILE
915 #undef LANG_HOOKS_TYPE_FOR_MODE
916 #undef LANG_HOOKS_TYPE_FOR_SIZE
917 #undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
918 #undef LANG_HOOKS_BUILTIN_FUNCTION
919 #undef LANG_HOOKS_GLOBAL_BINDINGS_P
920 #undef LANG_HOOKS_PUSHDECL
921 #undef LANG_HOOKS_GETDECLS
922 #undef LANG_HOOKS_WRITE_GLOBALS
923 #undef LANG_HOOKS_GIMPLIFY_EXPR
924 #undef LANG_HOOKS_EH_PERSONALITY
926 #define LANG_HOOKS_NAME "GNU Brig"
927 #define LANG_HOOKS_INIT brig_langhook_init
928 #define LANG_HOOKS_OPTION_LANG_MASK brig_langhook_option_lang_mask
929 #define LANG_HOOKS_INIT_OPTIONS_STRUCT brig_langhook_init_options_struct
930 #define LANG_HOOKS_HANDLE_OPTION brig_langhook_handle_option
931 #define LANG_HOOKS_POST_OPTIONS brig_langhook_post_options
932 #define LANG_HOOKS_PARSE_FILE brig_langhook_parse_file
933 #define LANG_HOOKS_TYPE_FOR_MODE brig_langhook_type_for_mode
934 #define LANG_HOOKS_TYPE_FOR_SIZE brig_langhook_type_for_size
935 #define LANG_HOOKS_REGISTER_BUILTIN_TYPE brig_langhook_register_builtin_type
936 #define LANG_HOOKS_BUILTIN_FUNCTION brig_langhook_builtin_function
937 #define LANG_HOOKS_GLOBAL_BINDINGS_P brig_langhook_global_bindings_p
938 #define LANG_HOOKS_PUSHDECL brig_langhook_pushdecl
939 #define LANG_HOOKS_GETDECLS brig_langhook_getdecls
940 #define LANG_HOOKS_GIMPLIFY_EXPR brig_langhook_gimplify_expr
941 #define LANG_HOOKS_EH_PERSONALITY brig_langhook_eh_personality
943 /* Attribute hooks. */
944 #undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
945 #define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE brig_attribute_table
947 struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
949 #include "gt-brig-brig-lang.h"
950 #include "gtype-brig.h"