A :c:type:`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).
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)
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)
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)
Generate an rvalue for the given NIL-terminated string, of type :c:data:`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.
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
The available unary operations are:
Unary Operation | C equivalent |
---|---|
:c:macro:`GCC_JIT_UNARY_OP_MINUS` | -(EXPR) |
:c:macro:`GCC_JIT_UNARY_OP_BITWISE_NEGATE` | ~(EXPR) |
:c:macro:`GCC_JIT_UNARY_OP_LOGICAL_NEGATE` | !(EXPR) |
:c:macro:`GCC_JIT_UNARY_OP_ABS` | abs (EXPR) |
The available binary operations are:
Binary Operation | C equivalent |
---|---|
:c:macro:`GCC_JIT_BINARY_OP_PLUS` | x + y |
:c:macro:`GCC_JIT_BINARY_OP_MINUS` | x - y |
:c:macro:`GCC_JIT_BINARY_OP_MULT` | x * y |
:c:macro:`GCC_JIT_BINARY_OP_DIVIDE` | x / y |
:c:macro:`GCC_JIT_BINARY_OP_MODULO` | x % y |
:c:macro:`GCC_JIT_BINARY_OP_BITWISE_AND` | x & y |
:c:macro:`GCC_JIT_BINARY_OP_BITWISE_XOR` | x ^ y |
:c:macro:`GCC_JIT_BINARY_OP_BITWISE_OR` | x | y |
:c:macro:`GCC_JIT_BINARY_OP_LOGICAL_AND` | x && y |
:c:macro:`GCC_JIT_BINARY_OP_LOGICAL_OR` | x || y |
:c:macro:`GCC_JIT_BINARY_OP_LSHIFT` | x << y |
:c:macro:`GCC_JIT_BINARY_OP_RSHIFT` | x >> y |
Comparison | C equivalent |
---|---|
:c:macro:`GCC_JIT_COMPARISON_EQ` | x == y |
:c:macro:`GCC_JIT_COMPARISON_NE` | x != y |
:c:macro:`GCC_JIT_COMPARISON_LT` | x < y |
:c:macro:`GCC_JIT_COMPARISON_LE` | x <= y |
:c:macro:`GCC_JIT_COMPARISON_GT` | x > y |
:c:macro:`GCC_JIT_COMPARISON_GE` | x >= y |
Given a function and the given table of argument rvalues, construct a call to the function, with the result as an rvalue.
Note
:c:func:`gcc_jit_context_new_call` merely builds a :c:type:`gcc_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), use :c:func:`gcc_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));
Given an rvalue of function pointer type (e.g. from :c:func:`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 :c:func:`gcc_jit_context_new_call` applies.
Given an :c:type:`gcc_jit_rvalue *` for a call created through :c:func:`gcc_jit_context_new_call` or :c:func:`gcc_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 can be obtained:
- from a :c:type:`gcc_jit_function` using :c:func:`gcc_jit_function_get_address`, or
- from an existing function using :c:func:`gcc_jit_context_new_rvalue_from_ptr`, using a function pointer type obtained using :c:func:`gcc_jit_context_new_function_ptr_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
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.
Take the address of an lvalue; analogous to:
&(EXPR)
in C.
Add a new global variable of the given type and name to the context.
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 :c:type:`gcc_jit_result`:
Given an rvalue of pointer type T *, dereferencing the pointer, getting an lvalue of type T. Analogous to:
*(EXPR)
in C.
Field access is provided separately for both lvalues and rvalues.
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.
Given an rvalue of struct or union type, access the given field as an rvalue. Analogous to:
(EXPR).field
in C.
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.
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 of index corresponds to sizeof(T) bytes. Analogous to:
PTR[INDEX]
in C (or, indeed, to PTR + INDEX).