Expressions¶
Rvalues¶
-
gcc_jit_rvalue
¶
A gcc_jit_rvalue *
is an expression that can be computed.
It can be simple, e.g.:
an integer value e.g. 0 or 42
a string literal e.g. “Hello world”
a variable e.g. i. These are also lvalues (see below).
or compound e.g.:
a unary expression e.g. !cond
a binary expression e.g. (a + b)
a function call e.g. get_distance (&player_ship, &target)
etc.
Every rvalue has an associated type, and the API will check to ensure that types match up correctly (otherwise the context will emit an error).
-
gcc_jit_type *
gcc_jit_rvalue_get_type
(gcc_jit_rvalue *rvalue)¶ Get the type of this rvalue.
-
gcc_jit_object *
gcc_jit_rvalue_as_object
(gcc_jit_rvalue *rvalue)¶ Upcast the given rvalue to be an object.
Simple expressions¶
-
gcc_jit_rvalue *
gcc_jit_context_new_rvalue_from_int
(gcc_jit_context *ctxt, gcc_jit_type *numeric_type, int value)¶ Given a numeric type (integer or floating point), build an rvalue for the given constant
int
value.
-
gcc_jit_rvalue *
gcc_jit_context_new_rvalue_from_long
(gcc_jit_context *ctxt, gcc_jit_type *numeric_type, long value)¶ Given a numeric type (integer or floating point), build an rvalue for the given constant
long
value.
-
gcc_jit_rvalue *
gcc_jit_context_zero
(gcc_jit_context *ctxt, gcc_jit_type *numeric_type)¶ Given a numeric type (integer or floating point), get the rvalue for zero. Essentially this is just a shortcut for:
gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 0)
-
gcc_jit_rvalue *
gcc_jit_context_one
(gcc_jit_context *ctxt, gcc_jit_type *numeric_type)¶ Given a numeric type (integer or floating point), get the rvalue for one. Essentially this is just a shortcut for:
gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 1)
-
gcc_jit_rvalue *
gcc_jit_context_new_rvalue_from_double
(gcc_jit_context *ctxt, gcc_jit_type *numeric_type, double value)¶ Given a numeric type (integer or floating point), build an rvalue for the given constant
double
value.
-
gcc_jit_rvalue *
gcc_jit_context_new_rvalue_from_ptr
(gcc_jit_context *ctxt, gcc_jit_type *pointer_type, void *value)¶ Given a pointer type, build an rvalue for the given address.
-
gcc_jit_rvalue *
gcc_jit_context_null
(gcc_jit_context *ctxt, gcc_jit_type *pointer_type)¶ Given a pointer type, build an rvalue for
NULL
. Essentially this is just a shortcut for:gcc_jit_context_new_rvalue_from_ptr (ctxt, pointer_type, NULL)
-
gcc_jit_rvalue *
gcc_jit_context_new_string_literal
(gcc_jit_context *ctxt, const char *value)¶ Generate an rvalue for the given NIL-terminated string, of type
GCC_JIT_TYPE_CONST_CHAR_PTR
.The parameter
value
must be non-NULL. The call takes a copy of the underlying string, so it is valid to pass in a pointer to an on-stack buffer.
Vector expressions¶
-
gcc_jit_rvalue *
gcc_jit_context_new_rvalue_from_vector
(gcc_jit_context *ctxt, gcc_jit_location *loc, gcc_jit_type *vec_type, size_t num_elements, gcc_jit_rvalue **elements)¶ Build a vector rvalue from an array of elements.
“vec_type” should be a vector type, created using
gcc_jit_type_get_vector()
.“num_elements” should match that of the vector type.
This entrypoint was added in LIBGCCJIT_ABI_10; you can test for its presence using
#ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_rvalue_from_vector
Unary Operations¶
-
gcc_jit_rvalue *
gcc_jit_context_new_unary_op
(gcc_jit_context *ctxt, gcc_jit_location *loc, enum gcc_jit_unary_op op, gcc_jit_type *result_type, gcc_jit_rvalue *rvalue)¶ Build a unary operation out of an input rvalue.
The parameter
result_type
must be a numeric type.
-
enum
gcc_jit_unary_op
¶
The available unary operations are:
Unary Operation |
C equivalent |
---|---|
-(EXPR) |
|
~(EXPR) |
|
!(EXPR) |
|
abs (EXPR) |
-
GCC_JIT_UNARY_OP_MINUS
¶ Negate an arithmetic value; analogous to:
-(EXPR)
in C.
-
GCC_JIT_UNARY_OP_BITWISE_NEGATE
¶ Bitwise negation of an integer value (one’s complement); analogous to:
~(EXPR)
in C.
-
GCC_JIT_UNARY_OP_LOGICAL_NEGATE
¶ Logical negation of an arithmetic or pointer value; analogous to:
!(EXPR)
in C.
-
GCC_JIT_UNARY_OP_ABS
¶ Absolute value of an arithmetic expression; analogous to:
abs (EXPR)
in C.
Binary Operations¶
-
gcc_jit_rvalue *
gcc_jit_context_new_binary_op
(gcc_jit_context *ctxt, gcc_jit_location *loc, enum gcc_jit_binary_op op, gcc_jit_type *result_type, gcc_jit_rvalue *a, gcc_jit_rvalue *b)¶ Build a binary operation out of two constituent rvalues.
The parameter
result_type
must be a numeric type.
-
enum
gcc_jit_binary_op
¶
The available binary operations are:
Binary Operation |
C equivalent |
---|---|
x + y |
|
x - y |
|
x * y |
|
x / y |
|
x % y |
|
x & y |
|
x ^ y |
|
x | y |
|
x && y |
|
x || y |
|
x << y |
|
x >> y |
-
GCC_JIT_BINARY_OP_PLUS
¶ Addition of arithmetic values; analogous to:
(EXPR_A) + (EXPR_B)
in C.
For pointer addition, use
gcc_jit_context_new_array_access()
.
-
GCC_JIT_BINARY_OP_MINUS
¶ Subtraction of arithmetic values; analogous to:
(EXPR_A) - (EXPR_B)
in C.
-
GCC_JIT_BINARY_OP_MULT
¶ Multiplication of a pair of arithmetic values; analogous to:
(EXPR_A) * (EXPR_B)
in C.
-
GCC_JIT_BINARY_OP_DIVIDE
¶ Quotient of division of arithmetic values; analogous to:
(EXPR_A) / (EXPR_B)
in C.
The result type affects the kind of division: if the result type is integer-based, then the result is truncated towards zero, whereas a floating-point result type indicates floating-point division.
-
GCC_JIT_BINARY_OP_MODULO
¶ Remainder of division of arithmetic values; analogous to:
(EXPR_A) % (EXPR_B)
in C.
-
GCC_JIT_BINARY_OP_BITWISE_AND
¶ Bitwise AND; analogous to:
(EXPR_A) & (EXPR_B)
in C.
-
GCC_JIT_BINARY_OP_BITWISE_XOR
¶ Bitwise exclusive OR; analogous to:
(EXPR_A) ^ (EXPR_B)
in C.
-
GCC_JIT_BINARY_OP_BITWISE_OR
¶ Bitwise inclusive OR; analogous to:
(EXPR_A) | (EXPR_B)
in C.
-
GCC_JIT_BINARY_OP_LOGICAL_AND
¶ Logical AND; analogous to:
(EXPR_A) && (EXPR_B)
in C.
-
GCC_JIT_BINARY_OP_LOGICAL_OR
¶ Logical OR; analogous to:
(EXPR_A) || (EXPR_B)
in C.
-
GCC_JIT_BINARY_OP_LSHIFT
¶ Left shift; analogous to:
(EXPR_A) << (EXPR_B)
in C.
-
GCC_JIT_BINARY_OP_RSHIFT
¶ Right shift; analogous to:
(EXPR_A) >> (EXPR_B)
in C.
Comparisons¶
-
gcc_jit_rvalue *
gcc_jit_context_new_comparison
(gcc_jit_context *ctxt, gcc_jit_location *loc, enum gcc_jit_comparison op, gcc_jit_rvalue *a, gcc_jit_rvalue *b)¶ Build a boolean rvalue out of the comparison of two other rvalues.
-
enum
gcc_jit_comparison
¶
Comparison |
C equivalent |
---|---|
|
x == y |
|
x != y |
|
x < y |
|
x <= y |
|
x > y |
|
x >= y |
Function calls¶
-
gcc_jit_rvalue *
gcc_jit_context_new_call
(gcc_jit_context *ctxt, gcc_jit_location *loc, gcc_jit_function *func, int numargs, gcc_jit_rvalue **args)¶ Given a function and the given table of argument rvalues, construct a call to the function, with the result as an rvalue.
Note
gcc_jit_context_new_call()
merely builds agcc_jit_rvalue
i.e. an expression that can be evaluated, perhaps as part of a more complicated expression. The call won’t happen unless you add a statement to a function that evaluates the expression.For example, if you want to call a function and discard the result (or to call a function with
void
return type), usegcc_jit_block_add_eval()
:/* Add "(void)printf (arg0, arg1);". */ gcc_jit_block_add_eval ( block, NULL, gcc_jit_context_new_call ( ctxt, NULL, printf_func, 2, args));
-
gcc_jit_rvalue *
gcc_jit_context_new_call_through_ptr
(gcc_jit_context *ctxt, gcc_jit_location *loc, gcc_jit_rvalue *fn_ptr, int numargs, gcc_jit_rvalue **args)¶ Given an rvalue of function pointer type (e.g. from
gcc_jit_context_new_function_ptr_type()
), and the given table of argument rvalues, construct a call to the function pointer, with the result as an rvalue.Note
The same caveat as for
gcc_jit_context_new_call()
applies.
-
void
gcc_jit_rvalue_set_bool_require_tail_call
(gcc_jit_rvalue *call, int require_tail_call)¶ Given an
gcc_jit_rvalue *
for a call created throughgcc_jit_context_new_call()
orgcc_jit_context_new_call_through_ptr()
, mark/clear the call as needing tail-call optimization. The optimizer will attempt to optimize the call into a jump instruction; if it is unable to do do, an error will be emitted.This may be useful when implementing functions that use the continuation-passing style (e.g. for functional programming languages), in which every function “returns” by calling a “continuation” function pointer. This call must be guaranteed to be implemented as a jump, otherwise the program could consume an arbitrary amount of stack space as it executed.
This entrypoint was added in LIBGCCJIT_ABI_6; you can test for its presence using
#ifdef LIBGCCJIT_HAVE_gcc_jit_rvalue_set_bool_require_tail_call
Function pointers¶
Function pointers can be obtained:
from a
gcc_jit_function
usinggcc_jit_function_get_address()
, orfrom an existing function using
gcc_jit_context_new_rvalue_from_ptr()
, using a function pointer type obtained usinggcc_jit_context_new_function_ptr_type()
.
Type-coercion¶
-
gcc_jit_rvalue *
gcc_jit_context_new_cast
(gcc_jit_context *ctxt, gcc_jit_location *loc, gcc_jit_rvalue *rvalue, gcc_jit_type *type)¶ Given an rvalue of T, construct another rvalue of another type.
Currently only a limited set of conversions are possible:
int <-> float
int <-> bool
P* <-> Q*, for pointer types P and Q
Lvalues¶
-
gcc_jit_lvalue
¶
An lvalue is something that can of the left-hand side of an assignment: a storage area (such as a variable). It is also usable as an rvalue, where the rvalue is computed by reading from the storage area.
-
gcc_jit_object *
gcc_jit_lvalue_as_object
(gcc_jit_lvalue *lvalue)¶ Upcast an lvalue to be an object.
-
gcc_jit_rvalue *
gcc_jit_lvalue_as_rvalue
(gcc_jit_lvalue *lvalue)¶ Upcast an lvalue to be an rvalue.
-
gcc_jit_rvalue *
gcc_jit_lvalue_get_address
(gcc_jit_lvalue *lvalue, gcc_jit_location *loc)¶ Take the address of an lvalue; analogous to:
&(EXPR)
in C.
Global variables¶
-
gcc_jit_lvalue *
gcc_jit_context_new_global
(gcc_jit_context *ctxt, gcc_jit_location *loc, enum gcc_jit_global_kind kind, gcc_jit_type *type, const char *name)¶ Add a new global variable of the given type and name to the context.
The parameter
type
must be non-void.The parameter
name
must be non-NULL. The call takes a copy of the underlying string, so it is valid to pass in a pointer to an on-stack buffer.The “kind” parameter determines the visibility of the “global” outside of the
gcc_jit_result
:-
enum
gcc_jit_global_kind
¶
-
GCC_JIT_GLOBAL_EXPORTED
¶ Global is defined by the client code and is visible by name outside of this JIT context via
gcc_jit_result_get_global()
(and this value is required for the global to be accessible via that entrypoint).
-
GCC_JIT_GLOBAL_INTERNAL
¶ Global is defined by the client code, but is invisible outside of it. Analogous to a “static” global within a .c file. Specifically, the variable will only be visible within this context and within child contexts.
-
GCC_JIT_GLOBAL_IMPORTED
¶ Global is not defined by the client code; we’re merely referring to it. Analogous to using an “extern” global from a header file.
-
enum
Working with pointers, structs and unions¶
-
gcc_jit_lvalue *
gcc_jit_rvalue_dereference
(gcc_jit_rvalue *rvalue, gcc_jit_location *loc)¶ Given an rvalue of pointer type
T *
, dereferencing the pointer, getting an lvalue of typeT
. Analogous to:*(EXPR)
in C.
Field access is provided separately for both lvalues and rvalues.
-
gcc_jit_lvalue *
gcc_jit_lvalue_access_field
(gcc_jit_lvalue *struct_, gcc_jit_location *loc, gcc_jit_field *field)¶ Given an lvalue of struct or union type, access the given field, getting an lvalue of the field’s type. Analogous to:
(EXPR).field = ...;
in C.
-
gcc_jit_rvalue *
gcc_jit_rvalue_access_field
(gcc_jit_rvalue *struct_, gcc_jit_location *loc, gcc_jit_field *field)¶ Given an rvalue of struct or union type, access the given field as an rvalue. Analogous to:
(EXPR).field
in C.
-
gcc_jit_lvalue *
gcc_jit_rvalue_dereference_field
(gcc_jit_rvalue *ptr, gcc_jit_location *loc, gcc_jit_field *field)¶ Given an rvalue of pointer type
T *
where T is of struct or union type, access the given field as an lvalue. Analogous to:(EXPR)->field
in C, itself equivalent to
(*EXPR).FIELD
.
-
gcc_jit_lvalue *
gcc_jit_context_new_array_access
(gcc_jit_context *ctxt, gcc_jit_location *loc, gcc_jit_rvalue *ptr, gcc_jit_rvalue *index)¶ Given an rvalue of pointer type
T *
, get at the element T at the given index, using standard C array indexing rules i.e. each increment ofindex
corresponds tosizeof(T)
bytes. Analogous to:PTR[INDEX]
in C (or, indeed, to
PTR + INDEX
).