1 #include <stdlib.h>
2 #include <stdio.h>
3
4 #include "libgccjit.h"
5
6 #include "harness.h"
7
8 struct bar
9 {
10 int x;
11 int y;
12 };
13
14 void
create_code(gcc_jit_context * ctxt,void * user_data)15 create_code (gcc_jit_context *ctxt, void *user_data)
16 {
17 /* Let's try to inject the equivalent of:
18
19 int
20 test_reading (const struct bar *f)
21 {
22 return f->x * f->y;
23 }
24
25 int
26 test_writing ()
27 {
28 struct bar tmp;
29 tmp.x = 5;
30 tmp.y = 7;
31 return test_reading (&tmp);
32 }
33 */
34 gcc_jit_type *int_type =
35 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
36 gcc_jit_field *x =
37 gcc_jit_context_new_field (ctxt,
38 NULL,
39 int_type,
40 "x");
41 gcc_jit_field *y =
42 gcc_jit_context_new_field (ctxt,
43 NULL,
44 int_type,
45 "y");
46 gcc_jit_field *fields[] = {x, y};
47 gcc_jit_type *struct_type =
48 gcc_jit_struct_as_type (
49 gcc_jit_context_new_struct_type (ctxt, NULL, "bar", 2, fields));
50 gcc_jit_type *const_struct_type = gcc_jit_type_get_const (struct_type);
51 gcc_jit_type *ptr_type = gcc_jit_type_get_pointer (const_struct_type);
52
53 /* Build "test_reading". */
54 gcc_jit_param *param_f =
55 gcc_jit_context_new_param (ctxt, NULL, ptr_type, "f");
56 gcc_jit_function *fn_test_reading =
57 gcc_jit_context_new_function (ctxt, NULL,
58 GCC_JIT_FUNCTION_EXPORTED,
59 int_type,
60 "test_reading",
61 1, ¶m_f,
62 0);
63
64 /* return f->x * f->y; */
65 gcc_jit_block *reading_block = gcc_jit_function_new_block (fn_test_reading, NULL);
66 gcc_jit_block_end_with_return (
67 reading_block,
68 NULL,
69 gcc_jit_context_new_binary_op (
70 ctxt, NULL,
71 GCC_JIT_BINARY_OP_MULT,
72 int_type,
73 gcc_jit_lvalue_as_rvalue (
74 gcc_jit_rvalue_dereference_field (
75 gcc_jit_param_as_rvalue (param_f),
76 NULL,
77 x)),
78 gcc_jit_lvalue_as_rvalue (
79 gcc_jit_rvalue_dereference_field (
80 gcc_jit_param_as_rvalue (param_f),
81 NULL,
82 y))));
83
84 /* Build "test_writing". */
85 gcc_jit_function *fn_test_writing =
86 gcc_jit_context_new_function (ctxt, NULL,
87 GCC_JIT_FUNCTION_EXPORTED,
88 int_type,
89 "test_writing",
90 0, NULL,
91 0);
92
93 /* struct bar tmp; */
94 gcc_jit_lvalue *local_tmp =
95 gcc_jit_function_new_local (fn_test_writing, NULL,
96 struct_type,
97 "tmp");
98 /* tmp.x = 5; */
99 gcc_jit_block *writing_block = gcc_jit_function_new_block (fn_test_writing, NULL);
100 gcc_jit_block_add_assignment (
101 writing_block, NULL,
102 gcc_jit_lvalue_access_field (local_tmp, NULL, x),
103 gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 5));
104
105 /* tmp.y = 7; */
106 gcc_jit_block_add_assignment (
107 writing_block, NULL,
108 gcc_jit_lvalue_access_field (local_tmp, NULL, y),
109 gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 7));
110
111 /* return test_reading (&tmp); */
112 gcc_jit_rvalue *arg = gcc_jit_lvalue_get_address (local_tmp, NULL);
113 gcc_jit_block_end_with_return (
114 writing_block,
115 NULL,
116 gcc_jit_context_new_call (
117 ctxt, NULL,
118 fn_test_reading,
119 1, &arg));
120 }
121
122 void
verify_code(gcc_jit_context * ctxt,gcc_jit_result * result)123 verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
124 {
125 typedef int (*fn_type) (void);
126 CHECK_NON_NULL (result);
127
128 fn_type test_writing =
129 (fn_type)gcc_jit_result_get_code (result, "test_writing");
130 CHECK_NON_NULL (test_writing);
131
132 /* Verify that the code correctly returns the product of the fields. */
133 CHECK_VALUE (test_writing (), 35);
134 }
135
136