diff gcc/jit/docs/topics/expressions.rst @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children 84e7813d76e9
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gcc/jit/docs/topics/expressions.rst	Fri Oct 27 22:46:09 2017 +0900
@@ -0,0 +1,654 @@
+.. Copyright (C) 2014-2017 Free Software Foundation, Inc.
+   Originally contributed by David Malcolm <dmalcolm@redhat.com>
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+
+.. default-domain:: c
+
+Expressions
+===========
+
+Rvalues
+-------
+.. type:: gcc_jit_rvalue
+
+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).
+
+.. function:: gcc_jit_type *gcc_jit_rvalue_get_type (gcc_jit_rvalue *rvalue)
+
+  Get the type of this rvalue.
+
+.. function:: gcc_jit_object *gcc_jit_rvalue_as_object (gcc_jit_rvalue *rvalue)
+
+  Upcast the given rvalue to be an object.
+
+
+Simple expressions
+******************
+
+.. function:: 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 :c:type:`int` value.
+
+.. function:: 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 :c:type:`long` value.
+
+.. function::  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:
+
+   .. code-block:: c
+
+      gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 0)
+
+.. function::  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:
+
+   .. code-block:: c
+
+      gcc_jit_context_new_rvalue_from_int (ctxt, numeric_type, 1)
+
+.. function::  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 :c:type:`double` value.
+
+.. function:: 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.
+
+.. function:: 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:
+
+   .. code-block:: c
+
+      gcc_jit_context_new_rvalue_from_ptr (ctxt, pointer_type, NULL)
+
+.. function:: 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
+   :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.
+
+Vector expressions
+******************
+
+.. function:: 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
+   :func:`gcc_jit_type_get_vector`.
+
+   "num_elements" should match that of the vector type.
+
+   This entrypoint was added in :ref:`LIBGCCJIT_ABI_10`; you can test for
+   its presence using
+
+   .. code-block:: c
+
+      #ifdef LIBGCCJIT_HAVE_gcc_jit_context_new_rvalue_from_vector
+
+Unary Operations
+****************
+
+.. function:: 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.
+
+.. type:: enum gcc_jit_unary_op
+
+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)`
+==========================================  ============
+
+.. c:macro:: GCC_JIT_UNARY_OP_MINUS
+
+    Negate an arithmetic value; analogous to:
+
+    .. code-block:: c
+
+       -(EXPR)
+
+    in C.
+
+.. c:macro:: GCC_JIT_UNARY_OP_BITWISE_NEGATE
+
+    Bitwise negation of an integer value (one's complement); analogous
+    to:
+
+    .. code-block:: c
+
+       ~(EXPR)
+
+    in C.
+
+.. c:macro:: GCC_JIT_UNARY_OP_LOGICAL_NEGATE
+
+    Logical negation of an arithmetic or pointer value; analogous to:
+
+    .. code-block:: c
+
+       !(EXPR)
+
+    in C.
+
+.. c:macro:: GCC_JIT_UNARY_OP_ABS
+
+    Absolute value of an arithmetic expression; analogous to:
+
+    .. code-block:: c
+
+        abs (EXPR)
+
+    in C.
+
+Binary Operations
+*****************
+
+.. function:: 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.
+
+.. type:: enum gcc_jit_binary_op
+
+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`
+========================================  ============
+
+.. c:macro:: GCC_JIT_BINARY_OP_PLUS
+
+   Addition of arithmetic values; analogous to:
+
+   .. code-block:: c
+
+     (EXPR_A) + (EXPR_B)
+
+   in C.
+
+   For pointer addition, use :c:func:`gcc_jit_context_new_array_access`.
+
+.. c:macro:: GCC_JIT_BINARY_OP_MINUS
+
+   Subtraction of arithmetic values; analogous to:
+
+   .. code-block:: c
+
+     (EXPR_A) - (EXPR_B)
+
+   in C.
+
+.. c:macro:: GCC_JIT_BINARY_OP_MULT
+
+   Multiplication of a pair of arithmetic values; analogous to:
+
+   .. code-block:: c
+
+     (EXPR_A) * (EXPR_B)
+
+   in C.
+
+.. c:macro:: GCC_JIT_BINARY_OP_DIVIDE
+
+   Quotient of division of arithmetic values; analogous to:
+
+   .. code-block:: c
+
+     (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.
+
+.. c:macro:: GCC_JIT_BINARY_OP_MODULO
+
+   Remainder of division of arithmetic values; analogous to:
+
+   .. code-block:: c
+
+     (EXPR_A) % (EXPR_B)
+
+   in C.
+
+.. c:macro:: GCC_JIT_BINARY_OP_BITWISE_AND
+
+   Bitwise AND; analogous to:
+
+   .. code-block:: c
+
+     (EXPR_A) & (EXPR_B)
+
+   in C.
+
+.. c:macro:: GCC_JIT_BINARY_OP_BITWISE_XOR
+
+   Bitwise exclusive OR; analogous to:
+
+   .. code-block:: c
+
+      (EXPR_A) ^ (EXPR_B)
+
+   in C.
+
+.. c:macro:: GCC_JIT_BINARY_OP_BITWISE_OR
+
+   Bitwise inclusive OR; analogous to:
+
+   .. code-block:: c
+
+     (EXPR_A) | (EXPR_B)
+
+   in C.
+
+.. c:macro:: GCC_JIT_BINARY_OP_LOGICAL_AND
+
+   Logical AND; analogous to:
+
+   .. code-block:: c
+
+     (EXPR_A) && (EXPR_B)
+
+   in C.
+
+.. c:macro:: GCC_JIT_BINARY_OP_LOGICAL_OR
+
+   Logical OR; analogous to:
+
+   .. code-block:: c
+
+     (EXPR_A) || (EXPR_B)
+
+   in C.
+
+.. c:macro:: GCC_JIT_BINARY_OP_LSHIFT
+
+   Left shift; analogous to:
+
+   .. code-block:: c
+
+     (EXPR_A) << (EXPR_B)
+
+   in C.
+
+.. c:macro:: GCC_JIT_BINARY_OP_RSHIFT
+
+   Right shift; analogous to:
+
+   .. code-block:: c
+
+     (EXPR_A) >> (EXPR_B)
+
+   in C.
+
+Comparisons
+***********
+
+.. function:: 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.
+
+.. type:: enum gcc_jit_comparison
+
+=======================================  ============
+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`
+=======================================  ============
+
+
+Function calls
+**************
+.. function:: 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::
+
+      :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`:
+
+      .. code-block:: c
+
+         /* Add "(void)printf (arg0, arg1);".  */
+         gcc_jit_block_add_eval (
+           block, NULL,
+           gcc_jit_context_new_call (
+             ctxt,
+             NULL,
+             printf_func,
+             2, args));
+
+.. function:: 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
+   :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.
+
+.. function:: void\
+              gcc_jit_rvalue_set_bool_require_tail_call (gcc_jit_rvalue *call,\
+                                                         int require_tail_call)
+
+   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 :ref:`LIBGCCJIT_ABI_6`; you can test for
+   its presence using
+
+   .. code-block:: c
+
+      #ifdef LIBGCCJIT_HAVE_gcc_jit_rvalue_set_bool_require_tail_call
+
+Function pointers
+*****************
+
+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`.
+
+Type-coercion
+*************
+
+.. function:: 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
+-------
+
+.. type:: 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.
+
+.. function:: gcc_jit_object *\
+              gcc_jit_lvalue_as_object (gcc_jit_lvalue *lvalue)
+
+   Upcast an lvalue to be an object.
+
+.. function:: gcc_jit_rvalue *\
+              gcc_jit_lvalue_as_rvalue (gcc_jit_lvalue *lvalue)
+
+   Upcast an lvalue to be an rvalue.
+
+.. function:: gcc_jit_rvalue *\
+              gcc_jit_lvalue_get_address (gcc_jit_lvalue *lvalue,\
+                                          gcc_jit_location *loc)
+
+   Take the address of an lvalue; analogous to:
+
+   .. code-block:: c
+
+     &(EXPR)
+
+   in C.
+
+Global variables
+****************
+
+.. function:: 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 ``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`:
+
+   .. type:: enum gcc_jit_global_kind
+
+   .. c:macro:: GCC_JIT_GLOBAL_EXPORTED
+
+      Global is defined by the client code and is visible
+      by name outside of this JIT context via
+      :c:func:`gcc_jit_result_get_global` (and this value is required for
+      the global to be accessible via that entrypoint).
+
+   .. c:macro:: 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.
+
+   .. c:macro:: 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.
+
+Working with pointers, structs and unions
+-----------------------------------------
+
+.. function:: 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 type ``T``.  Analogous to:
+
+   .. code-block:: c
+
+     *(EXPR)
+
+   in C.
+
+Field access is provided separately for both lvalues and rvalues.
+
+.. function:: 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:
+
+   .. code-block:: c
+
+      (EXPR).field = ...;
+
+   in C.
+
+.. function:: 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:
+
+   .. code-block:: c
+
+      (EXPR).field
+
+   in C.
+
+.. function:: 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:
+
+   .. code-block:: c
+
+      (EXPR)->field
+
+   in C, itself equivalent to ``(*EXPR).FIELD``.
+
+.. function:: 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 of ``index`` corresponds to ``sizeof(T)`` bytes.
+   Analogous to:
+
+   .. code-block:: c
+
+      PTR[INDEX]
+
+   in C (or, indeed, to ``PTR + INDEX``).