1 /* A C++ API for libgccjit, purely as inline wrapper functions.
2 Copyright (C) 2014-2021 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 GCC is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #ifndef LIBGCCJIT_PLUS_PLUS_H
21 #define LIBGCCJIT_PLUS_PLUS_H
23 #include "libgccjit.h"
29 /****************************************************************************
31 ****************************************************************************/
35 /* Indentation indicates inheritance. */
55 /* Errors within the API become C++ exceptions of this class. */
63 context
get_context () const;
65 std::string
get_debug_string () const;
69 object (gcc_jit_object
*obj
);
71 gcc_jit_object
*get_inner_object () const;
74 gcc_jit_object
*m_inner_obj
;
77 inline std::ostream
& operator << (std::ostream
& stream
, const object
&obj
);
79 /* Some client code will want to supply source code locations, others
80 won't. To avoid doubling the number of entrypoints, everything
81 accepting a location also has a default argument. To do this, the
82 other classes need to see that "location" has a default constructor,
83 hence we need to declare it first. */
84 class location
: public object
88 location (gcc_jit_location
*loc
);
90 gcc_jit_location
*get_inner_location () const;
96 static context
acquire ();
98 context (gcc_jit_context
*ctxt
);
100 gccjit::context
new_child_context ();
102 gcc_jit_context
*get_inner_context () { return m_inner_ctxt
; }
106 gcc_jit_result
*compile ();
108 void compile_to_file (enum gcc_jit_output_kind output_kind
,
109 const char *output_path
);
111 void dump_to_file (const std::string
&path
,
112 bool update_locations
);
114 void set_logfile (FILE *logfile
,
118 void dump_reproducer_to_file (const char *path
);
120 void set_str_option (enum gcc_jit_str_option opt
,
123 void set_int_option (enum gcc_jit_int_option opt
,
126 void set_bool_option (enum gcc_jit_bool_option opt
,
129 void set_bool_allow_unreachable_blocks (int bool_value
);
130 void set_bool_use_external_driver (int bool_value
);
132 void add_command_line_option (const char *optname
);
133 void add_driver_option (const char *optname
);
135 void set_timer (gccjit::timer t
);
136 gccjit::timer
get_timer () const;
139 new_location (const std::string
&filename
,
143 type
get_type (enum gcc_jit_types kind
);
144 type
get_int_type (size_t num_bytes
, int is_signed
);
146 /* A way to map a specific int type, using the compiler to
147 get the details automatically e.g.:
148 gccjit::type type = get_int_type <my_int_type_t> (); */
149 template <typename T
>
150 type
get_int_type ();
152 type
new_array_type (type element_type
, int num_elements
,
153 location loc
= location ());
155 field
new_field (type type_
, const std::string
&name
,
156 location loc
= location ());
158 field
new_bitfield (type type_
, int width
, const std::string
&name
,
159 location loc
= location ());
161 struct_
new_struct_type (const std::string
&name
,
162 std::vector
<field
> &fields
,
163 location loc
= location ());
165 struct_
new_opaque_struct_type (const std::string
&name
,
166 location loc
= location ());
168 param
new_param (type type_
,
169 const std::string
&name
,
170 location loc
= location ());
172 function
new_function (enum gcc_jit_function_kind kind
,
174 const std::string
&name
,
175 std::vector
<param
> ¶ms
,
177 location loc
= location ());
179 function
get_builtin_function (const std::string
&name
);
181 lvalue
new_global (enum gcc_jit_global_kind kind
,
183 const std::string
&name
,
184 location loc
= location ());
186 rvalue
new_rvalue (type numeric_type
,
188 rvalue
new_rvalue (type numeric_type
,
190 rvalue
zero (type numeric_type
) const;
191 rvalue
one (type numeric_type
) const;
192 rvalue
new_rvalue (type numeric_type
,
194 rvalue
new_rvalue (type pointer_type
,
196 rvalue
new_rvalue (const std::string
&value
) const;
197 rvalue
new_rvalue (type vector_type
,
198 std::vector
<rvalue
> elements
) const;
200 /* Generic unary operations... */
201 rvalue
new_unary_op (enum gcc_jit_unary_op op
,
204 location loc
= location ());
206 /* ...and shorter ways to spell the various specific kinds of
208 rvalue
new_minus (type result_type
,
210 location loc
= location ());
211 rvalue
new_bitwise_negate (type result_type
,
213 location loc
= location ());
214 rvalue
new_logical_negate (type result_type
,
216 location loc
= location ());
218 /* Generic binary operations... */
219 rvalue
new_binary_op (enum gcc_jit_binary_op op
,
222 location loc
= location ());
224 /* ...and shorter ways to spell the various specific kinds of
226 rvalue
new_plus (type result_type
,
228 location loc
= location ());
229 rvalue
new_minus (type result_type
,
231 location loc
= location ());
232 rvalue
new_mult (type result_type
,
234 location loc
= location ());
235 rvalue
new_divide (type result_type
,
237 location loc
= location ());
238 rvalue
new_modulo (type result_type
,
240 location loc
= location ());
241 rvalue
new_bitwise_and (type result_type
,
243 location loc
= location ());
244 rvalue
new_bitwise_xor (type result_type
,
246 location loc
= location ());
247 rvalue
new_bitwise_or (type result_type
,
249 location loc
= location ());
250 rvalue
new_logical_and (type result_type
,
252 location loc
= location ());
253 rvalue
new_logical_or (type result_type
,
255 location loc
= location ());
257 /* Generic comparisons... */
258 rvalue
new_comparison (enum gcc_jit_comparison op
,
260 location loc
= location ());
261 /* ...and shorter ways to spell the various specific kinds of
263 rvalue
new_eq (rvalue a
, rvalue b
,
264 location loc
= location ());
265 rvalue
new_ne (rvalue a
, rvalue b
,
266 location loc
= location ());
267 rvalue
new_lt (rvalue a
, rvalue b
,
268 location loc
= location ());
269 rvalue
new_le (rvalue a
, rvalue b
,
270 location loc
= location ());
271 rvalue
new_gt (rvalue a
, rvalue b
,
272 location loc
= location ());
273 rvalue
new_ge (rvalue a
, rvalue b
,
274 location loc
= location ());
276 /* The most general way of creating a function call. */
277 rvalue
new_call (function func
,
278 std::vector
<rvalue
> &args
,
279 location loc
= location ());
281 /* In addition, we provide a series of overloaded "new_call" methods
282 for specific numbers of args (from 0 - 6), to avoid the need for
283 client code to manually build a vector. */
284 rvalue
new_call (function func
,
285 location loc
= location ());
286 rvalue
new_call (function func
,
288 location loc
= location ());
289 rvalue
new_call (function func
,
290 rvalue arg0
, rvalue arg1
,
291 location loc
= location ());
292 rvalue
new_call (function func
,
293 rvalue arg0
, rvalue arg1
, rvalue arg2
,
294 location loc
= location ());
295 rvalue
new_call (function func
,
296 rvalue arg0
, rvalue arg1
, rvalue arg2
,
298 location loc
= location ());
299 rvalue
new_call (function func
,
300 rvalue arg0
, rvalue arg1
, rvalue arg2
,
301 rvalue arg3
, rvalue arg4
,
302 location loc
= location ());
303 rvalue
new_call (function func
,
304 rvalue arg0
, rvalue arg1
, rvalue arg2
,
305 rvalue arg3
, rvalue arg4
, rvalue arg5
,
306 location loc
= location ());
308 rvalue
new_cast (rvalue expr
,
310 location loc
= location ());
312 lvalue
new_array_access (rvalue ptr
,
314 location loc
= location ());
316 case_
new_case (rvalue min_value
,
320 void add_top_level_asm (const char *asm_stmts
,
321 location loc
= location ());
324 gcc_jit_context
*m_inner_ctxt
;
327 class field
: public object
331 field (gcc_jit_field
*inner
);
333 gcc_jit_field
*get_inner_field () const;
336 class type
: public object
340 type (gcc_jit_type
*inner
);
342 gcc_jit_type
*get_inner_type () const;
346 type
get_volatile ();
347 type
get_aligned (size_t alignment_in_bytes
);
348 type
get_vector (size_t num_units
);
350 // Shortcuts for getting values of numeric types:
355 class struct_
: public type
359 struct_ (gcc_jit_struct
*inner
);
361 gcc_jit_struct
*get_inner_struct () const;
364 class function
: public object
368 function (gcc_jit_function
*func
);
370 gcc_jit_function
*get_inner_function () const;
372 void dump_to_dot (const std::string
&path
);
374 param
get_param (int index
) const;
377 block
new_block (const std::string
&name
);
379 lvalue
new_local (type type_
,
380 const std::string
&name
,
381 location loc
= location ());
383 rvalue
get_address (location loc
= location ());
385 /* A series of overloaded operator () with various numbers of arguments
386 for a very terse way of creating a call to this function. The call
387 is created within the same context as the function itself, which may
388 not be what you want. */
389 rvalue
operator() (location loc
= location ());
390 rvalue
operator() (rvalue arg0
,
391 location loc
= location ());
392 rvalue
operator() (rvalue arg0
, rvalue arg1
,
393 location loc
= location ());
394 rvalue
operator() (rvalue arg0
, rvalue arg1
, rvalue arg2
,
395 location loc
= location ());
398 class block
: public object
402 block (gcc_jit_block
*inner
);
404 gcc_jit_block
*get_inner_block () const;
406 function
get_function () const;
408 void add_eval (rvalue rvalue
,
409 location loc
= location ());
411 void add_assignment (lvalue lvalue
,
413 location loc
= location ());
415 void add_assignment_op (lvalue lvalue
,
416 enum gcc_jit_binary_op op
,
418 location loc
= location ());
420 /* A way to add a function call to the body of a function being
421 defined, with various numbers of args. */
422 rvalue
add_call (function other
,
423 location loc
= location ());
424 rvalue
add_call (function other
,
426 location loc
= location ());
427 rvalue
add_call (function other
,
428 rvalue arg0
, rvalue arg1
,
429 location loc
= location ());
430 rvalue
add_call (function other
,
431 rvalue arg0
, rvalue arg1
, rvalue arg2
,
432 location loc
= location ());
433 rvalue
add_call (function other
,
434 rvalue arg0
, rvalue arg1
, rvalue arg2
, rvalue arg3
,
435 location loc
= location ());
437 void add_comment (const std::string
&text
,
438 location loc
= location ());
440 void end_with_conditional (rvalue boolval
,
443 location loc
= location ());
445 void end_with_jump (block target
,
446 location loc
= location ());
448 void end_with_return (rvalue rvalue
,
449 location loc
= location ());
450 void end_with_return (location loc
= location ());
452 void end_with_switch (rvalue expr
,
454 std::vector
<case_
> cases
,
455 location loc
= location ());
457 extended_asm
add_extended_asm (const std::string
&asm_template
,
458 location loc
= location ());
459 extended_asm
end_with_extended_asm_goto (const std::string
&asm_template
,
460 std::vector
<block
> goto_blocks
,
461 block
*fallthrough_block
,
462 location loc
= location ());
465 class rvalue
: public object
469 rvalue (gcc_jit_rvalue
*inner
);
470 gcc_jit_rvalue
*get_inner_rvalue () const;
474 rvalue
access_field (field field
,
475 location loc
= location ());
477 lvalue
dereference_field (field field
,
478 location loc
= location ());
480 lvalue
dereference (location loc
= location ());
482 rvalue
cast_to (type type_
,
483 location loc
= location ());
486 lvalue
operator[] (rvalue index
);
487 lvalue
operator[] (int index
);
490 class lvalue
: public rvalue
494 lvalue (gcc_jit_lvalue
*inner
);
496 gcc_jit_lvalue
*get_inner_lvalue () const;
498 lvalue
access_field (field field
,
499 location loc
= location ());
501 rvalue
get_address (location loc
= location ());
502 lvalue
set_initializer (const void *blob
, size_t num_bytes
);
505 class param
: public lvalue
509 param (gcc_jit_param
*inner
);
511 gcc_jit_param
*get_inner_param () const;
514 class case_
: public object
518 case_ (gcc_jit_case
*inner
);
520 gcc_jit_case
*get_inner_case () const;
523 class extended_asm
: public object
527 extended_asm (gcc_jit_extended_asm
*inner
);
530 set_volatile_flag (bool flag
);
533 set_inline_flag (bool flag
);
536 add_output_operand (const std::string
&asm_symbolic_name
,
537 const std::string
&constraint
,
538 gccjit::lvalue dest
);
540 add_output_operand (const std::string
&constraint
,
541 gccjit::lvalue dest
);
544 add_input_operand (const std::string
&asm_symbolic_name
,
545 const std::string
&constraint
,
548 add_input_operand (const std::string
&constraint
,
552 add_clobber (const std::string
&victim
);
554 gcc_jit_extended_asm
*get_inner_extended_asm () const;
557 /* Overloaded operators, for those who want the most terse API
558 (at the possible risk of being a little too magical).
560 In each case, the first parameter is used to determine which context
561 owns the resulting expression, and, where appropriate, what the
564 /* Unary operators. */
565 rvalue
operator- (rvalue a
); // unary minus
566 rvalue
operator~ (rvalue a
); // unary bitwise negate
567 rvalue
operator! (rvalue a
); // unary logical negate
569 /* Binary operators. */
570 rvalue
operator+ (rvalue a
, rvalue b
);
571 rvalue
operator- (rvalue a
, rvalue b
);
572 rvalue
operator* (rvalue a
, rvalue b
);
573 rvalue
operator/ (rvalue a
, rvalue b
);
574 rvalue
operator% (rvalue a
, rvalue b
);
575 rvalue
operator& (rvalue a
, rvalue b
); // bitwise and
576 rvalue
operator^ (rvalue a
, rvalue b
); // bitwise_xor
577 rvalue
operator| (rvalue a
, rvalue b
); // bitwise_or
578 rvalue
operator&& (rvalue a
, rvalue b
); // logical_and
579 rvalue
operator|| (rvalue a
, rvalue b
); // logical_or
582 rvalue
operator== (rvalue a
, rvalue b
);
583 rvalue
operator!= (rvalue a
, rvalue b
);
584 rvalue
operator< (rvalue a
, rvalue b
);
585 rvalue
operator<= (rvalue a
, rvalue b
);
586 rvalue
operator> (rvalue a
, rvalue b
);
587 rvalue
operator>= (rvalue a
, rvalue b
);
590 lvalue
operator* (rvalue ptr
);
596 timer (gcc_jit_timer
*inner_timer
);
598 void push (const char *item_name
);
599 void pop (const char *item_name
);
600 void print (FILE *f_out
) const;
604 gcc_jit_timer
*get_inner_timer () const;
607 gcc_jit_timer
*m_inner_timer
;
613 auto_time (timer t
, const char *item_name
);
614 auto_time (context ctxt
, const char *item_name
);
619 const char *m_item_name
;
623 /****************************************************************************
624 Implementation of the API
625 ****************************************************************************/
629 inline context
context::acquire ()
631 return context (gcc_jit_context_acquire ());
633 inline context::context () : m_inner_ctxt (NULL
) {}
634 inline context::context (gcc_jit_context
*inner
) : m_inner_ctxt (inner
)
640 inline gccjit::context
641 context::new_child_context ()
643 return context (gcc_jit_context_new_child_context (m_inner_ctxt
));
649 gcc_jit_context_release (m_inner_ctxt
);
653 inline gcc_jit_result
*
656 gcc_jit_result
*result
= gcc_jit_context_compile (m_inner_ctxt
);
663 context::compile_to_file (enum gcc_jit_output_kind output_kind
,
664 const char *output_path
)
666 gcc_jit_context_compile_to_file (m_inner_ctxt
,
672 context::dump_to_file (const std::string
&path
,
673 bool update_locations
)
675 gcc_jit_context_dump_to_file (m_inner_ctxt
,
681 context::set_logfile (FILE *logfile
,
685 gcc_jit_context_set_logfile (m_inner_ctxt
,
692 context::dump_reproducer_to_file (const char *path
)
694 gcc_jit_context_dump_reproducer_to_file (m_inner_ctxt
,
699 context::set_str_option (enum gcc_jit_str_option opt
,
702 gcc_jit_context_set_str_option (m_inner_ctxt
, opt
, value
);
707 context::set_int_option (enum gcc_jit_int_option opt
,
710 gcc_jit_context_set_int_option (m_inner_ctxt
, opt
, value
);
715 context::set_bool_option (enum gcc_jit_bool_option opt
,
718 gcc_jit_context_set_bool_option (m_inner_ctxt
, opt
, value
);
722 context::set_bool_allow_unreachable_blocks (int bool_value
)
724 gcc_jit_context_set_bool_allow_unreachable_blocks (m_inner_ctxt
,
729 context::set_bool_use_external_driver (int bool_value
)
731 gcc_jit_context_set_bool_use_external_driver (m_inner_ctxt
,
736 context::add_command_line_option (const char *optname
)
738 gcc_jit_context_add_command_line_option (m_inner_ctxt
, optname
);
742 context::add_driver_option (const char *optname
)
744 gcc_jit_context_add_driver_option (m_inner_ctxt
, optname
);
748 context::set_timer (gccjit::timer t
)
750 gcc_jit_context_set_timer (m_inner_ctxt
, t
.get_inner_timer ());
754 context::get_timer () const
756 return gccjit::timer (gcc_jit_context_get_timer (m_inner_ctxt
));
761 context::new_location (const std::string
&filename
,
765 return location (gcc_jit_context_new_location (m_inner_ctxt
,
772 context::get_type (enum gcc_jit_types kind
)
774 return type (gcc_jit_context_get_type (m_inner_ctxt
, kind
));
778 context::get_int_type (size_t num_bytes
, int is_signed
)
780 return type (gcc_jit_context_get_int_type (m_inner_ctxt
,
785 template <typename T
>
787 context::get_int_type ()
789 return get_int_type (sizeof (T
), std::numeric_limits
<T
>::is_signed
);
793 context::new_array_type (type element_type
, int num_elements
, location loc
)
795 return type (gcc_jit_context_new_array_type (
797 loc
.get_inner_location (),
798 element_type
.get_inner_type (),
803 context::new_field (type type_
, const std::string
&name
, location loc
)
805 return field (gcc_jit_context_new_field (m_inner_ctxt
,
806 loc
.get_inner_location (),
807 type_
.get_inner_type (),
812 context::new_bitfield (type type_
, int width
, const std::string
&name
,
815 return field (gcc_jit_context_new_bitfield (m_inner_ctxt
,
816 loc
.get_inner_location (),
817 type_
.get_inner_type (),
823 context::new_struct_type (const std::string
&name
,
824 std::vector
<field
> &fields
,
827 /* Treat std::vector as an array, relying on it not being resized: */
828 field
*as_array_of_wrappers
= &fields
[0];
830 /* Treat the array as being of the underlying pointers, relying on
831 the wrapper type being such a pointer internally. */
832 gcc_jit_field
**as_array_of_ptrs
=
833 reinterpret_cast<gcc_jit_field
**> (as_array_of_wrappers
);
835 return struct_ (gcc_jit_context_new_struct_type (m_inner_ctxt
,
836 loc
.get_inner_location (),
843 context::new_opaque_struct_type (const std::string
&name
,
846 return struct_ (gcc_jit_context_new_opaque_struct (
848 loc
.get_inner_location (),
853 context::new_param (type type_
,
854 const std::string
&name
,
857 return param (gcc_jit_context_new_param (m_inner_ctxt
,
858 loc
.get_inner_location (),
859 type_
.get_inner_type (),
864 context::new_function (enum gcc_jit_function_kind kind
,
866 const std::string
&name
,
867 std::vector
<param
> ¶ms
,
871 /* Treat std::vector as an array, relying on it not being resized: */
872 param
*as_array_of_wrappers
= ¶ms
[0];
874 /* Treat the array as being of the underlying pointers, relying on
875 the wrapper type being such a pointer internally. */
876 gcc_jit_param
**as_array_of_ptrs
=
877 reinterpret_cast<gcc_jit_param
**> (as_array_of_wrappers
);
879 return function (gcc_jit_context_new_function (m_inner_ctxt
,
880 loc
.get_inner_location (),
882 return_type
.get_inner_type (),
890 context::get_builtin_function (const std::string
&name
)
892 return function (gcc_jit_context_get_builtin_function (m_inner_ctxt
,
897 context::new_global (enum gcc_jit_global_kind kind
,
899 const std::string
&name
,
902 return lvalue (gcc_jit_context_new_global (m_inner_ctxt
,
903 loc
.get_inner_location (),
905 type_
.get_inner_type (),
910 context::new_rvalue (type numeric_type
,
914 gcc_jit_context_new_rvalue_from_int (m_inner_ctxt
,
915 numeric_type
.get_inner_type (),
920 context::new_rvalue (type numeric_type
,
924 gcc_jit_context_new_rvalue_from_long (m_inner_ctxt
,
925 numeric_type
.get_inner_type (),
930 context::zero (type numeric_type
) const
932 return rvalue (gcc_jit_context_zero (m_inner_ctxt
,
933 numeric_type
.get_inner_type ()));
937 context::one (type numeric_type
) const
939 return rvalue (gcc_jit_context_one (m_inner_ctxt
,
940 numeric_type
.get_inner_type ()));
944 context::new_rvalue (type numeric_type
,
948 gcc_jit_context_new_rvalue_from_double (m_inner_ctxt
,
949 numeric_type
.get_inner_type (),
954 context::new_rvalue (type pointer_type
,
958 gcc_jit_context_new_rvalue_from_ptr (m_inner_ctxt
,
959 pointer_type
.get_inner_type (),
964 context::new_rvalue (const std::string
&value
) const
967 gcc_jit_context_new_string_literal (m_inner_ctxt
, value
.c_str ()));
971 context::new_rvalue (type vector_type
,
972 std::vector
<rvalue
> elements
) const
974 /* Treat std::vector as an array, relying on it not being resized: */
975 rvalue
*as_array_of_wrappers
= &elements
[0];
977 /* Treat the array as being of the underlying pointers, relying on
978 the wrapper type being such a pointer internally. */
979 gcc_jit_rvalue
**as_array_of_ptrs
=
980 reinterpret_cast<gcc_jit_rvalue
**> (as_array_of_wrappers
);
983 gcc_jit_context_new_rvalue_from_vector (m_inner_ctxt
,
985 vector_type
.get_inner_type (),
991 context::new_unary_op (enum gcc_jit_unary_op op
,
996 return rvalue (gcc_jit_context_new_unary_op (m_inner_ctxt
,
997 loc
.get_inner_location (),
999 result_type
.get_inner_type (),
1000 a
.get_inner_rvalue ()));
1003 context::new_minus (type result_type
,
1007 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_MINUS
,
1008 result_type
, a
, loc
));
1011 context::new_bitwise_negate (type result_type
,
1015 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_BITWISE_NEGATE
,
1016 result_type
, a
, loc
));
1019 context::new_logical_negate (type result_type
,
1023 return rvalue (new_unary_op (GCC_JIT_UNARY_OP_LOGICAL_NEGATE
,
1024 result_type
, a
, loc
));
1028 context::new_binary_op (enum gcc_jit_binary_op op
,
1033 return rvalue (gcc_jit_context_new_binary_op (m_inner_ctxt
,
1034 loc
.get_inner_location (),
1036 result_type
.get_inner_type (),
1037 a
.get_inner_rvalue (),
1038 b
.get_inner_rvalue ()));
1041 context::new_plus (type result_type
,
1045 return new_binary_op (GCC_JIT_BINARY_OP_PLUS
,
1046 result_type
, a
, b
, loc
);
1049 context::new_minus (type result_type
,
1053 return new_binary_op (GCC_JIT_BINARY_OP_MINUS
,
1054 result_type
, a
, b
, loc
);
1057 context::new_mult (type result_type
,
1061 return new_binary_op (GCC_JIT_BINARY_OP_MULT
,
1062 result_type
, a
, b
, loc
);
1065 context::new_divide (type result_type
,
1069 return new_binary_op (GCC_JIT_BINARY_OP_DIVIDE
,
1070 result_type
, a
, b
, loc
);
1073 context::new_modulo (type result_type
,
1077 return new_binary_op (GCC_JIT_BINARY_OP_MODULO
,
1078 result_type
, a
, b
, loc
);
1081 context::new_bitwise_and (type result_type
,
1085 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_AND
,
1086 result_type
, a
, b
, loc
);
1089 context::new_bitwise_xor (type result_type
,
1093 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_XOR
,
1094 result_type
, a
, b
, loc
);
1097 context::new_bitwise_or (type result_type
,
1101 return new_binary_op (GCC_JIT_BINARY_OP_BITWISE_OR
,
1102 result_type
, a
, b
, loc
);
1105 context::new_logical_and (type result_type
,
1109 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_AND
,
1110 result_type
, a
, b
, loc
);
1113 context::new_logical_or (type result_type
,
1117 return new_binary_op (GCC_JIT_BINARY_OP_LOGICAL_OR
,
1118 result_type
, a
, b
, loc
);
1122 context::new_comparison (enum gcc_jit_comparison op
,
1126 return rvalue (gcc_jit_context_new_comparison (m_inner_ctxt
,
1127 loc
.get_inner_location (),
1129 a
.get_inner_rvalue (),
1130 b
.get_inner_rvalue ()));
1133 context::new_eq (rvalue a
, rvalue b
,
1136 return new_comparison (GCC_JIT_COMPARISON_EQ
,
1140 context::new_ne (rvalue a
, rvalue b
,
1143 return new_comparison (GCC_JIT_COMPARISON_NE
,
1147 context::new_lt (rvalue a
, rvalue b
,
1150 return new_comparison (GCC_JIT_COMPARISON_LT
,
1154 context::new_le (rvalue a
, rvalue b
,
1157 return new_comparison (GCC_JIT_COMPARISON_LE
,
1161 context::new_gt (rvalue a
, rvalue b
,
1164 return new_comparison (GCC_JIT_COMPARISON_GT
,
1168 context::new_ge (rvalue a
, rvalue b
,
1171 return new_comparison (GCC_JIT_COMPARISON_GE
,
1176 context::new_call (function func
,
1177 std::vector
<rvalue
> &args
,
1180 /* Treat std::vector as an array, relying on it not being resized: */
1181 rvalue
*as_array_of_wrappers
= &args
[0];
1183 /* Treat the array as being of the underlying pointers, relying on
1184 the wrapper type being such a pointer internally. */
1185 gcc_jit_rvalue
**as_array_of_ptrs
=
1186 reinterpret_cast<gcc_jit_rvalue
**> (as_array_of_wrappers
);
1187 return gcc_jit_context_new_call (m_inner_ctxt
,
1188 loc
.get_inner_location (),
1189 func
.get_inner_function (),
1194 context::new_call (function func
,
1197 std::vector
<rvalue
> args
;
1198 return new_call (func
, args
, loc
);
1202 context::new_call (function func
,
1206 std::vector
<rvalue
> args(1);
1208 return new_call (func
, args
, loc
);
1211 context::new_call (function func
,
1212 rvalue arg0
, rvalue arg1
,
1215 std::vector
<rvalue
> args(2);
1218 return new_call (func
, args
, loc
);
1221 context::new_call (function func
,
1222 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1225 std::vector
<rvalue
> args(3);
1229 return new_call (func
, args
, loc
);
1232 context::new_call (function func
,
1233 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1237 std::vector
<rvalue
> args(4);
1242 return new_call (func
, args
, loc
);
1245 context::new_call (function func
,
1246 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1247 rvalue arg3
, rvalue arg4
,
1250 std::vector
<rvalue
> args(5);
1256 return new_call (func
, args
, loc
);
1259 context::new_call (function func
,
1260 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1261 rvalue arg3
, rvalue arg4
, rvalue arg5
,
1264 std::vector
<rvalue
> args(6);
1271 return new_call (func
, args
, loc
);
1275 context::new_cast (rvalue expr
,
1279 return rvalue (gcc_jit_context_new_cast (m_inner_ctxt
,
1280 loc
.get_inner_location (),
1281 expr
.get_inner_rvalue (),
1282 type_
.get_inner_type ()));
1286 context::new_array_access (rvalue ptr
,
1290 return lvalue (gcc_jit_context_new_array_access (m_inner_ctxt
,
1291 loc
.get_inner_location (),
1292 ptr
.get_inner_rvalue (),
1293 index
.get_inner_rvalue ()));
1297 context::new_case (rvalue min_value
,
1301 return case_ (gcc_jit_context_new_case (m_inner_ctxt
,
1302 min_value
.get_inner_rvalue (),
1303 max_value
.get_inner_rvalue (),
1304 dest_block
.get_inner_block ()));
1308 context::add_top_level_asm (const char *asm_stmts
, location loc
)
1310 gcc_jit_context_add_top_level_asm (m_inner_ctxt
,
1311 loc
.get_inner_location (),
1317 object::get_context () const
1319 return context (gcc_jit_object_get_context (m_inner_obj
));
1323 object::get_debug_string () const
1325 return gcc_jit_object_get_debug_string (m_inner_obj
);
1328 inline object::object () : m_inner_obj (NULL
) {}
1329 inline object::object (gcc_jit_object
*obj
) : m_inner_obj (obj
)
1335 inline gcc_jit_object
*
1336 object::get_inner_object () const
1341 inline std::ostream
&
1342 operator << (std::ostream
& stream
, const object
&obj
)
1344 return stream
<< obj
.get_debug_string ();
1348 inline location::location () : object () {}
1349 inline location::location (gcc_jit_location
*loc
)
1350 : object (gcc_jit_location_as_object (loc
))
1353 inline gcc_jit_location
*
1354 location::get_inner_location () const
1356 /* Manual downcast: */
1357 return reinterpret_cast<gcc_jit_location
*> (get_inner_object ());
1361 inline field::field () : object () {}
1362 inline field::field (gcc_jit_field
*inner
)
1363 : object (gcc_jit_field_as_object (inner
))
1366 inline gcc_jit_field
*
1367 field::get_inner_field () const
1369 /* Manual downcast: */
1370 return reinterpret_cast<gcc_jit_field
*> (get_inner_object ());
1374 inline type::type () : object () {}
1375 inline type::type (gcc_jit_type
*inner
)
1376 : object (gcc_jit_type_as_object (inner
))
1379 inline gcc_jit_type
*
1380 type::get_inner_type () const
1382 /* Manual downcast: */
1383 return reinterpret_cast<gcc_jit_type
*> (get_inner_object ());
1387 type::get_pointer ()
1389 return type (gcc_jit_type_get_pointer (get_inner_type ()));
1395 return type (gcc_jit_type_get_const (get_inner_type ()));
1399 type::get_volatile ()
1401 return type (gcc_jit_type_get_volatile (get_inner_type ()));
1405 type::get_aligned (size_t alignment_in_bytes
)
1407 return type (gcc_jit_type_get_aligned (get_inner_type (),
1408 alignment_in_bytes
));
1412 type::get_vector (size_t num_units
)
1414 return type (gcc_jit_type_get_vector (get_inner_type (),
1421 return get_context ().new_rvalue (*this, 0);
1427 return get_context ().new_rvalue (*this, 1);
1431 inline struct_::struct_ () : type (NULL
) {}
1432 inline struct_::struct_ (gcc_jit_struct
*inner
) :
1433 type (gcc_jit_struct_as_type (inner
))
1437 inline gcc_jit_struct
*
1438 struct_::get_inner_struct () const
1440 /* Manual downcast: */
1441 return reinterpret_cast<gcc_jit_struct
*> (get_inner_object ());
1445 inline function::function () : object () {}
1446 inline function::function (gcc_jit_function
*inner
)
1447 : object (gcc_jit_function_as_object (inner
))
1450 inline gcc_jit_function
*
1451 function::get_inner_function () const
1453 /* Manual downcast: */
1454 return reinterpret_cast<gcc_jit_function
*> (get_inner_object ());
1458 function::dump_to_dot (const std::string
&path
)
1460 gcc_jit_function_dump_to_dot (get_inner_function (),
1465 function::get_param (int index
) const
1467 return param (gcc_jit_function_get_param (get_inner_function (),
1472 function::new_block ()
1474 return block (gcc_jit_function_new_block (get_inner_function (),
1479 function::new_block (const std::string
&name
)
1481 return block (gcc_jit_function_new_block (get_inner_function (),
1486 function::new_local (type type_
,
1487 const std::string
&name
,
1490 return lvalue (gcc_jit_function_new_local (get_inner_function (),
1491 loc
.get_inner_location (),
1492 type_
.get_inner_type (),
1497 function::get_address (location loc
)
1499 return rvalue (gcc_jit_function_get_address (get_inner_function (),
1500 loc
.get_inner_location ()));
1504 block::get_function () const
1506 return function (gcc_jit_block_get_function ( get_inner_block ()));
1510 block::add_eval (rvalue rvalue
,
1513 gcc_jit_block_add_eval (get_inner_block (),
1514 loc
.get_inner_location (),
1515 rvalue
.get_inner_rvalue ());
1519 block::add_assignment (lvalue lvalue
,
1523 gcc_jit_block_add_assignment (get_inner_block (),
1524 loc
.get_inner_location (),
1525 lvalue
.get_inner_lvalue (),
1526 rvalue
.get_inner_rvalue ());
1530 block::add_assignment_op (lvalue lvalue
,
1531 enum gcc_jit_binary_op op
,
1535 gcc_jit_block_add_assignment_op (get_inner_block (),
1536 loc
.get_inner_location (),
1537 lvalue
.get_inner_lvalue (),
1539 rvalue
.get_inner_rvalue ());
1543 block::add_comment (const std::string
&text
,
1546 gcc_jit_block_add_comment (get_inner_block (),
1547 loc
.get_inner_location (),
1552 block::end_with_conditional (rvalue boolval
,
1557 gcc_jit_block_end_with_conditional (get_inner_block (),
1558 loc
.get_inner_location (),
1559 boolval
.get_inner_rvalue (),
1560 on_true
.get_inner_block (),
1561 on_false
.get_inner_block ());
1565 block::end_with_jump (block target
,
1568 gcc_jit_block_end_with_jump (get_inner_block (),
1569 loc
.get_inner_location (),
1570 target
.get_inner_block ());
1574 block::end_with_return (rvalue rvalue
,
1577 gcc_jit_block_end_with_return (get_inner_block (),
1578 loc
.get_inner_location (),
1579 rvalue
.get_inner_rvalue ());
1583 block::end_with_return (location loc
)
1585 gcc_jit_block_end_with_void_return (get_inner_block (),
1586 loc
.get_inner_location ());
1590 block::end_with_switch (rvalue expr
,
1591 block default_block
,
1592 std::vector
<case_
> cases
,
1595 /* Treat std::vector as an array, relying on it not being resized: */
1596 case_
*as_array_of_wrappers
= &cases
[0];
1598 /* Treat the array as being of the underlying pointers, relying on
1599 the wrapper type being such a pointer internally. */
1600 gcc_jit_case
**as_array_of_ptrs
=
1601 reinterpret_cast<gcc_jit_case
**> (as_array_of_wrappers
);
1602 gcc_jit_block_end_with_switch (get_inner_block (),
1603 loc
.get_inner_location (),
1604 expr
.get_inner_rvalue (),
1605 default_block
.get_inner_block (),
1611 block::add_extended_asm (const std::string
&asm_template
,
1614 return gcc_jit_block_add_extended_asm (get_inner_block (),
1615 loc
.get_inner_location (),
1616 asm_template
.c_str ());
1620 block::end_with_extended_asm_goto (const std::string
&asm_template
,
1621 std::vector
<block
> goto_blocks
,
1622 block
*fallthrough_block
,
1625 /* Treat std::vector as an array, relying on it not being resized: */
1626 block
*as_array_of_wrappers
= &goto_blocks
[0];
1628 /* Treat the array as being of the underlying pointers, relying on
1629 the wrapper type being such a pointer internally. */
1630 gcc_jit_block
**as_array_of_ptrs
=
1631 reinterpret_cast<gcc_jit_block
**> (as_array_of_wrappers
);
1632 return gcc_jit_block_end_with_extended_asm_goto
1633 (get_inner_block (),
1634 loc
.get_inner_location (),
1635 asm_template
.c_str (),
1636 goto_blocks
.size (),
1638 fallthrough_block
? fallthrough_block
->get_inner_block () : NULL
);
1642 block::add_call (function other
,
1645 rvalue c
= get_context ().new_call (other
, loc
);
1650 block::add_call (function other
,
1654 rvalue c
= get_context ().new_call (other
, arg0
, loc
);
1659 block::add_call (function other
,
1660 rvalue arg0
, rvalue arg1
,
1663 rvalue c
= get_context ().new_call (other
, arg0
, arg1
, loc
);
1668 block::add_call (function other
,
1669 rvalue arg0
, rvalue arg1
, rvalue arg2
,
1672 rvalue c
= get_context ().new_call (other
, arg0
, arg1
, arg2
, loc
);
1678 block::add_call (function other
,
1679 rvalue arg0
, rvalue arg1
, rvalue arg2
, rvalue arg3
,
1682 rvalue c
= get_context ().new_call (other
, arg0
, arg1
, arg2
, arg3
, loc
);
1688 function::operator() (location loc
)
1690 return get_context ().new_call (*this, loc
);
1693 function::operator() (rvalue arg0
,
1696 return get_context ().new_call (*this,
1701 function::operator() (rvalue arg0
, rvalue arg1
,
1704 return get_context ().new_call (*this,
1709 function::operator() (rvalue arg0
, rvalue arg1
, rvalue arg2
,
1712 return get_context ().new_call (*this,
1718 inline block::block () : object () {}
1719 inline block::block (gcc_jit_block
*inner
)
1720 : object (gcc_jit_block_as_object (inner
))
1723 inline gcc_jit_block
*
1724 block::get_inner_block () const
1726 /* Manual downcast: */
1727 return reinterpret_cast<gcc_jit_block
*> (get_inner_object ());
1731 inline rvalue::rvalue () : object () {}
1732 inline rvalue::rvalue (gcc_jit_rvalue
*inner
)
1733 : object (gcc_jit_rvalue_as_object (inner
))
1736 inline gcc_jit_rvalue
*
1737 rvalue::get_inner_rvalue () const
1739 /* Manual downcast: */
1740 return reinterpret_cast<gcc_jit_rvalue
*> (get_inner_object ());
1746 return type (gcc_jit_rvalue_get_type (get_inner_rvalue ()));
1750 rvalue::access_field (field field
,
1753 return rvalue (gcc_jit_rvalue_access_field (get_inner_rvalue (),
1754 loc
.get_inner_location (),
1755 field
.get_inner_field ()));
1759 rvalue::dereference_field (field field
,
1762 return lvalue (gcc_jit_rvalue_dereference_field (get_inner_rvalue (),
1763 loc
.get_inner_location (),
1764 field
.get_inner_field ()));
1768 rvalue::dereference (location loc
)
1770 return lvalue (gcc_jit_rvalue_dereference (get_inner_rvalue (),
1771 loc
.get_inner_location ()));
1775 rvalue::cast_to (type type_
,
1778 return get_context ().new_cast (*this, type_
, loc
);
1782 rvalue::operator[] (rvalue index
)
1784 return get_context ().new_array_access (*this, index
);
1788 rvalue::operator[] (int index
)
1790 context ctxt
= get_context ();
1791 type int_t
= ctxt
.get_int_type
<int> ();
1792 return ctxt
.new_array_access (*this,
1793 ctxt
.new_rvalue (int_t
,
1797 // class lvalue : public rvalue
1798 inline lvalue::lvalue () : rvalue () {}
1799 inline lvalue::lvalue (gcc_jit_lvalue
*inner
)
1800 : rvalue (gcc_jit_lvalue_as_rvalue (inner
))
1803 inline gcc_jit_lvalue
*
1804 lvalue::get_inner_lvalue () const
1806 /* Manual downcast: */
1807 return reinterpret_cast<gcc_jit_lvalue
*> (get_inner_object ());
1811 lvalue::access_field (field field
, location loc
)
1813 return lvalue (gcc_jit_lvalue_access_field (get_inner_lvalue (),
1814 loc
.get_inner_location (),
1815 field
.get_inner_field ()));
1819 lvalue::get_address (location loc
)
1821 return rvalue (gcc_jit_lvalue_get_address (get_inner_lvalue (),
1822 loc
.get_inner_location ()));
1826 lvalue::set_initializer (const void *blob
, size_t num_bytes
)
1828 gcc_jit_global_set_initializer (get_inner_lvalue (),
1834 // class param : public lvalue
1835 inline param::param () : lvalue () {}
1836 inline param::param (gcc_jit_param
*inner
)
1837 : lvalue (gcc_jit_param_as_lvalue (inner
))
1840 // class case_ : public object
1841 inline case_::case_ () : object () {}
1842 inline case_::case_ (gcc_jit_case
*inner
)
1843 : object (gcc_jit_case_as_object (inner
))
1847 inline gcc_jit_case
*
1848 case_::get_inner_case () const
1850 /* Manual downcast: */
1851 return reinterpret_cast<gcc_jit_case
*> (get_inner_object ());
1854 // class extended_asm : public object
1855 inline extended_asm::extended_asm () : object () {}
1856 inline extended_asm::extended_asm (gcc_jit_extended_asm
*inner
)
1857 : object (gcc_jit_extended_asm_as_object (inner
))
1861 inline extended_asm
&
1862 extended_asm::set_volatile_flag (bool flag
)
1864 gcc_jit_extended_asm_set_volatile_flag (get_inner_extended_asm (), flag
);
1868 inline extended_asm
&
1869 extended_asm::set_inline_flag (bool flag
)
1871 gcc_jit_extended_asm_set_inline_flag (get_inner_extended_asm (), flag
);
1875 inline extended_asm
&
1876 extended_asm::add_output_operand (const std::string
&asm_symbolic_name
,
1877 const std::string
&constraint
,
1878 gccjit::lvalue dest
)
1880 gcc_jit_extended_asm_add_output_operand
1881 (get_inner_extended_asm (),
1882 asm_symbolic_name
.c_str (),
1883 constraint
.c_str (),
1884 dest
.get_inner_lvalue ());
1888 inline extended_asm
&
1889 extended_asm::add_output_operand (const std::string
&constraint
,
1890 gccjit::lvalue dest
)
1892 gcc_jit_extended_asm_add_output_operand
1893 (get_inner_extended_asm (),
1894 NULL
, /* asm_symbolic_name */
1895 constraint
.c_str (),
1896 dest
.get_inner_lvalue ());
1900 inline extended_asm
&
1901 extended_asm::add_input_operand (const std::string
&asm_symbolic_name
,
1902 const std::string
&constraint
,
1905 gcc_jit_extended_asm_add_input_operand
1906 (get_inner_extended_asm (),
1907 asm_symbolic_name
.c_str (),
1908 constraint
.c_str (),
1909 src
.get_inner_rvalue ());
1913 inline extended_asm
&
1914 extended_asm::add_input_operand (const std::string
&constraint
,
1917 gcc_jit_extended_asm_add_input_operand
1918 (get_inner_extended_asm (),
1919 NULL
, /* asm_symbolic_name */
1920 constraint
.c_str (),
1921 src
.get_inner_rvalue ());
1925 inline extended_asm
&
1926 extended_asm::add_clobber (const std::string
&victim
)
1928 gcc_jit_extended_asm_add_clobber (get_inner_extended_asm (),
1933 inline gcc_jit_extended_asm
*
1934 extended_asm::get_inner_extended_asm () const
1936 /* Manual downcast: */
1937 return reinterpret_cast<gcc_jit_extended_asm
*> (get_inner_object ());
1940 /* Overloaded operators. */
1942 inline rvalue
operator- (rvalue a
)
1944 return a
.get_context ().new_minus (a
.get_type (), a
);
1946 inline rvalue
operator~ (rvalue a
)
1948 return a
.get_context ().new_bitwise_negate (a
.get_type (), a
);
1950 inline rvalue
operator! (rvalue a
)
1952 return a
.get_context ().new_logical_negate (a
.get_type (), a
);
1956 inline rvalue
operator+ (rvalue a
, rvalue b
)
1958 return a
.get_context ().new_plus (a
.get_type (), a
, b
);
1960 inline rvalue
operator- (rvalue a
, rvalue b
)
1962 return a
.get_context ().new_minus (a
.get_type (), a
, b
);
1964 inline rvalue
operator* (rvalue a
, rvalue b
)
1966 return a
.get_context ().new_mult (a
.get_type (), a
, b
);
1968 inline rvalue
operator/ (rvalue a
, rvalue b
)
1970 return a
.get_context ().new_divide (a
.get_type (), a
, b
);
1972 inline rvalue
operator% (rvalue a
, rvalue b
)
1974 return a
.get_context ().new_modulo (a
.get_type (), a
, b
);
1976 inline rvalue
operator& (rvalue a
, rvalue b
)
1978 return a
.get_context ().new_bitwise_and (a
.get_type (), a
, b
);
1980 inline rvalue
operator^ (rvalue a
, rvalue b
)
1982 return a
.get_context ().new_bitwise_xor (a
.get_type (), a
, b
);
1984 inline rvalue
operator| (rvalue a
, rvalue b
)
1986 return a
.get_context ().new_bitwise_or (a
.get_type (), a
, b
);
1988 inline rvalue
operator&& (rvalue a
, rvalue b
)
1990 return a
.get_context ().new_logical_and (a
.get_type (), a
, b
);
1992 inline rvalue
operator|| (rvalue a
, rvalue b
)
1994 return a
.get_context ().new_logical_or (a
.get_type (), a
, b
);
1998 inline rvalue
operator== (rvalue a
, rvalue b
)
2000 return a
.get_context ().new_eq (a
, b
);
2002 inline rvalue
operator!= (rvalue a
, rvalue b
)
2004 return a
.get_context ().new_ne (a
, b
);
2006 inline rvalue
operator< (rvalue a
, rvalue b
)
2008 return a
.get_context ().new_lt (a
, b
);
2010 inline rvalue
operator<= (rvalue a
, rvalue b
)
2012 return a
.get_context ().new_le (a
, b
);
2014 inline rvalue
operator> (rvalue a
, rvalue b
)
2016 return a
.get_context ().new_gt (a
, b
);
2018 inline rvalue
operator>= (rvalue a
, rvalue b
)
2020 return a
.get_context ().new_ge (a
, b
);
2023 /* Dereferencing. */
2024 inline lvalue
operator* (rvalue ptr
)
2026 return ptr
.dereference ();
2033 m_inner_timer
= gcc_jit_timer_new ();
2037 timer::timer (gcc_jit_timer
*inner_timer
)
2039 m_inner_timer
= inner_timer
;
2043 timer::push (const char *item_name
)
2045 gcc_jit_timer_push (m_inner_timer
, item_name
);
2050 timer::pop (const char *item_name
)
2052 gcc_jit_timer_pop (m_inner_timer
, item_name
);
2056 timer::print (FILE *f_out
) const
2058 gcc_jit_timer_print (m_inner_timer
, f_out
);
2061 inline gcc_jit_timer
*
2062 timer::get_inner_timer () const
2064 return m_inner_timer
;
2070 gcc_jit_timer_release (m_inner_timer
);
2071 m_inner_timer
= NULL
;
2077 auto_time::auto_time (timer t
, const char *item_name
)
2079 m_item_name (item_name
)
2085 auto_time::auto_time (context ctxt
, const char *item_name
)
2086 : m_timer (ctxt
.get_timer ()),
2087 m_item_name (item_name
)
2089 m_timer
.push (item_name
);
2093 auto_time::~auto_time ()
2095 m_timer
.pop (m_item_name
);
2103 return gcc_jit_version_major ();
2109 return gcc_jit_version_minor ();
2115 return gcc_jit_version_patchlevel ();
2117 } // namespace version
2118 } // namespace gccjit
2120 #endif /* #ifndef LIBGCCJIT_PLUS_PLUS_H */