void
create_code (gcc_jit_context *ctxt, void *user_data)
{
    gcc_jit_type *t_int =
        gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
    gcc_jit_type *return_type = t_int;
    gcc_jit_param *x =
        gcc_jit_context_new_param (ctxt, NULL, t_int, "x");
    gcc_jit_param *params[1] = {x};
    gcc_jit_function *func =
        gcc_jit_context_new_function (ctxt, NULL,
                                      GCC_JIT_FUNCTION_EXPORTED,
                                      return_type,
                                      "test_switch",
                                      1, params, 0);

    gcc_jit_block *b_initial =
        gcc_jit_function_new_block (func, "initial");

    gcc_jit_block *b_default =
        gcc_jit_function_new_block (func, "default");

    /* Erroneous NULL case.  */
    gcc_jit_case *cases[1] = {
        NULL
    };

    gcc_jit_block_end_with_switch (
        b_initial, NULL,
        gcc_jit_param_as_rvalue (x),
        b_default,
        1,
        cases);
}
示例#2
0
void
create_code (gcc_jit_context *ctxt)
{
  /* Let's try to inject the equivalent of:

      int square (int i)
      {
        return i * i;
      }
  */
  gcc_jit_type *int_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
  gcc_jit_param *param_i =
    gcc_jit_context_new_param (ctxt, NULL, int_type, "i");
  gcc_jit_function *func =
    gcc_jit_context_new_function (ctxt, NULL,
                                  GCC_JIT_FUNCTION_EXPORTED,
                                  int_type,
                                  "square",
                                  1, &param_i,
                                  0);

  gcc_jit_block *block = gcc_jit_function_new_block (func, NULL);

  gcc_jit_rvalue *expr =
    gcc_jit_context_new_binary_op (
      ctxt, NULL,
      GCC_JIT_BINARY_OP_MULT, int_type,
      gcc_jit_param_as_rvalue (param_i),
      gcc_jit_param_as_rvalue (param_i));

   gcc_jit_block_end_with_return (block, NULL, expr);
}
void
create_code (gcc_jit_context *ctxt, void *user_data)
{
    /* Let's try to inject the equivalent of:

         struct foo;

         extern void called_function (struct foo *ptr);

         void
         test_fn ()
         {
           struct foo f;
     called_function (f);
       }

       and verify that we get a type error (foo * vs foo).
    */
    gcc_jit_type *void_type =
        gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
    gcc_jit_struct *struct_foo =
        gcc_jit_context_new_struct_type (ctxt, NULL, "foo", 0, NULL);
    gcc_jit_type *foo_ptr =
        gcc_jit_type_get_pointer (gcc_jit_struct_as_type (struct_foo));
    gcc_jit_param *param =
        gcc_jit_context_new_param (ctxt, NULL, foo_ptr, "ptr");

    gcc_jit_function *called_function =
        gcc_jit_context_new_function (ctxt, NULL,
                                      GCC_JIT_FUNCTION_IMPORTED,
                                      void_type,
                                      "called_function",
                                      1, &param,
                                      0);

    gcc_jit_function *test_fn =
        gcc_jit_context_new_function (ctxt, NULL,
                                      GCC_JIT_FUNCTION_EXPORTED,
                                      void_type,
                                      "test_fn",
                                      0, NULL,
                                      0);
    gcc_jit_lvalue *f =
        gcc_jit_function_new_local (
            test_fn, NULL, gcc_jit_struct_as_type (struct_foo), "f");

    gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL);

    gcc_jit_rvalue *arg = gcc_jit_lvalue_as_rvalue (f);

    gcc_jit_block_add_eval (
        block, NULL,
        gcc_jit_context_new_call (
            ctxt, NULL,
            called_function,
            1, &arg));
    gcc_jit_block_end_with_void_return (block, NULL);
}
示例#4
0
static void generate_return_zero(gcc_jit_context* ctx, gcc_jit_function *fun, gcc_jit_block** return_zero)
{
  if (*return_zero == NULL)
  {
    gcc_jit_type *int_type = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_INT);
    *return_zero = gcc_jit_function_new_block(fun, new_block_name());
    gcc_jit_block_end_with_return(
        *return_zero, /* loc */ NULL,
        gcc_jit_context_zero(ctx, int_type));
  }
}
void
create_code (gcc_jit_context *ctxt, void *user_data)
{
  /* Let's try to inject the equivalent of:
     void
     hello_world (const char *name)
     {
       // a test comment
       printf ("hello from %s\n", name);
     }
  */
  gcc_jit_type *void_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
  gcc_jit_type *const_char_ptr_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CONST_CHAR_PTR);
  gcc_jit_param *param_name =
    gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "name");
  gcc_jit_function *func =
    gcc_jit_context_new_function (ctxt, NULL,
				  GCC_JIT_FUNCTION_EXPORTED,
				  void_type,
				  "hello_world",
				  1, &param_name,
				  0);

  gcc_jit_param *param_format =
    gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "format");
  gcc_jit_function *printf_func =
    gcc_jit_context_new_function (ctxt, NULL,
				  GCC_JIT_FUNCTION_IMPORTED,
				  gcc_jit_context_get_type (
				     ctxt, GCC_JIT_TYPE_INT),
				  "printf",
				  1, &param_format,
				  1);
  gcc_jit_rvalue *args[2];
  args[0] = gcc_jit_context_new_string_literal (ctxt, "hello from %s\n");
  args[1] = gcc_jit_param_as_rvalue (param_name);

  gcc_jit_block *block = gcc_jit_function_new_block (func, NULL);

  gcc_jit_block_add_comment (
    block, NULL,
    "a test comment");

  gcc_jit_block_add_eval (
    block, NULL,
    gcc_jit_context_new_call (ctxt,
			      NULL,
			      printf_func,
			      2, args));
  gcc_jit_block_end_with_void_return (block, NULL);
}
示例#6
0
void
create_code (gcc_jit_context *ctxt, void *user_data)
{
  /* Where "ETC" is a very long suffix, let's try to inject the
     equivalent of:

       struct struct_ETC;

       int
       test_fn_ETC ()
       {
	  int local_ETC;
	  local_ETC = 42;
	  return local_ETC;
       }

     to verify that the API copes with such long names.  */

  populate_names ();

  gcc_jit_type *int_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);

  /* We don't yet use this struct.  */
  (void)gcc_jit_context_new_opaque_struct (ctxt, NULL,
					   long_names.struct_name);

  gcc_jit_function *test_fn =
    gcc_jit_context_new_function (ctxt, NULL,
				  GCC_JIT_FUNCTION_EXPORTED,
				  int_type,
				  long_names.fn_name,
				  0, NULL,
				  0);
  gcc_jit_lvalue *local =
    gcc_jit_function_new_local (test_fn,
				NULL,
				int_type,
				long_names.local_name);

  gcc_jit_block *block =
    gcc_jit_function_new_block (test_fn, long_names.block_name);

  gcc_jit_block_add_assignment (
    block,
    NULL,
    local,
    gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 42));

  gcc_jit_block_end_with_return (
    block, NULL,
    gcc_jit_lvalue_as_rvalue (local));
}
void
create_code (gcc_jit_context *ctxt, void *user_data)
{
    /* Let's try to inject the equivalent of:

       void
       fn_one (int i)
       {
       }

       int
       fn_two ()
       {
         return i * 2;
       }

       and verify that the API complains about the use of the param
       from the other function.  */
    gcc_jit_type *void_type =
        gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
    gcc_jit_type *int_type =
        gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);

    gcc_jit_param *param =
        gcc_jit_context_new_param (ctxt, NULL, int_type, "i");

    gcc_jit_context_new_function (ctxt, NULL,
                                  GCC_JIT_FUNCTION_EXPORTED,
                                  void_type,
                                  "fn_one",
                                  1, &param,
                                  0);
    gcc_jit_function *fn_two =
        gcc_jit_context_new_function (ctxt, NULL,
                                      GCC_JIT_FUNCTION_EXPORTED,
                                      int_type,
                                      "fn_two",
                                      0, NULL,
                                      0);

    gcc_jit_block *block = gcc_jit_function_new_block (fn_two, NULL);
    /* "return i * 2;", using param i from the wrong function.  */
    gcc_jit_block_end_with_return (
        block,
        NULL,
        gcc_jit_context_new_binary_op (
            ctxt, NULL,
            GCC_JIT_BINARY_OP_MULT,
            int_type,
            gcc_jit_param_as_rvalue (param),
            gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 2)));
}
void
create_code (gcc_jit_context *ctxt, void *user_data)
{
  /* Let's try to inject the equivalent of:

     void
     test_fn (void (*some_fn_ptr) (void *))
     {
        some_fn_ptr (42);
     }

     and verify that the API complains about the mismatching argument
     type ("int" vs "void *").  */
  gcc_jit_type *void_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
  gcc_jit_type *void_ptr_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID_PTR);
  gcc_jit_type *int_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);

  /* Build the function ptr type.  */
  gcc_jit_type *fn_ptr_type =
    gcc_jit_context_new_function_ptr_type (ctxt, NULL,
					   void_type,
					   1, &void_ptr_type, 0);

  /* Build the test_fn.  */
  gcc_jit_param *param_fn_ptr =
    gcc_jit_context_new_param (ctxt, NULL, fn_ptr_type, "some_fn_ptr");

  gcc_jit_function *test_fn =
    gcc_jit_context_new_function (ctxt, NULL,
                                  GCC_JIT_FUNCTION_EXPORTED,
                                  void_type,
                                  "test_fn",
                                  1, &param_fn_ptr,
                                  0);
  /* some_fn_ptr (42); */
  gcc_jit_rvalue *arg =
    gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 42);

  gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL);
  gcc_jit_block_add_eval (
    block, NULL,
    gcc_jit_context_new_call_through_ptr (
      ctxt,
      NULL,
      gcc_jit_param_as_rvalue (param_fn_ptr),
      1, &arg));
  /* the above has the wrong type for argument 1.  */
  gcc_jit_block_end_with_void_return (block, NULL);
}
示例#9
0
static void
create_test_of_builtin_strcmp (gcc_jit_context *ctxt)
{
  /* Let's try to inject the equivalent of:
       int
       test_of_builtin_strcmp (const char *a, const char *b)
       {
         return __builtin_strcmp (a, b);
       }
  */
  gcc_jit_type *int_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
  gcc_jit_type *const_char_ptr_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CONST_CHAR_PTR);

  /* Get the built-in function.  */
  gcc_jit_function *builtin_fn =
    gcc_jit_context_get_builtin_function (ctxt, "strcmp");

  CHECK_STRING_VALUE (
    gcc_jit_object_get_debug_string (gcc_jit_function_as_object (builtin_fn)),
    "strcmp");

  /* Build the test_fn.  */
  gcc_jit_param *param_a =
    gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "a");
  gcc_jit_param *param_b =
    gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "b");
  gcc_jit_param *params[2] = {param_a, param_b};
  gcc_jit_function *test_fn =
    gcc_jit_context_new_function (ctxt, NULL,
                                  GCC_JIT_FUNCTION_EXPORTED,
                                  int_type,
                                  "test_of_builtin_strcmp",
                                  2, params,
                                  0);
  gcc_jit_rvalue *args[2] = {gcc_jit_param_as_rvalue (param_a),
			     gcc_jit_param_as_rvalue (param_b)};
  gcc_jit_rvalue *call =
    gcc_jit_context_new_call (ctxt,
                              NULL,
                              builtin_fn,
                              2, args);
  CHECK_STRING_VALUE (
    gcc_jit_object_get_debug_string (gcc_jit_rvalue_as_object (call)),
    "strcmp (a, b)");

  gcc_jit_block *initial =
    gcc_jit_function_new_block (test_fn, "initial");
  gcc_jit_block_end_with_return (initial, NULL, call);
}
void
create_code (gcc_jit_context *ctxt, void *user_data)
{
  /* Let's try to inject the equivalent of:
     extern void called_function (int p);

     void
     test_caller ()
     {
        called_function (); // missing arg
     }

     and verify that the API complains about the missing argument.
  */
  gcc_jit_type *void_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
  gcc_jit_type *int_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);

  /* Declare the imported function.  */
  gcc_jit_param *param_p =
    gcc_jit_context_new_param (ctxt, NULL, int_type, "p");
  gcc_jit_function *called_fn =
    gcc_jit_context_new_function (ctxt, NULL,
                                  GCC_JIT_FUNCTION_IMPORTED,
                                  void_type,
                                  "called_function",
                                  1, &param_p,
                                  0);

  /* Build the test_fn.  */
  gcc_jit_function *test_fn =
    gcc_jit_context_new_function (ctxt, NULL,
                                  GCC_JIT_FUNCTION_EXPORTED,
                                  void_type,
                                  "test_caller",
                                  0, NULL,
                                  0);
  gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL);
  /* called_function ();  */
  gcc_jit_block_add_eval (
    block, NULL,
    gcc_jit_context_new_call (ctxt,
                              NULL,
                              called_fn,
                              0, NULL));
  /* the above has the wrong arg count.  */
  gcc_jit_block_end_with_void_return (block, NULL);
}
void
create_code (gcc_jit_context *ctxt, void *user_data)
{
  /* Let's try to inject the equivalent of:

     void
     test_fn ()
     {
        ((some_unspecified_fn_ptr_type)42) (43);
     }

     and verify that the API complains about the 42 not being a
     function pointer.  */
  gcc_jit_type *void_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
  gcc_jit_type *int_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);

  /* Build the test_fn.  */
  gcc_jit_function *test_fn =
    gcc_jit_context_new_function (ctxt, NULL,
                                  GCC_JIT_FUNCTION_EXPORTED,
                                  void_type,
                                  "test_fn",
                                  0, NULL,
                                  0);
  gcc_jit_rvalue *not_a_function =
    gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 42);
  gcc_jit_rvalue *arg =
    gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 43);

  /* ((some_unspecified_fn_ptr_type)42) (43); */
  gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL);
  gcc_jit_block_add_eval (
    block, NULL,
    gcc_jit_context_new_call_through_ptr (
      ctxt,
      NULL,
      /* This is not even a pointer, let alone a function pointer.  */
      not_a_function,
      1, &arg));
  gcc_jit_block_end_with_void_return (block, NULL);
}
示例#12
0
static void
create_use_of_void_return (gcc_jit_context *ctxt)
{
  /* Let's try to inject the equivalent of:
       void
       test_of_void_return (int *out)
       {
         *out = 1;
	 return;
       }
  */
  gcc_jit_type *void_t =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
  gcc_jit_type *int_t =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
  gcc_jit_type *int_ptr_t =
    gcc_jit_type_get_pointer (int_t);

  /* Build the test_fn.  */
  gcc_jit_param *param_out =
    gcc_jit_context_new_param (ctxt, NULL, int_ptr_t, "out");
  gcc_jit_function *test_fn =
    gcc_jit_context_new_function (ctxt, NULL,
                                  GCC_JIT_FUNCTION_EXPORTED,
                                  void_t,
                                  "test_of_void_return",
                                  1, &param_out,
                                  0);
  gcc_jit_block *initial =
    gcc_jit_function_new_block (test_fn, "initial");

  gcc_jit_block_add_assignment (
    initial, NULL,
    /* "*out = ..." */
    gcc_jit_rvalue_dereference (gcc_jit_param_as_rvalue (param_out),
				NULL),
    gcc_jit_context_one (ctxt, int_t));
  gcc_jit_block_end_with_void_return (initial, NULL);
}
void
create_code (gcc_jit_context *ctxt, void *user_data)
{
  /* Let's try to inject the equivalent of:
       void
       int test_bogus_dereference_read (int i)
       {
	 return *i;
       }
     i.e. where i is *not* a pointer.
  */
  gcc_jit_type *void_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
  gcc_jit_type *int_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);

  /* Build the test function.  */
  gcc_jit_param *param_i =
      gcc_jit_context_new_param (ctxt, NULL, int_type, "i");
  gcc_jit_function *test_fn =
    gcc_jit_context_new_function (ctxt, NULL,
                                  GCC_JIT_FUNCTION_EXPORTED,
                                  void_type,
                                  "test_bogus_dereference_read",
                                  1, &param_i,
                                  0);
  gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL);
  /* Erroneous: "return *i;" */
  gcc_jit_block_end_with_return (
    block,
    NULL,
    gcc_jit_lvalue_as_rvalue (
      gcc_jit_rvalue_dereference (
        gcc_jit_param_as_rvalue (param_i),
	NULL)));
}
示例#14
0
void
create_code (gcc_jit_context *ctxt, void *user_data)
{
  /* Let's try to inject the equivalent of:
     float
     test_union (int i)
     {
        union int_or_float u;
	u.as_int = i;
	return u.as_float;
     }
  */
  gcc_jit_type *int_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
  gcc_jit_type *float_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT);
  gcc_jit_field *as_int =
    gcc_jit_context_new_field (ctxt,
                               NULL,
                               int_type,
                               "as_int");
  gcc_jit_field *as_float =
    gcc_jit_context_new_field (ctxt,
                               NULL,
                               float_type,
                               "as_float");
  gcc_jit_field *fields[] = {as_int, as_float};
  gcc_jit_type *union_type =
    gcc_jit_context_new_union_type (ctxt, NULL,
				    "int_or_float", 2, fields);

  /* Build the test function.  */
  gcc_jit_param *param_i =
    gcc_jit_context_new_param (ctxt, NULL, int_type, "i");
  gcc_jit_function *test_fn =
    gcc_jit_context_new_function (ctxt, NULL,
                                  GCC_JIT_FUNCTION_EXPORTED,
                                  float_type,
                                  "test_union",
                                  1, &param_i,
                                  0);

  gcc_jit_lvalue *u =
    gcc_jit_function_new_local (test_fn, NULL,
				union_type, "u");

  gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL);

  /* u.as_int = i; */
  gcc_jit_block_add_assignment (
    block,
    NULL,
    /* "u.as_int = ..." */
    gcc_jit_lvalue_access_field (u,
				 NULL,
				 as_int),
    gcc_jit_param_as_rvalue (param_i));

  /* return u.as_float; */
  gcc_jit_block_end_with_return (
    block, NULL,
    gcc_jit_rvalue_access_field (gcc_jit_lvalue_as_rvalue (u),
				 NULL,
				 as_float));
}
示例#15
0
void
create_code (gcc_jit_context *ctxt)
{
  /*
    Simple sum-of-squares, to test conditionals and looping

    int loop_test (int n)
    {
      int i;
      int sum = 0;
      for (i = 0; i < n ; i ++)
      {
	sum += i * i;
      }
      return sum;
   */
  gcc_jit_type *the_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
  gcc_jit_type *return_type = the_type;

  gcc_jit_param *n =
    gcc_jit_context_new_param (ctxt, NULL, the_type, "n");
  gcc_jit_param *params[1] = {n};
  gcc_jit_function *func =
    gcc_jit_context_new_function (ctxt, NULL,
				  GCC_JIT_FUNCTION_EXPORTED,
				  return_type,
				  "loop_test",
				  1, params, 0);

  /* Build locals:  */
  gcc_jit_lvalue *i =
    gcc_jit_function_new_local (func, NULL, the_type, "i");
  gcc_jit_lvalue *sum =
    gcc_jit_function_new_local (func, NULL, the_type, "sum");

  gcc_jit_block *b_initial =
    gcc_jit_function_new_block (func, "initial");
  gcc_jit_block *b_loop_cond =
    gcc_jit_function_new_block (func, "loop_cond");
  gcc_jit_block *b_loop_body =
    gcc_jit_function_new_block (func, "loop_body");
  gcc_jit_block *b_after_loop =
    gcc_jit_function_new_block (func, "after_loop");

  /* sum = 0; */
  gcc_jit_block_add_assignment (
    b_initial, NULL,
    sum,
    gcc_jit_context_zero (ctxt, the_type));

  /* i = 0; */
  gcc_jit_block_add_assignment (
    b_initial, NULL,
    i,
    gcc_jit_context_zero (ctxt, the_type));

  gcc_jit_block_end_with_jump (b_initial, NULL, b_loop_cond);

  /* if (i >= n) */
  gcc_jit_block_end_with_conditional (
    b_loop_cond, NULL,
    gcc_jit_context_new_comparison (
       ctxt, NULL,
       GCC_JIT_COMPARISON_GE,
       gcc_jit_lvalue_as_rvalue (i),
       gcc_jit_param_as_rvalue (n)),
    b_after_loop,
    b_loop_body);

  /* sum += i * i */
  gcc_jit_block_add_assignment_op (
    b_loop_body, NULL,
    sum,
    GCC_JIT_BINARY_OP_PLUS,
    gcc_jit_context_new_binary_op (
      ctxt, NULL,
      GCC_JIT_BINARY_OP_MULT, the_type,
      gcc_jit_lvalue_as_rvalue (i),
      gcc_jit_lvalue_as_rvalue (i)));

  /* i++ */
  gcc_jit_block_add_assignment_op (
    b_loop_body, NULL,
    i,
    GCC_JIT_BINARY_OP_PLUS,
    gcc_jit_context_one (ctxt, the_type));

  gcc_jit_block_end_with_jump (b_loop_body, NULL, b_loop_cond);

  /* return sum */
  gcc_jit_block_end_with_return (
    b_after_loop,
    NULL,
    gcc_jit_lvalue_as_rvalue (sum));
}
示例#16
0
static void
make_calc_discriminant (struct top_level *top_level,
			struct middle_level *middle_level)
{
  /* Build "calc_discriminant".  */
  gcc_jit_param *param_q =
    gcc_jit_context_new_param (middle_level->ctxt, NULL,
			       top_level->quadratic_ptr, "q");
  middle_level->calc_discriminant =
    gcc_jit_context_new_function (middle_level->ctxt, NULL,
				  GCC_JIT_FUNCTION_EXPORTED,
				  top_level->void_type,
				  "calc_discriminant",
				  1, &param_q,
				  0);
  gcc_jit_block *blk =
    gcc_jit_function_new_block (middle_level->calc_discriminant, NULL);
  gcc_jit_block_add_comment (
    blk, NULL,
    "(b^2 - 4ac)");

  gcc_jit_rvalue *q_a =
    gcc_jit_lvalue_as_rvalue (
	gcc_jit_rvalue_dereference_field (
	  gcc_jit_param_as_rvalue (param_q),
	  NULL, top_level->a));
  gcc_jit_rvalue *q_b =
    gcc_jit_lvalue_as_rvalue (
	gcc_jit_rvalue_dereference_field (
	  gcc_jit_param_as_rvalue (param_q),
	  NULL, top_level->b));
  gcc_jit_rvalue *q_c =
    gcc_jit_lvalue_as_rvalue (
	gcc_jit_rvalue_dereference_field (
	  gcc_jit_param_as_rvalue (param_q),
	  NULL, top_level->c));

  gcc_jit_block_add_assignment (
    blk, NULL,

    /* q->discriminant =...  */
    gcc_jit_rvalue_dereference_field (
      gcc_jit_param_as_rvalue (param_q),
      NULL,
      top_level->discriminant),

    /* (q->b * q->b) - (4 * q->a * q->c) */
    gcc_jit_context_new_binary_op (
      middle_level->ctxt, NULL,
      GCC_JIT_BINARY_OP_MINUS,
      top_level->numeric_type,

      /* (q->b * q->b) */
      gcc_jit_context_new_binary_op (
	middle_level->ctxt, NULL,
	GCC_JIT_BINARY_OP_MULT,
	top_level->numeric_type,
	q_b, q_b),

      /* (4 * (q->a * q->c)) */
      gcc_jit_context_new_binary_op (
	middle_level->ctxt, NULL,
	GCC_JIT_BINARY_OP_MULT,
	top_level->numeric_type,
	/* 4.0 */
	gcc_jit_context_new_rvalue_from_int (
	  middle_level->ctxt,
	  top_level->numeric_type,
	  4),
	/* (q->a * q->c) */
	gcc_jit_context_new_binary_op (
	  middle_level->ctxt, NULL,
	  GCC_JIT_BINARY_OP_MULT,
	  top_level->numeric_type,
	  q_a, q_c)))); /* end of gcc_jit_function_add_assignment call.  */

  gcc_jit_block_end_with_void_return (blk, NULL);
}
示例#17
0
static void
make_test_quadratic (struct top_level *top_level,
		     struct middle_level *middle_level,
		     struct bottom_level *bottom_level)
{
  gcc_jit_param *a =
    gcc_jit_context_new_param (bottom_level->ctxt, NULL,
			       top_level->numeric_type, "a");
  gcc_jit_param *b =
    gcc_jit_context_new_param (bottom_level->ctxt, NULL,
			       top_level->numeric_type, "b");
  gcc_jit_param *c =
    gcc_jit_context_new_param (bottom_level->ctxt, NULL,
			       top_level->numeric_type, "c");
  gcc_jit_param *r1 =
    gcc_jit_context_new_param (bottom_level->ctxt, NULL,
			       top_level->numeric_type_ptr, "r1");
  gcc_jit_param *r2 =
    gcc_jit_context_new_param (bottom_level->ctxt, NULL,
			       top_level->numeric_type_ptr, "r2");
  gcc_jit_param *params[] = {a, b, c, r1, r2};
  gcc_jit_function *test_quadratic =
    gcc_jit_context_new_function (bottom_level->ctxt, NULL,
				  GCC_JIT_FUNCTION_EXPORTED,
				  top_level->int_type,
				  "test_quadratic",
				  5, params,
				  0);

  /* struct quadratic q; */
  gcc_jit_lvalue *q =
    gcc_jit_function_new_local (
      test_quadratic, NULL,
      top_level->struct_quadratic,
      "q");

  gcc_jit_block *initial =
    gcc_jit_function_new_block (test_quadratic,
				"initial");
  gcc_jit_block *on_positive_discriminant
    = gcc_jit_function_new_block (test_quadratic,
				  "positive_discriminant");

  gcc_jit_block *on_nonpositive_discriminant
    = gcc_jit_function_new_block (test_quadratic,
				  "nonpositive_discriminant");

  gcc_jit_block *on_zero_discriminant
    = gcc_jit_function_new_block (test_quadratic,
				  "zero_discriminant");

  gcc_jit_block *on_negative_discriminant
    = gcc_jit_function_new_block (test_quadratic,
				  "negative_discriminant");

  /* Initial block.  */
  /* q.a = a; */
  gcc_jit_block_add_assignment (
    initial, NULL,
    gcc_jit_lvalue_access_field (q, NULL, top_level->a),
    gcc_jit_param_as_rvalue (a));
  /* q.b = b; */
  gcc_jit_block_add_assignment (
    initial, NULL,
    gcc_jit_lvalue_access_field (q, NULL, top_level->b),
    gcc_jit_param_as_rvalue (b));
  /* q.c = c; */
  gcc_jit_block_add_assignment (
    initial, NULL,
    gcc_jit_lvalue_access_field (q, NULL, top_level->c),
    gcc_jit_param_as_rvalue (c));
  /* calc_discriminant (&q); */
  gcc_jit_rvalue *address_of_q = gcc_jit_lvalue_get_address (q, NULL);
  gcc_jit_block_add_eval (
    initial, NULL,
    gcc_jit_context_new_call (
      bottom_level->ctxt, NULL,
      middle_level->calc_discriminant,
      1, &address_of_q));

  gcc_jit_block_add_comment (
    initial, NULL,
    "if (q.discriminant > 0)");
  gcc_jit_block_end_with_conditional (
    initial, NULL,
    gcc_jit_context_new_comparison (
      bottom_level->ctxt, NULL,
      GCC_JIT_COMPARISON_GT,
      gcc_jit_rvalue_access_field (
	gcc_jit_lvalue_as_rvalue (q),
	NULL,
	top_level->discriminant),
      top_level->zero),
    on_positive_discriminant,
    on_nonpositive_discriminant);

  /* Block: "on_positive_discriminant" */
  /* double s = sqrt (q.discriminant); */
  gcc_jit_lvalue *s = gcc_jit_function_new_local (
    test_quadratic, NULL,
    top_level->numeric_type,
    "s");
  gcc_jit_rvalue *discriminant_of_q =
    gcc_jit_rvalue_access_field (gcc_jit_lvalue_as_rvalue (q),
				 NULL,
				 top_level->discriminant);
  gcc_jit_block_add_assignment (
    on_positive_discriminant, NULL,
    s,
    gcc_jit_context_new_call (
      bottom_level->ctxt, NULL,
      top_level->sqrt,
      1, &discriminant_of_q));

  gcc_jit_rvalue *minus_b =
    gcc_jit_context_new_unary_op (
      bottom_level->ctxt, NULL,
      GCC_JIT_UNARY_OP_MINUS,
      top_level->numeric_type,
      gcc_jit_param_as_rvalue (b));
  gcc_jit_rvalue *two_a =
    gcc_jit_context_new_binary_op (
      bottom_level->ctxt, NULL,
      GCC_JIT_BINARY_OP_MULT,
      top_level->numeric_type,
      gcc_jit_context_new_rvalue_from_int (
	bottom_level->ctxt,
	top_level->numeric_type,
	2),
      gcc_jit_param_as_rvalue (a));

  gcc_jit_block_add_comment (
    on_positive_discriminant, NULL,
    "*r1 = (-b + s) / (2 * a);");
  gcc_jit_block_add_assignment (
    on_positive_discriminant, NULL,

    /* "*r1 = ..." */
    gcc_jit_rvalue_dereference (
      gcc_jit_param_as_rvalue (r1), NULL),

    /* (-b + s) / (2 * a) */
    gcc_jit_context_new_binary_op (
      bottom_level->ctxt, NULL,
      GCC_JIT_BINARY_OP_DIVIDE,
      top_level->numeric_type,
      gcc_jit_context_new_binary_op (
	bottom_level->ctxt, NULL,
	GCC_JIT_BINARY_OP_PLUS,
	top_level->numeric_type,
	minus_b,
	gcc_jit_lvalue_as_rvalue (s)),
      two_a));

  gcc_jit_block_add_comment (
    on_positive_discriminant, NULL,
    "*r2 = (-b - s) / (2 * a)");
  gcc_jit_block_add_assignment (
    on_positive_discriminant, NULL,

    /* "*r2 = ..." */
    gcc_jit_rvalue_dereference (
      gcc_jit_param_as_rvalue (r2), NULL),

    /* (-b - s) / (2 * a) */
    gcc_jit_context_new_binary_op (
      bottom_level->ctxt, NULL,
      GCC_JIT_BINARY_OP_DIVIDE,
      top_level->numeric_type,
      gcc_jit_context_new_binary_op (
	bottom_level->ctxt, NULL,
	GCC_JIT_BINARY_OP_MINUS,
	top_level->numeric_type,
	minus_b,
	gcc_jit_lvalue_as_rvalue (s)),
      two_a));

  /* "return 2;" */
  gcc_jit_block_end_with_return (
    on_positive_discriminant, NULL,
    gcc_jit_context_new_rvalue_from_int (
      bottom_level->ctxt,
      top_level->int_type,
      2));

  /* Block: "on_nonpositive_discriminant" */
  gcc_jit_block_add_comment (
    on_nonpositive_discriminant, NULL,
    "else if (q.discriminant == 0)");
  gcc_jit_block_end_with_conditional (
    on_nonpositive_discriminant, NULL,
    gcc_jit_context_new_comparison (
      bottom_level->ctxt, NULL,
      GCC_JIT_COMPARISON_EQ,
      gcc_jit_rvalue_access_field (
	gcc_jit_lvalue_as_rvalue (q),
	NULL,
	top_level->discriminant),
      top_level->zero),
    on_zero_discriminant,
    on_negative_discriminant);

  /* Block: "on_zero_discriminant" */
  gcc_jit_block_add_comment (
    on_zero_discriminant, NULL,
    "*r1 = -b / (2 * a);");
  gcc_jit_block_add_assignment (
    on_zero_discriminant, NULL,

    /* "*r1 = ..." */
    gcc_jit_rvalue_dereference (
      gcc_jit_param_as_rvalue (r1), NULL),

    /* -b / (2 * a) */
    gcc_jit_context_new_binary_op (
      bottom_level->ctxt, NULL,
      GCC_JIT_BINARY_OP_DIVIDE,
      top_level->numeric_type,
      minus_b,
      two_a));

  /* "return 1;" */
  gcc_jit_block_end_with_return (
    on_zero_discriminant, NULL,
      gcc_jit_context_one (bottom_level->ctxt, top_level->int_type));

  /* Block: "on_negative_discriminant" */
  gcc_jit_block_end_with_return (
    /* else return 0; */
    on_negative_discriminant, NULL,
    gcc_jit_context_zero (bottom_level->ctxt, top_level->int_type));
}
void
create_code (gcc_jit_context *ctxt, void *user_data)
{
  /* Let's try to inject the equivalent of:
     void
     test_bogus_access (struct foo f)
     {
       f.x = f.p;
     }
     i.e. using the wrong struct for the RHS.
  */
  gcc_jit_type *void_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
  gcc_jit_type *int_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);

  /* Map "struct foo".  */
  gcc_jit_field *x =
    gcc_jit_context_new_field (ctxt,
			       NULL,
			       int_type,
			       "x");
  gcc_jit_field *y =
    gcc_jit_context_new_field (ctxt,
			       NULL,
			       int_type,
			       "y");
  gcc_jit_field *foo_fields[] = {x, y};
  gcc_jit_struct *struct_foo =
    gcc_jit_context_new_struct_type (ctxt, NULL, "foo", 2, foo_fields);

  /* Map "struct bar".  */
  gcc_jit_field *p =
    gcc_jit_context_new_field (ctxt,
			       NULL,
			       int_type,
			       "p");
  gcc_jit_field *q =
    gcc_jit_context_new_field (ctxt,
			       NULL,
			       int_type,
			       "q");
  /* We don't actually need a gcc_jit_type for "struct bar" for the test.  */
  gcc_jit_field *bar_fields[] = {p, q};
  (void)gcc_jit_context_new_struct_type (ctxt, NULL, "foo", 2, bar_fields);

  /* Build the test function.  */
  gcc_jit_param *param_f =
    gcc_jit_context_new_param (ctxt, NULL,
			       gcc_jit_struct_as_type (struct_foo), "f");
  gcc_jit_function *test_fn =
    gcc_jit_context_new_function (ctxt, NULL,
				  GCC_JIT_FUNCTION_EXPORTED,
				  void_type,
				  "test_bogus_access",
				  1, &param_f,
				  0);

  /* OK: f.x = ... */
  gcc_jit_lvalue *lvalue =
    gcc_jit_lvalue_access_field (
      gcc_jit_param_as_lvalue (param_f),
      NULL,
      x);

  /* Erroneous: ... = f.p; */
  gcc_jit_rvalue *rvalue =
      gcc_jit_rvalue_access_field (
	gcc_jit_param_as_rvalue (param_f),
	NULL,
	p);

  gcc_jit_block *block =
    gcc_jit_function_new_block (test_fn, NULL);
  gcc_jit_block_add_assignment (
    block,
    NULL,
    lvalue, rvalue);
  gcc_jit_block_end_with_void_return (block, NULL);
}
示例#19
0
文件: toyvm.c 项目: KangDroid/gcc
static toyvm_compiled_function *
toyvm_function_compile (toyvm_function *fn)
{
  compilation_state state;
  int pc;
  char *funcname;

  memset (&state, 0, sizeof (state));

  funcname = get_function_name (fn->fn_filename);

  state.ctxt = gcc_jit_context_acquire ();

  gcc_jit_context_set_bool_option (state.ctxt,
				   GCC_JIT_BOOL_OPTION_DUMP_INITIAL_GIMPLE,
				   0);
  gcc_jit_context_set_bool_option (state.ctxt,
				   GCC_JIT_BOOL_OPTION_DUMP_GENERATED_CODE,
				   0);
  gcc_jit_context_set_int_option (state.ctxt,
				  GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL,
				  3);
  gcc_jit_context_set_bool_option (state.ctxt,
				   GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES,
				   0);
  gcc_jit_context_set_bool_option (state.ctxt,
				   GCC_JIT_BOOL_OPTION_DUMP_EVERYTHING,
				   0);
  gcc_jit_context_set_bool_option (state.ctxt,
				   GCC_JIT_BOOL_OPTION_DEBUGINFO,
				   1);

  /* Create types.  */
  state.int_type =
    gcc_jit_context_get_type (state.ctxt, GCC_JIT_TYPE_INT);
  state.bool_type =
    gcc_jit_context_get_type (state.ctxt, GCC_JIT_TYPE_BOOL);
  state.stack_type =
    gcc_jit_context_new_array_type (state.ctxt, NULL,
				    state.int_type, MAX_STACK_DEPTH);

  /* The constant value 1.  */
  state.const_one = gcc_jit_context_one (state.ctxt, state.int_type);

  /* Create locations.  */
  for (pc = 0; pc < fn->fn_num_ops; pc++)
    {
      toyvm_op *op = &fn->fn_ops[pc];

      state.op_locs[pc] = gcc_jit_context_new_location (state.ctxt,
							fn->fn_filename,
							op->op_linenum,
							0); /* column */
    }

  /* Creating the function.  */
  state.param_arg =
    gcc_jit_context_new_param (state.ctxt, state.op_locs[0],
			       state.int_type, "arg");
  state.fn =
    gcc_jit_context_new_function (state.ctxt,
				  state.op_locs[0],
				  GCC_JIT_FUNCTION_EXPORTED,
				  state.int_type,
				  funcname,
				  1, &state.param_arg, 0);

  /* Create stack lvalues.  */
  state.stack =
    gcc_jit_function_new_local (state.fn, NULL,
				state.stack_type, "stack");
  state.stack_depth =
    gcc_jit_function_new_local (state.fn, NULL,
				state.int_type, "stack_depth");
  state.x =
    gcc_jit_function_new_local (state.fn, NULL,
				state.int_type, "x");
  state.y =
    gcc_jit_function_new_local (state.fn, NULL,
				state.int_type, "y");

  /* 1st pass: create blocks, one per opcode. */

  /* We need an entry block to do one-time initialization, so create that
     first.  */
  state.initial_block = gcc_jit_function_new_block (state.fn, "initial");

  /* Create a block per operation.  */
  for (pc = 0; pc < fn->fn_num_ops; pc++)
    {
      char buf[16];
      sprintf (buf, "instr%i", pc);
      state.op_blocks[pc] = gcc_jit_function_new_block (state.fn, buf);
    }

  /* Populate the initial block.  */

  /* "stack_depth = 0;".  */
  gcc_jit_block_add_assignment (
    state.initial_block,
    state.op_locs[0],
    state.stack_depth,
    gcc_jit_context_zero (state.ctxt, state.int_type));

  /* "PUSH (arg);".  */
  add_push (&state,
	    state.initial_block,
	    gcc_jit_param_as_rvalue (state.param_arg),
	    state.op_locs[0]);

  /* ...and jump to insn 0.  */
  gcc_jit_block_end_with_jump (state.initial_block,
			       state.op_locs[0],
			       state.op_blocks[0]);

  /* 2nd pass: fill in instructions.  */
  for (pc = 0; pc < fn->fn_num_ops; pc++)
    {
      gcc_jit_location *loc = state.op_locs[pc];

      gcc_jit_block *block = state.op_blocks[pc];
      gcc_jit_block *next_block = (pc < fn->fn_num_ops
				   ? state.op_blocks[pc + 1]
				   : NULL);

      toyvm_op *op;
      op = &fn->fn_ops[pc];

      /* Helper macros.  */

#define X_EQUALS_POP()\
      add_pop (&state, block, state.x, loc)
#define Y_EQUALS_POP()\
      add_pop (&state, block, state.y, loc)
#define PUSH_RVALUE(RVALUE)\
      add_push (&state, block, (RVALUE), loc)
#define PUSH_X()\
      PUSH_RVALUE (gcc_jit_lvalue_as_rvalue (state.x))
#define PUSH_Y() \
      PUSH_RVALUE (gcc_jit_lvalue_as_rvalue (state.y))

      gcc_jit_block_add_comment (block, loc, opcode_names[op->op_opcode]);

      /* Handle the individual opcodes.  */

      switch (op->op_opcode)
	{
	case DUP:
	  X_EQUALS_POP ();
	  PUSH_X ();
	  PUSH_X ();
	  break;

	case ROT:
	  Y_EQUALS_POP ();
	  X_EQUALS_POP ();
	  PUSH_Y ();
	  PUSH_X ();
	  break;

	case BINARY_ADD:
	  Y_EQUALS_POP ();
	  X_EQUALS_POP ();
	  PUSH_RVALUE (
	   gcc_jit_context_new_binary_op (
	     state.ctxt,
	     loc,
	     GCC_JIT_BINARY_OP_PLUS,
	     state.int_type,
	     gcc_jit_lvalue_as_rvalue (state.x),
	     gcc_jit_lvalue_as_rvalue (state.y)));
	  break;

	case BINARY_SUBTRACT:
	  Y_EQUALS_POP ();
	  X_EQUALS_POP ();
	  PUSH_RVALUE (
	   gcc_jit_context_new_binary_op (
	     state.ctxt,
	     loc,
	     GCC_JIT_BINARY_OP_MINUS,
	     state.int_type,
	     gcc_jit_lvalue_as_rvalue (state.x),
	     gcc_jit_lvalue_as_rvalue (state.y)));
	  break;

	case BINARY_MULT:
	  Y_EQUALS_POP ();
	  X_EQUALS_POP ();
	  PUSH_RVALUE (
	   gcc_jit_context_new_binary_op (
	     state.ctxt,
	     loc,
	     GCC_JIT_BINARY_OP_MULT,
	     state.int_type,
	     gcc_jit_lvalue_as_rvalue (state.x),
	     gcc_jit_lvalue_as_rvalue (state.y)));
	  break;

	case BINARY_COMPARE_LT:
	  Y_EQUALS_POP ();
	  X_EQUALS_POP ();
	  PUSH_RVALUE (
	     /* cast of bool to int */
	     gcc_jit_context_new_cast (
	       state.ctxt,
	       loc,
	       /* (x < y) as a bool */
	       gcc_jit_context_new_comparison (
		 state.ctxt,
		 loc,
		 GCC_JIT_COMPARISON_LT,
		 gcc_jit_lvalue_as_rvalue (state.x),
		 gcc_jit_lvalue_as_rvalue (state.y)),
	       state.int_type));
	  break;

	case RECURSE:
	  {
	    X_EQUALS_POP ();
	    gcc_jit_rvalue *arg = gcc_jit_lvalue_as_rvalue (state.x);
	    PUSH_RVALUE (
	      gcc_jit_context_new_call (
		state.ctxt,
		loc,
		state.fn,
		1, &arg));
	    break;
	  }

	case RETURN:
	  X_EQUALS_POP ();
	  gcc_jit_block_end_with_return (
	    block,
	    loc,
	    gcc_jit_lvalue_as_rvalue (state.x));
	  break;

	  /* Ops taking an operand.  */
	case PUSH_CONST:
	  PUSH_RVALUE (
	    gcc_jit_context_new_rvalue_from_int (
	      state.ctxt,
	      state.int_type,
	      op->op_operand));
	  break;

	case JUMP_ABS_IF_TRUE:
	  X_EQUALS_POP ();
	  gcc_jit_block_end_with_conditional (
	    block,
	    loc,
	    /* "(bool)x".  */
	    gcc_jit_context_new_cast (
	      state.ctxt,
	      loc,
	      gcc_jit_lvalue_as_rvalue (state.x),
	      state.bool_type),
	    state.op_blocks[op->op_operand], /* on_true */
	    next_block); /* on_false */
	  break;

	default:
	  assert(0);
	} /* end of switch on opcode */

      /* Go to the next block.  */
      if (op->op_opcode != JUMP_ABS_IF_TRUE
	  && op->op_opcode != RETURN)
	gcc_jit_block_end_with_jump (
	  block,
	  loc,
	  next_block);

    } /* end of loop on PC locations.  */

  /* We've now finished populating the context.  Compile it.  */
  gcc_jit_result *jit_result = gcc_jit_context_compile (state.ctxt);
  gcc_jit_context_release (state.ctxt);

  toyvm_compiled_function *toyvm_result =
    (toyvm_compiled_function *)calloc (1, sizeof (toyvm_compiled_function));
  if (!toyvm_result)
    {
      fprintf (stderr, "out of memory allocating toyvm_compiled_function\n");
      gcc_jit_result_release (jit_result);
      return NULL;
    }

  toyvm_result->cf_jit_result = jit_result;
  toyvm_result->cf_code =
    (toyvm_compiled_code)gcc_jit_result_get_code (jit_result,
						  funcname);

  free (funcname);

  return toyvm_result;
}
void
create_code (gcc_jit_context *ctxt, void *user_data)
{
  /* Let's try to inject the equivalent of:
     extern void called_function (int i, int j, int k);

     void
     test_caller (int a)
     {
        called_function (a * 3, a * 4, a * 5);
     }
  */
  int i;
  gcc_jit_type *void_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
  gcc_jit_type *int_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);

  /* Declare the imported function.  */
  gcc_jit_param *params[3];
  params[0] =
    gcc_jit_context_new_param (ctxt, NULL, int_type, "i");
  params[1] =
    gcc_jit_context_new_param (ctxt, NULL, int_type, "j");
  params[2] =
    gcc_jit_context_new_param (ctxt, NULL, int_type, "k");
  gcc_jit_function *called_fn =
    gcc_jit_context_new_function (ctxt, NULL,
                                  GCC_JIT_FUNCTION_IMPORTED,
                                  void_type,
                                  "called_function",
                                  3, params,
                                  0);

  /* Build the test_fn.  */
  gcc_jit_param *param_a =
    gcc_jit_context_new_param (ctxt, NULL, int_type, "a");
  gcc_jit_function *test_fn =
    gcc_jit_context_new_function (ctxt, NULL,
                                  GCC_JIT_FUNCTION_EXPORTED,
                                  void_type,
                                  "test_caller",
                                  1, &param_a,
                                  0);
  /* "a * 3, a * 4, a * 5"  */
  gcc_jit_rvalue *args[3];
  for (i = 0; i < 3; i++)
    args[i] =
      gcc_jit_context_new_binary_op (
        ctxt, NULL,
        GCC_JIT_BINARY_OP_MULT,
        int_type,
        gcc_jit_param_as_rvalue (param_a),
        gcc_jit_context_new_rvalue_from_int (
          ctxt,
          int_type,
          (i + 3) ));
  gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL);
  gcc_jit_block_add_eval (
    block, NULL,
    gcc_jit_context_new_call (ctxt,
                              NULL,
                              called_fn,
                              3, args));
  gcc_jit_block_end_with_void_return (block, NULL);
}
示例#21
0
void
create_code (gcc_jit_context *ctxt, void * user_data)
{
  gcc_jit_type *type_void = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
  gcc_jit_type *type_int = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
  gcc_jit_type *type_unsigned_char = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UNSIGNED_CHAR);
  gcc_jit_type *type_void_ptr =
    gcc_jit_type_get_pointer (type_void);
  gcc_jit_type *type_void_ptr_ptr =
    gcc_jit_type_get_pointer (type_void_ptr);
  gcc_jit_type *type_unsigned_char__ =
    gcc_jit_type_get_pointer (type_unsigned_char);
  gcc_jit_field *field_x =
    gcc_jit_context_new_field (ctxt,
                               NULL, /* gcc_jit_location *loc */
                               type_int, /* gcc_jit_type *type, */
                               "x"); /* const char *name */
  gcc_jit_field *field_y =
    gcc_jit_context_new_field (ctxt,
                               NULL, /* gcc_jit_location *loc */
                               type_int, /* gcc_jit_type *type, */
                               "y"); /* const char *name */
  gcc_jit_struct *struct_struct_ip_coord =
    gcc_jit_context_new_opaque_struct (ctxt,
                                       NULL, /* gcc_jit_location *loc */
                                       "ip_coord"); /* const char *name */
  gcc_jit_field *fields_fields_0x18dc9d0[2] = {
    field_x,
    field_y,
  };
  gcc_jit_struct_set_fields (struct_struct_ip_coord, /* gcc_jit_struct *struct_type */
                             NULL, /* gcc_jit_location *loc */
                             2, /* int num_fields */
                             fields_fields_0x18dc9d0); /* gcc_jit_field **fields */
  gcc_jit_field *field_size =
    gcc_jit_context_new_field (ctxt,
                               NULL, /* gcc_jit_location *loc */
                               gcc_jit_struct_as_type (struct_struct_ip_coord), /* gcc_jit_type *type, */
                               "size"); /* const char *name */
  gcc_jit_field *field_imrow =
    gcc_jit_context_new_field (ctxt,
                               NULL, /* gcc_jit_location *loc */
                               type_void_ptr_ptr, /* gcc_jit_type *type, */
                               "imrow"); /* const char *name */
  gcc_jit_struct *struct_struct_ip_image =
    gcc_jit_context_new_opaque_struct (ctxt,
                                       NULL, /* gcc_jit_location *loc */
                                       "ip_image"); /* const char *name */
  gcc_jit_field *fields_fields_0x18dd310[] = {
    field_size,
    field_imrow
  };
  gcc_jit_struct_set_fields (struct_struct_ip_image, /* gcc_jit_struct *struct_type */
                             NULL, /* gcc_jit_location *loc */
                             2, /* int num_fields */
                             fields_fields_0x18dd310); /* gcc_jit_field **fields */
  gcc_jit_type *type_struct_ip_image__ =
    gcc_jit_type_get_pointer (gcc_jit_struct_as_type (struct_struct_ip_image));
  gcc_jit_param *param_dest =
    gcc_jit_context_new_param (ctxt,
                               NULL, /* gcc_jit_location *loc */
                               type_struct_ip_image__, /*gcc_jit_type *type */
                               "dest"); /* const char *name */
  gcc_jit_param *param_src =
    gcc_jit_context_new_param (ctxt,
                               NULL, /* gcc_jit_location *loc */
                               type_struct_ip_image__, /*gcc_jit_type *type */
                               "src"); /* const char *name */
  gcc_jit_param *params_for_func_ip_jit_im_add_clip_UBYTE[2] = {
    param_dest,
    param_src,
  };
  gcc_jit_function *func_ip_jit_im_add_clip_UBYTE =
    gcc_jit_context_new_function (ctxt, /* gcc_jit_context *ctxt */
                                  NULL, /* gcc_jit_location *loc */
                                  GCC_JIT_FUNCTION_EXPORTED, /* enum gcc_jit_function_kind kind */
                                  type_void, /* gcc_jit_type *return_type */
                                  "ip_jit_im_add_clip_UBYTE", /* const char *name */
                                  2, /* int num_params */
                                  params_for_func_ip_jit_im_add_clip_UBYTE, /* gcc_jit_param **params */
                                  0); /* int is_variadic */
  gcc_jit_lvalue *local_rowlen =
    gcc_jit_function_new_local (func_ip_jit_im_add_clip_UBYTE, /* gcc_jit_function *func */
                                NULL, /* gcc_jit_location *loc */
                                type_int, /* gcc_jit_type *type */
                                "rowlen"); /* const char *name */
  gcc_jit_lvalue *local_numrows =
    gcc_jit_function_new_local (func_ip_jit_im_add_clip_UBYTE, /* gcc_jit_function *func */
                                NULL, /* gcc_jit_location *loc */
                                type_int, /* gcc_jit_type *type */
                                "numrows"); /* const char *name */
  gcc_jit_lvalue *local_j =
    gcc_jit_function_new_local (func_ip_jit_im_add_clip_UBYTE, /* gcc_jit_function *func */
                                NULL, /* gcc_jit_location *loc */
                                type_int, /* gcc_jit_type *type */
                                "j"); /* const char *name */
  gcc_jit_lvalue *local_dptr =
    gcc_jit_function_new_local (func_ip_jit_im_add_clip_UBYTE, /* gcc_jit_function *func */
                                NULL, /* gcc_jit_location *loc */
                                type_unsigned_char__, /* gcc_jit_type *type */
                                "dptr"); /* const char *name */
  gcc_jit_lvalue *local_sptr =
    gcc_jit_function_new_local (func_ip_jit_im_add_clip_UBYTE, /* gcc_jit_function *func */
                                NULL, /* gcc_jit_location *loc */
                                type_unsigned_char__, /* gcc_jit_type *type */
                                "sptr"); /* const char *name */
  gcc_jit_lvalue *local_i =
    gcc_jit_function_new_local (func_ip_jit_im_add_clip_UBYTE, /* gcc_jit_function *func */
                                NULL, /* gcc_jit_location *loc */
                                type_int, /* gcc_jit_type *type */
                                "i"); /* const char *name */
  gcc_jit_block *block_F1 =
    gcc_jit_function_new_block (func_ip_jit_im_add_clip_UBYTE, "F1");
  gcc_jit_block *block_C1 =
    gcc_jit_function_new_block (func_ip_jit_im_add_clip_UBYTE, "C1");
  gcc_jit_block *block_L1 =
    gcc_jit_function_new_block (func_ip_jit_im_add_clip_UBYTE, "L1");
  gcc_jit_block *block_C2 =
    gcc_jit_function_new_block (func_ip_jit_im_add_clip_UBYTE, "C2");
  gcc_jit_block *block_L2 =
    gcc_jit_function_new_block (func_ip_jit_im_add_clip_UBYTE, "L2");
  gcc_jit_block *block_A2 =
    gcc_jit_function_new_block (func_ip_jit_im_add_clip_UBYTE, "A2");
  gcc_jit_block *block_A1 =
    gcc_jit_function_new_block (func_ip_jit_im_add_clip_UBYTE, "A1");
  gcc_jit_lvalue *lvalue_dest__size=
    gcc_jit_rvalue_dereference_field (gcc_jit_param_as_rvalue (param_dest), /* gcc_jit_rvalue *ptr */
                                      NULL, /* gcc_jit_location *loc */
                                      field_size); /* gcc_jit_field *field */
  gcc_jit_rvalue *rvalue_dest__size_x = 
    gcc_jit_rvalue_access_field (gcc_jit_lvalue_as_rvalue (lvalue_dest__size), /*gcc_jit_rvalue *struct_or_union */
                                 NULL, /*gcc_jit_location *loc */
                                 field_x);
  gcc_jit_block_add_assignment (block_F1, /*gcc_jit_block *block */
                                NULL, /* gcc_jit_location *loc */
                                local_rowlen, /* gcc_jit_lvalue *lvalue */
                                rvalue_dest__size_x); /* gcc_jit_rvalue *rvalue */
  gcc_jit_rvalue *rvalue_dest__size_y = 
    gcc_jit_rvalue_access_field (gcc_jit_lvalue_as_rvalue (lvalue_dest__size), /*gcc_jit_rvalue *struct_or_union */
                                 NULL, /*gcc_jit_location *loc */
                                 field_y);
  gcc_jit_block_add_assignment (block_F1, /*gcc_jit_block *block */
                                NULL, /* gcc_jit_location *loc */
                                local_numrows, /* gcc_jit_lvalue *lvalue */
                                rvalue_dest__size_y); /* gcc_jit_rvalue *rvalue */
  gcc_jit_rvalue *rvalue__int_0 =
    gcc_jit_context_new_rvalue_from_int (ctxt, /* gcc_jit_context *ctxt */
                                         type_int, /* gcc_jit_type *numeric_type */
                                         0); /* int value */
  gcc_jit_block_add_assignment (block_F1, /*gcc_jit_block *block */
                                NULL, /* gcc_jit_location *loc */
                                local_j, /* gcc_jit_lvalue *lvalue */
                                rvalue__int_0); /* gcc_jit_rvalue *rvalue */
  gcc_jit_block_end_with_jump (block_F1, /*gcc_jit_block *block */
                               NULL, /* gcc_jit_location *loc */
                               block_C1); /* gcc_jit_block *target */
  gcc_jit_rvalue *rvalue_j___numrows =
    gcc_jit_context_new_comparison (ctxt,
                                    NULL, /* gcc_jit_location *loc */
                                    GCC_JIT_COMPARISON_LT, /* enum gcc_jit_comparison op */
                                    gcc_jit_lvalue_as_rvalue (local_j), /* gcc_jit_rvalue *a */
                                    gcc_jit_lvalue_as_rvalue (local_numrows)); /* gcc_jit_rvalue *b */
  gcc_jit_block_end_with_conditional (block_C1, /*gcc_jit_block *block */
                                      NULL, /* gcc_jit_location *loc */
                                      rvalue_j___numrows, /* gcc_jit_rvalue *boolval */
                                      block_L1, /* gcc_jit_block *on_true */
                                      block_A1); /* gcc_jit_block *on_false */
  gcc_jit_lvalue *lvalue_dest__imrow=
    gcc_jit_rvalue_dereference_field (gcc_jit_param_as_rvalue (param_dest), /* gcc_jit_rvalue *ptr */
                                      NULL, /* gcc_jit_location *loc */
                                      field_imrow); /* gcc_jit_field *field */
  gcc_jit_lvalue *lvalue_dest__imrow_j_ = 
    gcc_jit_context_new_array_access (ctxt, /* gcc_jit_context *ctxt */
                                      NULL, /*gcc_jit_location *loc */
                                      gcc_jit_lvalue_as_rvalue (lvalue_dest__imrow), /* gcc_jit_rvalue *ptr */
                                      gcc_jit_lvalue_as_rvalue (local_j)); /* gcc_jit_rvalue *index */
  gcc_jit_rvalue *rvalue__unsigned_char___dest__imrow_j_ =
    gcc_jit_context_new_cast (ctxt,
                              NULL, /* gcc_jit_location *loc */
                              gcc_jit_lvalue_as_rvalue (lvalue_dest__imrow_j_), /* gcc_jit_rvalue *rvalue */
                              type_unsigned_char__); /* gcc_jit_type *type */
  gcc_jit_block_add_assignment (block_L1, /*gcc_jit_block *block */
                                NULL, /* gcc_jit_location *loc */
                                local_dptr, /* gcc_jit_lvalue *lvalue */
                                rvalue__unsigned_char___dest__imrow_j_); /* gcc_jit_rvalue *rvalue */
  gcc_jit_lvalue *lvalue_src__imrow=
    gcc_jit_rvalue_dereference_field (gcc_jit_param_as_rvalue (param_src), /* gcc_jit_rvalue *ptr */
                                      NULL, /* gcc_jit_location *loc */
                                      field_imrow); /* gcc_jit_field *field */
  gcc_jit_lvalue *lvalue_src__imrow_j_ = 
    gcc_jit_context_new_array_access (ctxt, /* gcc_jit_context *ctxt */
                                      NULL, /*gcc_jit_location *loc */
                                      gcc_jit_lvalue_as_rvalue (lvalue_src__imrow), /* gcc_jit_rvalue *ptr */
                                      gcc_jit_lvalue_as_rvalue (local_j)); /* gcc_jit_rvalue *index */
  gcc_jit_rvalue *rvalue__unsigned_char___src__imrow_j_ =
    gcc_jit_context_new_cast (ctxt,
                              NULL, /* gcc_jit_location *loc */
                              gcc_jit_lvalue_as_rvalue (lvalue_src__imrow_j_), /* gcc_jit_rvalue *rvalue */
                              type_unsigned_char__); /* gcc_jit_type *type */
  gcc_jit_block_add_assignment (block_L1, /*gcc_jit_block *block */
                                NULL, /* gcc_jit_location *loc */
                                local_sptr, /* gcc_jit_lvalue *lvalue */
                                rvalue__unsigned_char___src__imrow_j_); /* gcc_jit_rvalue *rvalue */
  gcc_jit_rvalue *rvalue__int_0_0x18dd890 =
    gcc_jit_context_new_rvalue_from_int (ctxt, /* gcc_jit_context *ctxt */
                                         type_int, /* gcc_jit_type *numeric_type */
                                         0); /* int value */
  gcc_jit_block_add_assignment (block_L1, /*gcc_jit_block *block */
                                NULL, /* gcc_jit_location *loc */
                                local_i, /* gcc_jit_lvalue *lvalue */
                                rvalue__int_0_0x18dd890); /* gcc_jit_rvalue *rvalue */
  gcc_jit_block_end_with_jump (block_L1, /*gcc_jit_block *block */
                               NULL, /* gcc_jit_location *loc */
                               block_C2); /* gcc_jit_block *target */
  gcc_jit_rvalue *rvalue_i___rowlen =
    gcc_jit_context_new_comparison (ctxt,
                                    NULL, /* gcc_jit_location *loc */
                                    GCC_JIT_COMPARISON_LT, /* enum gcc_jit_comparison op */
                                    gcc_jit_lvalue_as_rvalue (local_i), /* gcc_jit_rvalue *a */
                                    gcc_jit_lvalue_as_rvalue (local_rowlen)); /* gcc_jit_rvalue *b */
  gcc_jit_block_end_with_conditional (block_C2, /*gcc_jit_block *block */
                                      NULL, /* gcc_jit_location *loc */
                                      rvalue_i___rowlen, /* gcc_jit_rvalue *boolval */
                                      block_L2, /* gcc_jit_block *on_true */
                                      block_A2); /* gcc_jit_block *on_false */
  gcc_jit_lvalue *dereference__dptr =
    gcc_jit_rvalue_dereference (gcc_jit_lvalue_as_rvalue (local_dptr), /* gcc_jit_rvalue *rvalue */
                                NULL); /* gcc_jit_location *loc */
  gcc_jit_lvalue *dereference__sptr =
    gcc_jit_rvalue_dereference (gcc_jit_lvalue_as_rvalue (local_sptr), /* gcc_jit_rvalue *rvalue */
                                NULL); /* gcc_jit_location *loc */
  gcc_jit_block *block_p_C1_true =
    gcc_jit_function_new_block (func_ip_jit_im_add_clip_UBYTE, "p_C1_true");
  gcc_jit_block *block_p_C1_end =
    gcc_jit_function_new_block (func_ip_jit_im_add_clip_UBYTE, "p_C1_end");
  gcc_jit_lvalue *local_ival =
    gcc_jit_function_new_local (func_ip_jit_im_add_clip_UBYTE, /* gcc_jit_function *func */
                                NULL, /* gcc_jit_location *loc */
                                type_int, /* gcc_jit_type *type */
                                "ival"); /* const char *name */
  gcc_jit_rvalue *rvalue__int__dptr =
    gcc_jit_context_new_cast (ctxt,
                              NULL, /* gcc_jit_location *loc */
                              gcc_jit_lvalue_as_rvalue (dereference__dptr), /* gcc_jit_rvalue *rvalue */
                              type_int); /* gcc_jit_type *type */
  gcc_jit_rvalue *rvalue__int__sptr =
    gcc_jit_context_new_cast (ctxt,
                              NULL, /* gcc_jit_location *loc */
                              gcc_jit_lvalue_as_rvalue (dereference__sptr), /* gcc_jit_rvalue *rvalue */
                              type_int); /* gcc_jit_type *type */
  gcc_jit_rvalue *rvalue__int__dptr____int__sptr =
    gcc_jit_context_new_binary_op (ctxt,
                                   NULL, /* gcc_jit_location *loc */
                                   GCC_JIT_BINARY_OP_PLUS, /* enum gcc_jit_binary_op op */
                                   type_int, /* gcc_jit_type *result_type */
                                   rvalue__int__dptr, /* gcc_jit_rvalue *a */
                                   rvalue__int__sptr); /* gcc_jit_rvalue *b */
  gcc_jit_block_add_assignment (block_L2, /*gcc_jit_block *block */
                                NULL, /* gcc_jit_location *loc */
                                local_ival, /* gcc_jit_lvalue *lvalue */
                                rvalue__int__dptr____int__sptr); /* gcc_jit_rvalue *rvalue */
  gcc_jit_rvalue *rvalue__int_255 =
    gcc_jit_context_new_rvalue_from_int (ctxt, /* gcc_jit_context *ctxt */
                                         type_int, /* gcc_jit_type *numeric_type */
                                         255); /* int value */
  gcc_jit_rvalue *rvalue_ival____int_255 =
    gcc_jit_context_new_comparison (ctxt,
                                    NULL, /* gcc_jit_location *loc */
                                    GCC_JIT_COMPARISON_GT, /* enum gcc_jit_comparison op */
                                    gcc_jit_lvalue_as_rvalue (local_ival), /* gcc_jit_rvalue *a */
                                    rvalue__int_255); /* gcc_jit_rvalue *b */
  gcc_jit_block_end_with_conditional (block_L2, /*gcc_jit_block *block */
                                      NULL, /* gcc_jit_location *loc */
                                      rvalue_ival____int_255, /* gcc_jit_rvalue *boolval */
                                      block_p_C1_true, /* gcc_jit_block *on_true */
                                      block_p_C1_end); /* gcc_jit_block *on_false */
  gcc_jit_block_add_assignment (block_p_C1_true, /*gcc_jit_block *block */
                                NULL, /* gcc_jit_location *loc */
                                local_ival, /* gcc_jit_lvalue *lvalue */
                                rvalue__int_255); /* gcc_jit_rvalue *rvalue */
  gcc_jit_block_end_with_jump (block_p_C1_true, /*gcc_jit_block *block */
                               NULL, /* gcc_jit_location *loc */
                               block_p_C1_end); /* gcc_jit_block *target */
  gcc_jit_rvalue *rvalue__unsigned_char_ival =
    gcc_jit_context_new_cast (ctxt,
                              NULL, /* gcc_jit_location *loc */
                              gcc_jit_lvalue_as_rvalue (local_ival), /* gcc_jit_rvalue *rvalue */
                              type_unsigned_char); /* gcc_jit_type *type */
  gcc_jit_lvalue *dereference__dptr_0x18df2e0 =
    gcc_jit_rvalue_dereference (gcc_jit_lvalue_as_rvalue (local_dptr), /* gcc_jit_rvalue *rvalue */
                                NULL); /* gcc_jit_location *loc */
  gcc_jit_block_add_assignment (block_p_C1_end, /*gcc_jit_block *block */
                                NULL, /* gcc_jit_location *loc */
                                dereference__dptr_0x18df2e0, /* gcc_jit_lvalue *lvalue */
                                rvalue__unsigned_char_ival); /* gcc_jit_rvalue *rvalue */
  gcc_jit_rvalue *rvalue__int_1 =
    gcc_jit_context_new_rvalue_from_int (ctxt, /* gcc_jit_context *ctxt */
                                         type_int, /* gcc_jit_type *numeric_type */
                                         1); /* int value */
  gcc_jit_lvalue *lvalue_dptr__int_1_ = 
    gcc_jit_context_new_array_access (ctxt, /* gcc_jit_context *ctxt */
                                      NULL, /*gcc_jit_location *loc */
                                      gcc_jit_lvalue_as_rvalue (local_dptr), /* gcc_jit_rvalue *ptr */
                                      rvalue__int_1); /* gcc_jit_rvalue *index */
  gcc_jit_rvalue *address_of__dptr__int_1_ =
    gcc_jit_lvalue_get_address (lvalue_dptr__int_1_, /* gcc_jit_lvalue *lvalue */
                                NULL); /* gcc_jit_location *loc */
  gcc_jit_block_add_assignment (block_p_C1_end, /*gcc_jit_block *block */
                                NULL, /* gcc_jit_location *loc */
                                local_dptr, /* gcc_jit_lvalue *lvalue */
                                address_of__dptr__int_1_); /* gcc_jit_rvalue *rvalue */
  gcc_jit_rvalue *rvalue__int_1_0x18df500 =
    gcc_jit_context_new_rvalue_from_int (ctxt, /* gcc_jit_context *ctxt */
                                         type_int, /* gcc_jit_type *numeric_type */
                                         1); /* int value */
  gcc_jit_lvalue *lvalue_sptr__int_1_ = 
    gcc_jit_context_new_array_access (ctxt, /* gcc_jit_context *ctxt */
                                      NULL, /*gcc_jit_location *loc */
                                      gcc_jit_lvalue_as_rvalue (local_sptr), /* gcc_jit_rvalue *ptr */
                                      rvalue__int_1_0x18df500); /* gcc_jit_rvalue *index */
  gcc_jit_rvalue *address_of__sptr__int_1_ =
    gcc_jit_lvalue_get_address (lvalue_sptr__int_1_, /* gcc_jit_lvalue *lvalue */
                                NULL); /* gcc_jit_location *loc */
  gcc_jit_block_add_assignment (block_p_C1_end, /*gcc_jit_block *block */
                                NULL, /* gcc_jit_location *loc */
                                local_sptr, /* gcc_jit_lvalue *lvalue */
                                address_of__sptr__int_1_); /* gcc_jit_rvalue *rvalue */
  gcc_jit_rvalue *rvalue__int_1_0x18df650 =
    gcc_jit_context_new_rvalue_from_int (ctxt, /* gcc_jit_context *ctxt */
                                         type_int, /* gcc_jit_type *numeric_type */
                                         1); /* int value */
  gcc_jit_rvalue *rvalue_i____int_1 =
    gcc_jit_context_new_binary_op (ctxt,
                                   NULL, /* gcc_jit_location *loc */
                                   GCC_JIT_BINARY_OP_PLUS, /* enum gcc_jit_binary_op op */
                                   type_int, /* gcc_jit_type *result_type */
                                   gcc_jit_lvalue_as_rvalue (local_i), /* gcc_jit_rvalue *a */
                                   rvalue__int_1_0x18df650); /* gcc_jit_rvalue *b */
  gcc_jit_block_add_assignment (block_p_C1_end, /*gcc_jit_block *block */
                                NULL, /* gcc_jit_location *loc */
                                local_i, /* gcc_jit_lvalue *lvalue */
                                rvalue_i____int_1); /* gcc_jit_rvalue *rvalue */
  gcc_jit_block_end_with_jump (block_p_C1_end, /*gcc_jit_block *block */
                               NULL, /* gcc_jit_location *loc */
                               block_C2); /* gcc_jit_block *target */
  gcc_jit_rvalue *rvalue__int_1_0x18df7e0 =
    gcc_jit_context_new_rvalue_from_int (ctxt, /* gcc_jit_context *ctxt */
                                         type_int, /* gcc_jit_type *numeric_type */
                                         1); /* int value */
  gcc_jit_rvalue *rvalue_j____int_1 =
    gcc_jit_context_new_binary_op (ctxt,
                                   NULL, /* gcc_jit_location *loc */
                                   GCC_JIT_BINARY_OP_PLUS, /* enum gcc_jit_binary_op op */
                                   type_int, /* gcc_jit_type *result_type */
                                   gcc_jit_lvalue_as_rvalue (local_j), /* gcc_jit_rvalue *a */
                                   rvalue__int_1_0x18df7e0); /* gcc_jit_rvalue *b */
  gcc_jit_block_add_assignment (block_A2, /*gcc_jit_block *block */
                                NULL, /* gcc_jit_location *loc */
                                local_j, /* gcc_jit_lvalue *lvalue */
                                rvalue_j____int_1); /* gcc_jit_rvalue *rvalue */
  gcc_jit_block_end_with_jump (block_A2, /*gcc_jit_block *block */
                               NULL, /* gcc_jit_location *loc */
                               block_C1); /* gcc_jit_block *target */
  gcc_jit_block_end_with_void_return (block_A1, /*gcc_jit_block *block */
                                      NULL); /* gcc_jit_location *loc */
}
示例#22
0
static void
create_overflow_fn (gcc_jit_context *ctxt,
		    gcc_jit_type *type,
		    const char *funcname,
		    const char *builtin_name)
{
  /* Create the equivalent of this C:

       int
       test_overflow_T_OP (T x, T y, int *ovf)
       {
	 T result;
	 result = x OP y;
	 *ovf = ...; // did overflow happen?
	 return result;
       }

  */
  gcc_jit_type *t_bool =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_BOOL);
  gcc_jit_type *t_bool_star =
    gcc_jit_type_get_pointer (t_bool);

  gcc_jit_param *x =
    gcc_jit_context_new_param (
      ctxt,
      NULL,
      type, "x");
  gcc_jit_param *y =
    gcc_jit_context_new_param (
      ctxt,
      NULL,
      type, "y");
  gcc_jit_param *ovf =
    gcc_jit_context_new_param (
      ctxt,
      NULL,
      t_bool_star, "ovf");
  gcc_jit_param *params[3] = {x, y, ovf};

  gcc_jit_function *func =
    gcc_jit_context_new_function (ctxt,
				  NULL,
				  GCC_JIT_FUNCTION_EXPORTED,
				  type,
				  funcname,
				  3, params, 0);

  gcc_jit_lvalue *result =
    gcc_jit_function_new_local (func, NULL, type, "result");

  gcc_jit_block *b_initial =
    gcc_jit_function_new_block (func, "initial");

  /* The builtins are listed in builtins.def as being variadic, but
     the have these signatures:
       bool __builtin_add_overflow (type1 a, type2 b, type3 *res);
       bool __builtin_sub_overflow (type1 a, type2 b, type3 *res);
       bool __builtin_mul_overflow (type1 a, type2 b, type3 *res);  */

  gcc_jit_function *builtin_fn =
    gcc_jit_context_get_builtin_function (ctxt, builtin_name);

  /* Construct a call of the form:
       (returns bool) __builtin_add_overflow (x, y, &result).  */
  gcc_jit_rvalue *args[3] = {gcc_jit_param_as_rvalue (x),
			     gcc_jit_param_as_rvalue (y),
			     gcc_jit_lvalue_get_address (result, NULL)};
  gcc_jit_rvalue *call =
    gcc_jit_context_new_call (ctxt,
			      NULL,
			      builtin_fn,
			      3, args);

  /* "*ovf = BUILTIN_CALL ();" */
  gcc_jit_block_add_assignment (
    b_initial, NULL,
    gcc_jit_rvalue_dereference (gcc_jit_param_as_rvalue (ovf),
				NULL),
    call);

  /* "return result;" */
  gcc_jit_block_end_with_return (
    b_initial, NULL,
    gcc_jit_lvalue_as_rvalue (result));
}
示例#23
0
void generate_code_regexp(gcc_jit_context *ctx, const char* regexp)
{
  const char* matchhere_regexp = regexp;
  if (regexp[0] == '^')
  {
    matchhere_regexp++;
  }
  gcc_jit_function* matchhere = generate_code_matchhere(ctx, matchhere_regexp, "matchhere");

  // match function
  gcc_jit_type *int_type = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_INT);
  gcc_jit_type *char_type = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_CHAR);
  gcc_jit_type *const_char_ptr_type = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_CONST_CHAR_PTR);

  gcc_jit_param *param_text = gcc_jit_context_new_param(ctx, /* loc */ NULL, const_char_ptr_type, "text");
  gcc_jit_param *param_regex = gcc_jit_context_new_param(ctx, /* loc */ NULL, const_char_ptr_type, "_regex");
  gcc_jit_rvalue *rval_text = gcc_jit_param_as_rvalue(param_text);

  gcc_jit_param* params[] = { param_regex, param_text };
  gcc_jit_function *match = gcc_jit_context_new_function(ctx, /* loc */ NULL,
      GCC_JIT_FUNCTION_EXPORTED, int_type, "match",
      2, params, /* is_variadic */ 0);

  gcc_jit_rvalue* args[] = { rval_text };
  gcc_jit_rvalue* call_to_matchhere = gcc_jit_context_new_call(ctx, /* loc */ NULL,
      matchhere,
      1, args);
  if (regexp[0] == '^')
  {
    gcc_jit_block* block = gcc_jit_function_new_block(match, new_block_name());

    gcc_jit_block_end_with_return(
        block, /* loc */ NULL,
        gcc_jit_context_new_comparison(ctx, /* loc */ NULL,
          GCC_JIT_COMPARISON_NE, 
          call_to_matchhere,
          gcc_jit_context_zero(ctx, int_type)));
  }
  else
  {
    gcc_jit_block* loop_body = gcc_jit_function_new_block(match, new_block_name());
    gcc_jit_block* return_one = gcc_jit_function_new_block(match, new_block_name());
    gcc_jit_block* condition_check = gcc_jit_function_new_block(match, new_block_name());
    gcc_jit_block* return_zero = gcc_jit_function_new_block(match, new_block_name());

    gcc_jit_block_end_with_conditional(
        loop_body, /* loc */ NULL,
        gcc_jit_context_new_comparison(ctx, /* loc */ NULL,
          GCC_JIT_COMPARISON_NE, 
          call_to_matchhere,
          gcc_jit_context_zero(ctx, int_type)),
        return_one,
        condition_check);

    gcc_jit_block_end_with_return(
        return_one, /* loc */ NULL,
        gcc_jit_context_one(ctx, int_type));

    gcc_jit_lvalue* tmp = gcc_jit_function_new_local(match, /* loc */ NULL, char_type, new_local_name());
    gcc_jit_block_add_assignment(
        condition_check, /* loc */ NULL,
        tmp,
        gcc_jit_lvalue_as_rvalue(
          gcc_jit_rvalue_dereference(rval_text, /* loc */ NULL)));
    gcc_jit_block_add_assignment(
        condition_check, /* loc */ NULL,
        gcc_jit_param_as_lvalue(param_text),
        gcc_jit_context_new_cast(
          ctx, /* loc */ NULL,
          gcc_jit_lvalue_get_address(
            gcc_jit_context_new_array_access(
              ctx, /* loc */ NULL,
              rval_text,
              gcc_jit_context_one(ctx, int_type)),
            /* loc */ NULL),
          const_char_ptr_type));
    gcc_jit_block_end_with_conditional(
        condition_check, /* loc */ NULL,
        gcc_jit_context_new_comparison(ctx, /* loc */ NULL,
          GCC_JIT_COMPARISON_NE, 
          gcc_jit_lvalue_as_rvalue(tmp),
          gcc_jit_context_zero(ctx, char_type)),
        loop_body,
        return_zero);

    gcc_jit_block_end_with_return(
        return_zero, /* loc */ NULL,
        gcc_jit_context_zero(ctx, int_type));
  }
  // gcc_jit_function_dump_to_dot(match, "match.dot");

  // gcc_jit_context_dump_to_file(ctx, "generated-regex.dump", /* update-locations */ 1);
  // gcc_jit_context_set_bool_option(ctx, GCC_JIT_BOOL_OPTION_DEBUGINFO, 1);
}
示例#24
0
static gcc_jit_function *generate_code_matchhere(gcc_jit_context *ctx, const char* regexp, const char* function_name)
{
  gcc_jit_type *int_type = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_INT);
  gcc_jit_type *char_type = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_CHAR);
  gcc_jit_type *const_char_ptr_type = gcc_jit_context_get_type(ctx, GCC_JIT_TYPE_CONST_CHAR_PTR);

  gcc_jit_param *param_text = gcc_jit_context_new_param(ctx, /* loc */ NULL, const_char_ptr_type, "text");
  gcc_jit_rvalue *rval_text = gcc_jit_param_as_rvalue(param_text);

  // matchhere
  gcc_jit_param* params[] = { param_text };
  gcc_jit_function *matchhere = gcc_jit_context_new_function(ctx, /* loc */ NULL,
      GCC_JIT_FUNCTION_INTERNAL, int_type, function_name,
      1, params, /* is_variadic */ 0);
  gcc_jit_block* current_block = gcc_jit_function_new_block(matchhere, new_block_name());

  gcc_jit_rvalue* text_plus_one = 
    gcc_jit_context_new_cast(
        ctx, /* loc */ NULL,
        gcc_jit_lvalue_get_address(
          gcc_jit_context_new_array_access(
            ctx, /* loc */ NULL,
            rval_text,
            gcc_jit_context_one(ctx, int_type)),
          /* loc */ NULL),
        const_char_ptr_type);

  gcc_jit_block* return_zero = NULL;

  gcc_jit_block* return_one = gcc_jit_function_new_block(matchhere, new_block_name());
  gcc_jit_block_end_with_return(
      return_one, /* loc */ NULL,
      gcc_jit_context_one(ctx, int_type));

  // Now go creating
  for (;;)
  {
    if (regexp[0] == '\0')
    {
      gcc_jit_block_end_with_jump(
          current_block, /* loc */ NULL,
          return_one);
      break; // We are done
    }
    else if (regexp[1] == '*')
    {
      // Generate code for the remaining regular expression
      gcc_jit_function *remaining_regexp_match = generate_code_matchhere(ctx, regexp + 2, new_function_name());

      gcc_jit_block* loop_body = gcc_jit_function_new_block(matchhere, new_block_name());
      gcc_jit_block* loop_check = gcc_jit_function_new_block(matchhere, new_block_name());

      gcc_jit_block_end_with_jump(current_block, /* loc */ NULL, loop_body);

      gcc_jit_rvalue* args[] = { rval_text };
      gcc_jit_rvalue* match_remainder = 
        gcc_jit_context_new_comparison(
            ctx, /* loc */ NULL,
            GCC_JIT_COMPARISON_NE,
            gcc_jit_context_new_call(ctx, /* loc */ NULL,
              remaining_regexp_match, 1, args),
            gcc_jit_context_zero(ctx, int_type));

      gcc_jit_block_end_with_conditional(loop_body, /* loc */ NULL,
          match_remainder,
          return_one,
          loop_check);

      gcc_jit_lvalue* tmp = gcc_jit_function_new_local(matchhere, /* loc */ NULL, char_type, new_local_name());
      gcc_jit_block_add_assignment(
          loop_check, /* loc */ NULL,
          tmp,
          gcc_jit_lvalue_as_rvalue(
            gcc_jit_rvalue_dereference(rval_text, /* loc */ NULL)));

      gcc_jit_rvalue* check_expr;
      if (regexp[0] == '.')
      {
        check_expr =
          gcc_jit_context_new_comparison(ctx, /* loc */ NULL,
              GCC_JIT_COMPARISON_NE,
              gcc_jit_lvalue_as_rvalue(tmp),
              gcc_jit_context_zero(ctx, char_type));
      }
      else
      {
        check_expr =
          gcc_jit_context_new_comparison(ctx, /* loc */ NULL,
              GCC_JIT_COMPARISON_EQ,
              gcc_jit_lvalue_as_rvalue(tmp),
              gcc_jit_context_new_rvalue_from_int(ctx, char_type, regexp[0]));
      }

      generate_return_zero(ctx, matchhere, &return_zero);

      gcc_jit_block_add_assignment(loop_check, /* loc */ NULL,
          gcc_jit_param_as_lvalue(param_text),
          text_plus_one);
      gcc_jit_block_end_with_conditional(loop_check, /* loc */ NULL,
          check_expr,
          loop_body,
          return_zero);

      break; // We are done
    }
    else if (regexp[0] == '$' && regexp[1] == '\0')
    {
      gcc_jit_block_end_with_return(
          current_block, /* loc */ NULL,
          gcc_jit_context_new_comparison(ctx, /* loc */ NULL,
            GCC_JIT_COMPARISON_EQ, 
            gcc_jit_lvalue_as_rvalue(
              gcc_jit_rvalue_dereference(rval_text, /* loc */ NULL)
              ),
            gcc_jit_context_zero(ctx, char_type)));

      regexp++;
    }
    else if (regexp[0] == '.')
    {
      generate_return_zero(ctx, matchhere, &return_zero);

      gcc_jit_block* next_block = gcc_jit_function_new_block(matchhere, new_block_name());

      // if (*text == '\0')
      //    return 0;
      gcc_jit_block_end_with_conditional(
          current_block, /* loc */ NULL,
          gcc_jit_context_new_comparison(ctx, /* loc */ NULL,
            GCC_JIT_COMPARISON_EQ, 
            gcc_jit_lvalue_as_rvalue(
              gcc_jit_rvalue_dereference(rval_text, /* loc */ NULL)
              ),
            gcc_jit_context_zero(ctx, char_type)),
          return_zero,
          next_block);

      // text = &text[1]; // pointer arithmetic
      gcc_jit_block_add_assignment(next_block, /* loc */ NULL,
          gcc_jit_param_as_lvalue(param_text),
          text_plus_one);

      // Chain the code
      current_block = next_block;

      // Done with the current letter
      regexp++;
    }
    else
    {
      generate_return_zero(ctx, matchhere, &return_zero);

      gcc_jit_block* next_block = gcc_jit_function_new_block(matchhere, new_block_name());

      // if (*text != regexp[0])
      //    return 0;
      gcc_jit_block_end_with_conditional(
          current_block, /* loc */ NULL,
          gcc_jit_context_new_comparison(ctx, /* loc */ NULL,
            GCC_JIT_COMPARISON_NE, 
            gcc_jit_lvalue_as_rvalue(
              gcc_jit_rvalue_dereference(rval_text, /* loc */ NULL)
              ),
            gcc_jit_context_new_rvalue_from_int(ctx, char_type, regexp[0])),
          return_zero,
          next_block);

      // text = &text[1]; // pointer arithmetic
      gcc_jit_block_add_assignment(next_block, /* loc */ NULL,
          gcc_jit_param_as_lvalue(param_text),
          text_plus_one);

      // Chain the code
      current_block = next_block;

      // Done with the current letter
      regexp++;
    }
  }

  // char c[64];
  // snprintf(c, 63, "%s.dot", function_name);
  // c[63] = '\0';

  // gcc_jit_function_dump_to_dot(matchhere, c);

  return matchhere;
}
示例#25
0
void
create_code (gcc_jit_context *ctxt, void *user_data)
{
  /* Let's try to inject the equivalent of:

	double
	test_nested_loops (int n, double *a, double *b)
	{
	  double result = 0.;
	  for (int i = 0; i < n; i++)
	    for (int j = 0; j < n; j++)
	      result += a[i] * b[j];
	  return result
	}
  */
  gcc_jit_type *val_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE);
  gcc_jit_type *ptr_type = gcc_jit_type_get_pointer (val_type);
  gcc_jit_type *int_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);

  gcc_jit_type *return_type = val_type;
  gcc_jit_param *param_n =
    gcc_jit_context_new_param (ctxt, NULL, int_type, "n");
  gcc_jit_param *param_a =
    gcc_jit_context_new_param (ctxt, NULL, ptr_type, "a");
  gcc_jit_param *param_b =
    gcc_jit_context_new_param (ctxt, NULL, ptr_type, "b");
  gcc_jit_param *params[3] = {param_n, param_a, param_b};
  gcc_jit_function *func =
    gcc_jit_context_new_function (ctxt, NULL,
				  GCC_JIT_FUNCTION_EXPORTED,
				  return_type,
				  "test_nested_loops",
				  3, params, 0);

  /* Create locals. */
  gcc_jit_lvalue *result =
    gcc_jit_function_new_local (func, NULL, val_type, "result");
  gcc_jit_lvalue *i =
    gcc_jit_function_new_local (func, NULL, int_type, "i");
  gcc_jit_lvalue *j =
    gcc_jit_function_new_local (func, NULL, int_type, "j");

  /* Create basic blocks. */
  gcc_jit_block *b_entry =
    gcc_jit_function_new_block (func, "b_entry");
  gcc_jit_block *b_outer_loop_cond =
    gcc_jit_function_new_block (func, "b_outer_loop_cond");
  gcc_jit_block *b_outer_loop_head =
    gcc_jit_function_new_block (func, "b_outer_loop_head");
  gcc_jit_block *b_outer_loop_tail =
    gcc_jit_function_new_block (func, "b_outer_loop_tail");
  gcc_jit_block *b_inner_loop_cond =
    gcc_jit_function_new_block (func, "b_inner_loop_cond");
  gcc_jit_block *b_inner_loop_body =
    gcc_jit_function_new_block (func, "b_inner_loop_body");
  gcc_jit_block *b_exit =
    gcc_jit_function_new_block (func, "b_exit");


  /* Populate b_entry. */

  /* "result = 0.;" */
  gcc_jit_block_add_assignment (
    b_entry, NULL,
    result,
    gcc_jit_context_zero (ctxt, val_type));
  /* "i = 0;" */
  gcc_jit_block_add_assignment (
    b_entry, NULL,
    i,
    gcc_jit_context_zero (ctxt, int_type));
  gcc_jit_block_end_with_jump (b_entry, NULL, b_outer_loop_cond);

  /* Populate b_outer_loop_cond. */
  gcc_jit_block_end_with_conditional (
    b_outer_loop_cond,
    NULL,
    /* (i < n) */
    gcc_jit_context_new_comparison (
      ctxt, NULL,
      GCC_JIT_COMPARISON_LT,
      gcc_jit_lvalue_as_rvalue (i),
      gcc_jit_param_as_rvalue (param_n)),
    b_outer_loop_head,
    b_exit);

  /* Populate b_outer_loop_head. */
  /* j = 0; */
  gcc_jit_block_add_assignment (
    b_outer_loop_head, NULL,
    j,
    gcc_jit_context_zero (ctxt, int_type));
  gcc_jit_block_end_with_jump (b_outer_loop_head, NULL, b_inner_loop_cond);

  /* Populate b_inner_loop_cond. */
  gcc_jit_block_end_with_conditional (
    b_inner_loop_cond,
    NULL,
    /* (j < n) */
    gcc_jit_context_new_comparison (
      ctxt, NULL,
      GCC_JIT_COMPARISON_LT,
      gcc_jit_lvalue_as_rvalue (j),
      gcc_jit_param_as_rvalue (param_n)),
    b_inner_loop_body,
    b_outer_loop_tail);

  /* Populate b_inner_loop_body. */
  /* "result += a[i] * b[j];" */
  gcc_jit_block_add_assignment_op (
    b_inner_loop_body, NULL,
    result,
    GCC_JIT_BINARY_OP_PLUS,
    gcc_jit_context_new_binary_op (
      ctxt, NULL,
      GCC_JIT_BINARY_OP_MULT,
      val_type,
      gcc_jit_lvalue_as_rvalue (
        gcc_jit_context_new_array_access(
          ctxt, NULL,
          gcc_jit_param_as_rvalue (param_a),
          gcc_jit_lvalue_as_rvalue (i))),
      gcc_jit_lvalue_as_rvalue (
        gcc_jit_context_new_array_access(
          ctxt, NULL,
          gcc_jit_param_as_rvalue (param_b),
          gcc_jit_lvalue_as_rvalue (j)))));
  /* "j++" */
  gcc_jit_block_add_assignment_op (
    b_inner_loop_body, NULL,
    j,
    GCC_JIT_BINARY_OP_PLUS,
    gcc_jit_context_one (ctxt, int_type));

  gcc_jit_block_end_with_jump (b_inner_loop_body, NULL, b_inner_loop_cond);

  /* Populate b_outer_loop_tail. */
  /* "i++" */
  gcc_jit_block_add_assignment_op (
    b_outer_loop_tail, NULL,
    i,
    GCC_JIT_BINARY_OP_PLUS,
    gcc_jit_context_one (ctxt, int_type));
  gcc_jit_block_end_with_jump (b_outer_loop_tail, NULL, b_outer_loop_cond);

  /* Populate b_exit. */
  /* "return result;" */
  gcc_jit_block_end_with_return (
    b_exit,
    NULL,
    gcc_jit_lvalue_as_rvalue (result));
}
示例#26
0
/**********************************************************************
 GCC_JIT_FUNCTION_ALWAYS_INLINE and GCC_JIT_FUNCTION_INTERNAL
 **********************************************************************/
static void
create_test_of_hidden_function (gcc_jit_context *ctxt,
				enum gcc_jit_function_kind hidden_kind,
				const char *hidden_func_name,
				const char *visible_func_name)
{
  /* Let's try to inject the equivalent of:
     static double hidden_mult (double a, double b)
     {
       return x * x;
     }
     double my_square (double x)
     {
       return my_mult (x, x);
     }

     where hidden_mult can potentially be
       inline  __attribute__((always_inline)).  */
  gcc_jit_type *double_type =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE);

  /* Create "my_mult" */
  gcc_jit_param *param_a =
    gcc_jit_context_new_param (ctxt, NULL, double_type, "a");
  gcc_jit_param *param_b =
    gcc_jit_context_new_param (ctxt, NULL, double_type, "b");
  gcc_jit_param *params[2] = {param_a, param_b};
  gcc_jit_function *my_mult =
    gcc_jit_context_new_function (ctxt, NULL,
				  hidden_kind,
                                  double_type,
                                  hidden_func_name,
                                  2, params,
                                  0);
  gcc_jit_block *body_of_my_mult =
    gcc_jit_function_new_block (my_mult, NULL);
  gcc_jit_block_end_with_return (
    body_of_my_mult, NULL,
    gcc_jit_context_new_binary_op (
      ctxt, NULL,
      GCC_JIT_BINARY_OP_MULT,
      double_type,
      gcc_jit_param_as_rvalue (param_a),
      gcc_jit_param_as_rvalue (param_b)));

  /* Create "my_square" */
  gcc_jit_param *param_x =
    gcc_jit_context_new_param (ctxt, NULL, double_type, "x");
  gcc_jit_function *my_square =
    gcc_jit_context_new_function (ctxt, NULL,
                                  GCC_JIT_FUNCTION_EXPORTED,
                                  double_type,
                                  visible_func_name,
                                  1, &param_x,
                                  0);
  gcc_jit_block *body_of_my_square =
    gcc_jit_function_new_block (my_square, NULL);
  gcc_jit_rvalue *args[2] = {gcc_jit_param_as_rvalue (param_x),
			     gcc_jit_param_as_rvalue (param_x)};
  gcc_jit_block_end_with_return (
    body_of_my_square, NULL,
    gcc_jit_context_new_call (
      ctxt, NULL,
      my_mult,
      2, args));
}
示例#27
0
static void
create_test_of_builtin_trig (gcc_jit_context *ctxt)
{
  /* Let's try to inject the equivalent of:
       int
       test_of_builtin_trig (double theta)
       {
         return 2 * sin (theta) * cos (theta);
       }
       (in theory, optimizable to sin (2 * theta))
  */

  gcc_jit_context_enable_dump (ctxt,
			       "tree-sincos",
			       &trig_sincos_dump);
  gcc_jit_context_enable_dump (ctxt,
			       "statistics",
			       &trig_statistics_dump);

  gcc_jit_type *double_t =
    gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE);

  /* Get the built-in functions.  */
  gcc_jit_function *builtin_sin =
    gcc_jit_context_get_builtin_function (ctxt, "sin");
  gcc_jit_function *builtin_cos =
    gcc_jit_context_get_builtin_function (ctxt, "cos");

  /* Build the test_fn.  */
  gcc_jit_param *param_theta =
    gcc_jit_context_new_param (ctxt, NULL, double_t, "theta");
  gcc_jit_function *test_fn =
    gcc_jit_context_new_function (ctxt, NULL,
                                  GCC_JIT_FUNCTION_EXPORTED,
                                  double_t,
                                  "test_of_builtin_trig",
                                  1, &param_theta,
                                  0);
  gcc_jit_rvalue *args[1] = {gcc_jit_param_as_rvalue (param_theta)};
  gcc_jit_rvalue *two =
    gcc_jit_context_new_rvalue_from_int (ctxt, double_t, 2);
  gcc_jit_rvalue *ret =
    gcc_jit_context_new_binary_op (
      ctxt, NULL,
      GCC_JIT_BINARY_OP_MULT,
      double_t,
      two,
      gcc_jit_context_new_binary_op (
        ctxt, NULL,
	GCC_JIT_BINARY_OP_MULT,
	double_t,
	gcc_jit_context_new_call (ctxt, NULL,
				  builtin_sin,
				  1, args),
	gcc_jit_context_new_call (ctxt, NULL,
				  builtin_cos,
				  1, args)));
  CHECK_STRING_VALUE (
    gcc_jit_object_get_debug_string (gcc_jit_rvalue_as_object (ret)),
    "(double)2 * sin (theta) * cos (theta)");

  gcc_jit_block *initial =
    gcc_jit_function_new_block (test_fn, "initial");
  gcc_jit_block_end_with_return (initial, NULL, ret);
}