evoasm 0.0.2.pre7 → 0.1.0.pre2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. checksums.yaml +4 -4
  2. data/.gdbinit +41 -0
  3. data/.gitignore +1 -2
  4. data/.gitmodules +3 -0
  5. data/.rubocop.yml +8 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.md +660 -0
  8. data/Makefile +1 -1
  9. data/README.md +17 -9
  10. data/Rakefile +39 -107
  11. data/bin/gdb +1 -1
  12. data/bin/gdb_loop +4 -0
  13. data/docs/FindingInstructions.md +17 -0
  14. data/docs/JIT.md +14 -0
  15. data/docs/SymbolicRegression.md +102 -0
  16. data/docs/Visualization.md +29 -0
  17. data/docs/examples/bit_insts.rb +44 -0
  18. data/docs/examples/jit.rb +26 -0
  19. data/docs/examples/loss.gif +0 -0
  20. data/docs/examples/program.png +0 -0
  21. data/docs/examples/sym_reg.rb +64 -0
  22. data/docs/examples/vis.rb +38 -0
  23. data/evoasm.gemspec +21 -15
  24. data/ext/evoasm_ext/Rakefile +3 -0
  25. data/ext/evoasm_ext/compile.rake +35 -0
  26. data/ext/evoasm_ext/libevoasm/src/evoasm-alloc.c +226 -0
  27. data/ext/evoasm_ext/libevoasm/src/evoasm-alloc.h +84 -0
  28. data/ext/evoasm_ext/libevoasm/src/evoasm-arch.c +52 -0
  29. data/ext/evoasm_ext/libevoasm/src/evoasm-arch.h +101 -0
  30. data/ext/evoasm_ext/libevoasm/src/evoasm-bitmap.h +158 -0
  31. data/ext/evoasm_ext/libevoasm/src/evoasm-buf.c +204 -0
  32. data/ext/evoasm_ext/libevoasm/src/evoasm-buf.h +109 -0
  33. data/ext/evoasm_ext/libevoasm/src/evoasm-domain.c +124 -0
  34. data/ext/evoasm_ext/libevoasm/src/evoasm-domain.h +279 -0
  35. data/ext/evoasm_ext/libevoasm/src/evoasm-error.c +65 -0
  36. data/ext/evoasm_ext/libevoasm/src/evoasm-error.h +108 -0
  37. data/ext/evoasm_ext/{evoasm-log.c → libevoasm/src/evoasm-log.c} +36 -18
  38. data/ext/evoasm_ext/libevoasm/src/evoasm-log.h +93 -0
  39. data/ext/evoasm_ext/libevoasm/src/evoasm-param.c +22 -0
  40. data/ext/evoasm_ext/libevoasm/src/evoasm-param.h +33 -0
  41. data/ext/evoasm_ext/libevoasm/src/evoasm-pop-params.c +192 -0
  42. data/ext/evoasm_ext/libevoasm/src/evoasm-pop-params.h +60 -0
  43. data/ext/evoasm_ext/libevoasm/src/evoasm-pop.c +1323 -0
  44. data/ext/evoasm_ext/libevoasm/src/evoasm-pop.h +107 -0
  45. data/ext/evoasm_ext/libevoasm/src/evoasm-program-io.c +116 -0
  46. data/ext/evoasm_ext/libevoasm/src/evoasm-program-io.h +60 -0
  47. data/ext/evoasm_ext/libevoasm/src/evoasm-program.c +1827 -0
  48. data/ext/evoasm_ext/libevoasm/src/evoasm-program.h +167 -0
  49. data/ext/evoasm_ext/libevoasm/src/evoasm-rand.c +65 -0
  50. data/ext/evoasm_ext/libevoasm/src/evoasm-rand.h +76 -0
  51. data/ext/evoasm_ext/libevoasm/src/evoasm-signal.c +106 -0
  52. data/ext/evoasm_ext/libevoasm/src/evoasm-signal.h +58 -0
  53. data/ext/evoasm_ext/libevoasm/src/evoasm-util.h +112 -0
  54. data/ext/evoasm_ext/libevoasm/src/evoasm-x64.c +925 -0
  55. data/ext/evoasm_ext/libevoasm/src/evoasm-x64.h +277 -0
  56. data/ext/evoasm_ext/libevoasm/src/evoasm.c +28 -0
  57. data/ext/evoasm_ext/libevoasm/src/evoasm.h +35 -0
  58. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-enums.h +2077 -0
  59. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-insts.c +191203 -0
  60. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-insts.h +1713 -0
  61. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-misc.c +348 -0
  62. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-misc.h +93 -0
  63. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-params.c +51 -0
  64. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-params.h +509 -0
  65. data/lib/evoasm.rb +28 -11
  66. data/lib/evoasm/buffer.rb +105 -0
  67. data/lib/evoasm/capstone.rb +100 -0
  68. data/lib/evoasm/domain.rb +116 -0
  69. data/lib/evoasm/error.rb +37 -16
  70. data/lib/evoasm/exception_error.rb +19 -0
  71. data/lib/evoasm/ffi_ext.rb +53 -0
  72. data/lib/evoasm/libevoasm.rb +286 -0
  73. data/lib/evoasm/libevoasm/x64_enums.rb +1967 -0
  74. data/lib/evoasm/parameter.rb +20 -0
  75. data/lib/evoasm/population.rb +145 -0
  76. data/lib/evoasm/population/parameters.rb +227 -0
  77. data/lib/evoasm/population/plotter.rb +89 -0
  78. data/lib/evoasm/prng.rb +64 -0
  79. data/lib/evoasm/program.rb +195 -12
  80. data/lib/evoasm/program/io.rb +144 -0
  81. data/lib/evoasm/test.rb +8 -0
  82. data/lib/evoasm/version.rb +1 -1
  83. data/lib/evoasm/x64.rb +115 -0
  84. data/lib/evoasm/x64/cpu_state.rb +95 -0
  85. data/lib/evoasm/x64/instruction.rb +109 -0
  86. data/lib/evoasm/x64/operand.rb +156 -0
  87. data/lib/evoasm/x64/parameters.rb +211 -0
  88. data/test/helpers/population_helper.rb +128 -0
  89. data/test/helpers/test_helper.rb +1 -0
  90. data/test/helpers/x64_helper.rb +24 -0
  91. data/test/integration/bitwise_reverse_test.rb +41 -0
  92. data/test/integration/gcd_test.rb +52 -0
  93. data/test/integration/popcnt_test.rb +46 -0
  94. data/test/integration/sym_reg_test.rb +68 -0
  95. data/test/unit/evoasm/buffer_test.rb +48 -0
  96. data/test/unit/evoasm/capstone_test.rb +18 -0
  97. data/test/unit/evoasm/domain_test.rb +55 -0
  98. data/test/unit/evoasm/population/parameters_test.rb +106 -0
  99. data/test/unit/evoasm/population_test.rb +96 -0
  100. data/test/unit/evoasm/prng_test.rb +47 -0
  101. data/test/unit/evoasm/x64/cpu_state_test.rb +73 -0
  102. data/test/unit/evoasm/x64/encoding_test.rb +320 -0
  103. data/test/unit/evoasm/x64/instruction_access_test.rb +177 -0
  104. data/test/unit/evoasm/x64/instruction_encoding_test.rb +780 -0
  105. data/test/unit/evoasm/x64/instruction_test.rb +62 -0
  106. data/test/unit/evoasm/x64/parameters_test.rb +65 -0
  107. data/test/unit/evoasm/x64_test.rb +52 -0
  108. metadata +195 -89
  109. data/Gemfile.rake +0 -8
  110. data/Gemfile.rake.lock +0 -51
  111. data/LICENSE.txt +0 -373
  112. data/data/tables/README.md +0 -19
  113. data/data/tables/x64.csv +0 -1684
  114. data/data/templates/evoasm-x64.c.erb +0 -319
  115. data/data/templates/evoasm-x64.h.erb +0 -126
  116. data/examples/abs.yml +0 -20
  117. data/examples/popcnt.yml +0 -17
  118. data/examples/sym_reg.yml +0 -26
  119. data/exe/evoasm-search +0 -13
  120. data/ext/evoasm_ext/evoasm-alloc.c +0 -145
  121. data/ext/evoasm_ext/evoasm-alloc.h +0 -59
  122. data/ext/evoasm_ext/evoasm-arch.c +0 -44
  123. data/ext/evoasm_ext/evoasm-arch.h +0 -161
  124. data/ext/evoasm_ext/evoasm-bitmap.h +0 -114
  125. data/ext/evoasm_ext/evoasm-buf.c +0 -130
  126. data/ext/evoasm_ext/evoasm-buf.h +0 -47
  127. data/ext/evoasm_ext/evoasm-error.c +0 -31
  128. data/ext/evoasm_ext/evoasm-error.h +0 -75
  129. data/ext/evoasm_ext/evoasm-free-list.c.tmpl +0 -121
  130. data/ext/evoasm_ext/evoasm-free-list.h.tmpl +0 -86
  131. data/ext/evoasm_ext/evoasm-log.h +0 -69
  132. data/ext/evoasm_ext/evoasm-misc.c +0 -23
  133. data/ext/evoasm_ext/evoasm-misc.h +0 -282
  134. data/ext/evoasm_ext/evoasm-param.h +0 -37
  135. data/ext/evoasm_ext/evoasm-search.c +0 -2145
  136. data/ext/evoasm_ext/evoasm-search.h +0 -214
  137. data/ext/evoasm_ext/evoasm-util.h +0 -40
  138. data/ext/evoasm_ext/evoasm-x64.c +0 -275624
  139. data/ext/evoasm_ext/evoasm-x64.h +0 -5436
  140. data/ext/evoasm_ext/evoasm.c +0 -7
  141. data/ext/evoasm_ext/evoasm.h +0 -23
  142. data/ext/evoasm_ext/evoasm_ext.c +0 -1757
  143. data/ext/evoasm_ext/extconf.rb +0 -31
  144. data/lib/evoasm/cli.rb +0 -6
  145. data/lib/evoasm/cli/search.rb +0 -127
  146. data/lib/evoasm/core_ext.rb +0 -1
  147. data/lib/evoasm/core_ext/array.rb +0 -9
  148. data/lib/evoasm/core_ext/integer.rb +0 -10
  149. data/lib/evoasm/core_ext/kwstruct.rb +0 -13
  150. data/lib/evoasm/core_ext/range.rb +0 -5
  151. data/lib/evoasm/examples.rb +0 -27
  152. data/lib/evoasm/gen.rb +0 -8
  153. data/lib/evoasm/gen/enum.rb +0 -169
  154. data/lib/evoasm/gen/name_util.rb +0 -80
  155. data/lib/evoasm/gen/state.rb +0 -176
  156. data/lib/evoasm/gen/state_dsl.rb +0 -152
  157. data/lib/evoasm/gen/strio.rb +0 -27
  158. data/lib/evoasm/gen/translator.rb +0 -1102
  159. data/lib/evoasm/gen/version.rb +0 -5
  160. data/lib/evoasm/gen/x64.rb +0 -237
  161. data/lib/evoasm/gen/x64/funcs.rb +0 -495
  162. data/lib/evoasm/gen/x64/inst.rb +0 -781
  163. data/lib/evoasm/search.rb +0 -40
  164. data/lib/evoasm/tasks/gen_task.rb +0 -86
  165. data/lib/evoasm/tasks/template_task.rb +0 -52
  166. data/test/test_helper.rb +0 -1
  167. data/test/x64/test_helper.rb +0 -19
  168. data/test/x64/x64_test.rb +0 -87
@@ -0,0 +1,109 @@
1
+ /*
2
+ * Copyright (C) 2016 Julian Aron Prenner <jap@polyadic.com>
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify
5
+ * it under the terms of the GNU Affero General Public License as published by
6
+ * the Free Software Foundation, either version 3 of the License, or
7
+ * (at your option) any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ * GNU Affero General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU Affero General Public License
15
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ */
17
+
18
+ #pragma once
19
+
20
+ #include <stdbool.h>
21
+ #include <stdint.h>
22
+ #include <stdlib.h>
23
+ #include <stdio.h>
24
+
25
+ #include "evoasm-error.h"
26
+ #include "evoasm-log.h"
27
+ #include "evoasm-alloc.h"
28
+ #include "evoasm.h"
29
+
30
+ typedef enum {
31
+ EVOASM_BUF_TYPE_MMAP,
32
+ EVOASM_BUF_TYPE_MALLOC,
33
+ EVOASM_BUF_TYPE_NONE
34
+ } evoasm_buf_type_t;
35
+
36
+ typedef enum {
37
+ EVOASM_BUF_ERROR_CODE_NO_SPACE
38
+ } evoasm_buf_error_code_t;
39
+
40
+ typedef struct {
41
+ size_t capa;
42
+ size_t pos;
43
+ unsigned type : 2;
44
+ uint8_t *data;
45
+ } evoasm_buf_t;
46
+
47
+ typedef struct evoasm_buf_ref {
48
+ size_t *pos;
49
+ uint8_t *data;
50
+ } evoasm_buf_ref_t;
51
+
52
+ evoasm_success_t
53
+ evoasm_buf_init(evoasm_buf_t *buf, evoasm_buf_type_t buf_type, size_t size);
54
+
55
+ evoasm_success_t
56
+ evoasm_buf_destroy(evoasm_buf_t *buf);
57
+
58
+ void
59
+ evoasm_buf_reset(evoasm_buf_t *buf);
60
+
61
+ size_t
62
+ evoasm_buf_append(evoasm_buf_t * restrict dst, evoasm_buf_t * restrict src);
63
+
64
+ evoasm_success_t
65
+ evoasm_buf_protect(evoasm_buf_t *buf, evoasm_mprot_mode_t mode);
66
+
67
+ intptr_t
68
+ evoasm_buf_exec(evoasm_buf_t *buf);
69
+
70
+ void
71
+ evoasm_buf_log(evoasm_buf_t *buf, evoasm_log_level_t log_level);
72
+
73
+ evoasm_success_t
74
+ evoasm_buf_clone(evoasm_buf_t * restrict buf, evoasm_buf_t * restrict cloned_buf);
75
+
76
+ void
77
+ evoasm_buf_to_buf_ref(evoasm_buf_t *buf, evoasm_buf_ref_t *buf_ref);
78
+
79
+ static inline void
80
+ evoasm_buf_ref_write8(evoasm_buf_ref_t *buf_ref, int64_t datum) {
81
+ size_t pos = *buf_ref->pos;
82
+ size_t new_pos = pos + 1;
83
+ *((uint8_t *)(buf_ref->data + pos)) = (uint8_t) datum;
84
+ *buf_ref->pos = new_pos;
85
+ }
86
+
87
+ static inline void
88
+ evoasm_buf_ref_write16(evoasm_buf_ref_t *buf_ref, int64_t datum) {
89
+ size_t pos = *buf_ref->pos;
90
+ size_t new_pos = pos + 2;
91
+ *((int16_t *)(buf_ref->data + pos)) = (int16_t) datum;
92
+ *buf_ref->pos = new_pos;
93
+ }
94
+
95
+ static inline void
96
+ evoasm_buf_ref_write32(evoasm_buf_ref_t *buf_ref, int64_t datum) {
97
+ size_t pos = *buf_ref->pos;
98
+ size_t new_pos = pos + 4;
99
+ *((int32_t *)(buf_ref->data + pos)) = (int32_t) datum;
100
+ *buf_ref->pos = new_pos;
101
+ }
102
+
103
+ static inline void
104
+ evoasm_buf_ref_write64(evoasm_buf_ref_t *buf_ref, int64_t datum) {
105
+ size_t pos = *buf_ref->pos;
106
+ size_t new_pos = pos + 8;
107
+ *((int64_t *)(buf_ref->data + pos)) = (int64_t) datum;
108
+ *buf_ref->pos = new_pos;
109
+ }
@@ -0,0 +1,124 @@
1
+ /*
2
+ * Copyright (C) 2016 Julian Aron Prenner <jap@polyadic.com>
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify
5
+ * it under the terms of the GNU Affero General Public License as published by
6
+ * the Free Software Foundation, either version 3 of the License, or
7
+ * (at your option) any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ * GNU Affero General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU Affero General Public License
15
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ */
17
+
18
+ #include <stdint.h>
19
+ #include <stdio.h>
20
+ #include <inttypes.h>
21
+
22
+ #include "evoasm-domain.h"
23
+ #include "evoasm-alloc.h"
24
+ #include "evoasm-param.h"
25
+
26
+ EVOASM_DEF_LOG_TAG("domain")
27
+
28
+ void
29
+ evoasm_domain_log(evoasm_domain_t *domain, evoasm_log_level_t log_level) {
30
+ switch(domain->type) {
31
+ case EVOASM_DOMAIN_TYPE_ENUM: {
32
+ evoasm_enum_domain_t *enum_domain = (evoasm_enum_domain_t *) domain;
33
+ evoasm_log(log_level, EVOASM_LOG_TAG, "Evoasm::Enum%d( ", enum_domain->len);
34
+ for(size_t i = 0; i < enum_domain->len; i++) {
35
+ evoasm_log(log_level, EVOASM_LOG_TAG, " %" PRId64 " ", enum_domain->vals[i]);
36
+ }
37
+ evoasm_log(log_level, EVOASM_LOG_TAG, " )");
38
+ break;
39
+ }
40
+ case EVOASM_DOMAIN_TYPE_RANGE: {
41
+ evoasm_range_domain_t *interval = (evoasm_range_domain_t *) domain;
42
+ evoasm_log(log_level, EVOASM_LOG_TAG, "Evoasm::Interval(%" PRId64 "..%" PRId64 ")", interval->min, interval->max);
43
+ break;
44
+ }
45
+ case EVOASM_DOMAIN_TYPE_INT64:
46
+ evoasm_log(log_level, EVOASM_LOG_TAG, "Evoasm::Interval(INT64_MIN..INT64_MAX)");
47
+ break;
48
+ default:
49
+ evoasm_log(log_level, EVOASM_LOG_TAG, "Evoasm::Domain INVALID");
50
+ }
51
+ }
52
+
53
+
54
+ void
55
+ evoasm_domain_get_bounds(evoasm_domain_t *domain, int64_t *min, int64_t *max) {
56
+ evoasm_domain_get_bounds_(domain, min, max);
57
+ }
58
+
59
+ evoasm_domain_type_t
60
+ evoasm_domain_get_type(evoasm_domain_t *domain) {
61
+ return (evoasm_domain_type_t) domain->type;
62
+ }
63
+
64
+ size_t
65
+ evoasm_enum_domain_get_len(evoasm_enum_domain_t *enum_domain) {
66
+ return enum_domain->len;
67
+ }
68
+
69
+ int64_t
70
+ evoasm_enum_domain_get_val(evoasm_enum_domain_t *enum_domain, size_t idx) {
71
+ return enum_domain->vals[idx];
72
+ }
73
+
74
+ int64_t
75
+ evoasm_domain_rand(evoasm_domain_t *domain, evoasm_prng_t *prng) {
76
+ return evoasm_domain_rand_(domain, prng);
77
+ }
78
+
79
+ EVOASM_DEF_ALLOC_FREE_FUNCS(domain)
80
+
81
+ evoasm_success_t
82
+ evoasm_domain_init(evoasm_domain_t *domain, evoasm_domain_type_t type, ...) {
83
+ va_list args;
84
+ va_start(args, type);
85
+
86
+ domain->type = type;
87
+
88
+ switch(type) {
89
+ case EVOASM_DOMAIN_TYPE_ENUM: {
90
+ evoasm_enum_domain_t *enum_domain = (evoasm_enum_domain_t *) domain;
91
+ size_t len = va_arg(args, size_t);
92
+ enum_domain->len = (uint16_t) len;
93
+
94
+ if(len > EVOASM_ENUM_DOMAIN_LEN_MAX) {
95
+ evoasm_error(EVOASM_ERROR_TYPE_NONE, EVOASM_ERROR_CODE_NONE,
96
+ "Exceeded maximum enumeration domain length (%d > %d)",
97
+ enum_domain->len, EVOASM_ENUM_DOMAIN_LEN_MAX);
98
+ return false;
99
+ }
100
+
101
+ for(size_t i = 0; i < len; i++) {
102
+ enum_domain->vals[i] = va_arg(args, int64_t);
103
+ }
104
+ break;
105
+ }
106
+ case EVOASM_DOMAIN_TYPE_RANGE: {
107
+ evoasm_range_domain_t *range_domain = (evoasm_range_domain_t *) domain;
108
+ range_domain->min = va_arg(args, int64_t);
109
+ range_domain->max = va_arg(args, int64_t);
110
+ break;
111
+ }
112
+ case EVOASM_DOMAIN_TYPE_INT64:
113
+ case EVOASM_DOMAIN_TYPE_INT32:
114
+ case EVOASM_DOMAIN_TYPE_INT16:
115
+ case EVOASM_DOMAIN_TYPE_INT8:
116
+ break;
117
+ default:
118
+ evoasm_assert_not_reached();
119
+
120
+ }
121
+ va_end(args);
122
+
123
+ return true;
124
+ }
@@ -0,0 +1,279 @@
1
+ /*
2
+ * Copyright (C) 2016 Julian Aron Prenner <jap@polyadic.com>
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify
5
+ * it under the terms of the GNU Affero General Public License as published by
6
+ * the Free Software Foundation, either version 3 of the License, or
7
+ * (at your option) any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ * GNU Affero General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU Affero General Public License
15
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ */
17
+
18
+ #pragma once
19
+
20
+ #include "evoasm-rand.h"
21
+
22
+ #define EVOASM_DECL_ENUM_DOMAIN_TYPE(l) \
23
+ typedef struct { \
24
+ uint8_t type; \
25
+ uint16_t len; \
26
+ int64_t vals[l]; \
27
+ } evoasm_enum ## l ## _domain_t;
28
+
29
+ #define EVOASM_ENUM_DOMAIN_VALS_SIZE(len) ((size_t)(len) * sizeof(int64_t))
30
+ #define EVOASM_ENUM_DOMAIN_SIZE(len) (sizeof(evoasm_enum_domain_t) + EVOASM_ENUM_DOMAIN_VALS_SIZE(len))
31
+
32
+ typedef enum {
33
+ EVOASM_DOMAIN_TYPE_ENUM,
34
+ EVOASM_DOMAIN_TYPE_RANGE,
35
+ EVOASM_DOMAIN_TYPE_INT64,
36
+ EVOASM_DOMAIN_TYPE_INT32,
37
+ EVOASM_DOMAIN_TYPE_INT16,
38
+ EVOASM_DOMAIN_TYPE_INT8,
39
+ EVOASM_DOMAIN_TYPE_NONE
40
+ } evoasm_domain_type_t;
41
+
42
+ typedef struct {
43
+ uint8_t type;
44
+ } evoasm_int64_domain_t;
45
+
46
+ typedef evoasm_int64_domain_t evoasm_int32_domain_t;
47
+ typedef evoasm_int64_domain_t evoasm_int16_domain_t;
48
+ typedef evoasm_int64_domain_t evoasm_int8_domain_t;
49
+
50
+ typedef struct {
51
+ uint8_t type;
52
+ int64_t min;
53
+ int64_t max;
54
+ } evoasm_range_domain_t;
55
+
56
+ typedef struct {
57
+ uint8_t type;
58
+ uint16_t len;
59
+ int64_t vals[];
60
+ } evoasm_enum_domain_t;
61
+
62
+ EVOASM_DECL_ENUM_DOMAIN_TYPE(2)
63
+ EVOASM_DECL_ENUM_DOMAIN_TYPE(3)
64
+ EVOASM_DECL_ENUM_DOMAIN_TYPE(4)
65
+ EVOASM_DECL_ENUM_DOMAIN_TYPE(8)
66
+ EVOASM_DECL_ENUM_DOMAIN_TYPE(11)
67
+ EVOASM_DECL_ENUM_DOMAIN_TYPE(16)
68
+
69
+ #define EVOASM_ENUM_DOMAIN_LEN_MAX 16
70
+
71
+ /* evoasm_domain_t must be as large
72
+ * as biggest enum
73
+ */
74
+ typedef evoasm_enum16_domain_t evoasm_domain_t;
75
+
76
+ static inline int64_t
77
+ evoasm_domain_rand_(evoasm_domain_t *domain, evoasm_prng_t *prng) {
78
+ switch(domain->type) {
79
+ case EVOASM_DOMAIN_TYPE_RANGE: {
80
+ evoasm_range_domain_t *range_domain = (evoasm_range_domain_t *) domain;
81
+ return evoasm_prng_rand_between_(prng, range_domain->min, range_domain->max);
82
+ }
83
+ case EVOASM_DOMAIN_TYPE_INT64: {
84
+ return (int64_t) evoasm_prng_rand64_(prng);
85
+ }
86
+ case EVOASM_DOMAIN_TYPE_INT32: {
87
+ return (int32_t) evoasm_prng_rand32_(prng);
88
+ }
89
+ case EVOASM_DOMAIN_TYPE_INT16: {
90
+ return (int16_t) evoasm_prng_rand16_(prng);
91
+ }
92
+ case EVOASM_DOMAIN_TYPE_INT8: {
93
+ return (int8_t) evoasm_prng_rand8_(prng);
94
+ }
95
+ case EVOASM_DOMAIN_TYPE_ENUM: {
96
+ evoasm_enum_domain_t *enm = (evoasm_enum_domain_t *) domain;
97
+ return enm->vals[evoasm_prng_rand64_(prng) % enm->len];
98
+ }
99
+ default:
100
+ evoasm_assert_not_reached();
101
+ return 0;
102
+ }
103
+ }
104
+
105
+ static inline void
106
+ evoasm_domain_clone(evoasm_domain_t *restrict domain, evoasm_domain_t *restrict domain_dst) {
107
+ domain_dst->type = domain->type;
108
+
109
+ switch(domain->type) {
110
+ case EVOASM_DOMAIN_TYPE_RANGE: {
111
+ evoasm_range_domain_t *interval = (evoasm_range_domain_t *) domain;
112
+ evoasm_range_domain_t *interval_dst = (evoasm_range_domain_t *) domain_dst;
113
+ interval_dst->min = interval->min;
114
+ interval_dst->max = interval->max;
115
+ break;
116
+ }
117
+ case EVOASM_DOMAIN_TYPE_INT64:
118
+ case EVOASM_DOMAIN_TYPE_INT32:
119
+ case EVOASM_DOMAIN_TYPE_INT16:
120
+ case EVOASM_DOMAIN_TYPE_INT8:
121
+ break;
122
+ case EVOASM_DOMAIN_TYPE_ENUM: {
123
+ evoasm_enum_domain_t *enm = (evoasm_enum_domain_t *) domain;
124
+ evoasm_enum_domain_t *enm_dst = (evoasm_enum_domain_t *) domain_dst;
125
+ enm_dst->len = enm->len;
126
+ memcpy(enm_dst->vals, enm->vals, EVOASM_ENUM_DOMAIN_VALS_SIZE(enm->len));
127
+ break;
128
+ }
129
+ default:
130
+ evoasm_assert_not_reached();
131
+ }
132
+ }
133
+
134
+ static inline void
135
+ evoasm_domain_get_bounds_(evoasm_domain_t *domain, int64_t *min, int64_t *max) {
136
+ switch(domain->type) {
137
+ case EVOASM_DOMAIN_TYPE_ENUM: {
138
+ evoasm_enum_domain_t *enum_domain = (evoasm_enum_domain_t *) domain;
139
+ *min = enum_domain->vals[0];
140
+ *max = enum_domain->vals[enum_domain->len];
141
+ break;
142
+ }
143
+ case EVOASM_DOMAIN_TYPE_RANGE: {
144
+ evoasm_range_domain_t *range_domain = (evoasm_range_domain_t *) domain;
145
+ *min = range_domain->min;
146
+ *max = range_domain->max;
147
+ break;
148
+ }
149
+ case EVOASM_DOMAIN_TYPE_INT8: {
150
+ *min = INT8_MIN;
151
+ *max = INT8_MAX;
152
+ break;
153
+ }
154
+ case EVOASM_DOMAIN_TYPE_INT16: {
155
+ *min = INT16_MIN;
156
+ *max = INT16_MAX;
157
+ break;
158
+ }
159
+ case EVOASM_DOMAIN_TYPE_INT32: {
160
+ *min = INT32_MIN;
161
+ *max = INT32_MAX;
162
+ break;
163
+ }
164
+ case EVOASM_DOMAIN_TYPE_INT64: {
165
+ *min = INT64_MIN;
166
+ *max = INT64_MAX;
167
+ break;
168
+ }
169
+ default:
170
+ evoasm_assert_not_reached();
171
+ }
172
+ }
173
+
174
+ static inline void
175
+ evoasm_domain_intersect(evoasm_domain_t *restrict domain1, evoasm_domain_t *restrict domain2,
176
+ evoasm_domain_t *restrict domain_dst) {
177
+
178
+ if(domain1->type == EVOASM_DOMAIN_TYPE_ENUM && domain2->type == EVOASM_DOMAIN_TYPE_ENUM) {
179
+ size_t i = 0, j = 0;
180
+ evoasm_enum_domain_t *enum1 = (evoasm_enum_domain_t *) domain1;
181
+ evoasm_enum_domain_t *enum2 = (evoasm_enum_domain_t *) domain2;
182
+ evoasm_enum_domain_t *enum_dst = (evoasm_enum_domain_t *) domain_dst;
183
+
184
+ enum_dst->len = 0;
185
+ /*
186
+ * NOTE: vals are sorted (INC)
187
+ */
188
+
189
+ while(i < enum1->len && j < enum2->len) {
190
+ int64_t v1 = enum1->vals[i];
191
+ int64_t v2 = enum2->vals[j];
192
+
193
+ if(v1 < v2) {
194
+ i++;
195
+ } else if(v2 < v1) {
196
+ j++;
197
+ } else {
198
+ enum_dst->vals[enum_dst->len++] = v1;
199
+ i++;
200
+ j++;
201
+ }
202
+ }
203
+
204
+ return;
205
+ }
206
+
207
+ if(domain2->type == EVOASM_DOMAIN_TYPE_ENUM) {
208
+ evoasm_domain_t *temp_domain = domain1;
209
+ domain1 = domain2;
210
+ domain2 = temp_domain;
211
+ }
212
+
213
+ int64_t min1, max1, min2, max2;
214
+
215
+ evoasm_domain_get_bounds_(domain2, &min2, &max2);
216
+
217
+ if(domain1->type == EVOASM_DOMAIN_TYPE_ENUM) {
218
+ size_t i;
219
+ evoasm_enum_domain_t *enum_domain_dst = (evoasm_enum_domain_t *) domain_dst;
220
+ evoasm_enum_domain_t *enum_domain1 = (evoasm_enum_domain_t *) domain1;
221
+
222
+ enum_domain_dst->len = 0;
223
+ for(i = 0; i < enum_domain1->len; i++) {
224
+ if(enum_domain1->vals[i] >= min2 && enum_domain1->vals[i] <= max2) {
225
+ enum_domain_dst->vals[enum_domain_dst->len++] = enum_domain1->vals[i];
226
+ }
227
+ }
228
+ } else {
229
+ evoasm_range_domain_t *range_domain_dst = (evoasm_range_domain_t *) domain_dst;
230
+
231
+ evoasm_domain_get_bounds_(domain1, &min1, &max1);
232
+ range_domain_dst->min = EVOASM_MAX(min1, min2);
233
+ range_domain_dst->max = EVOASM_MIN(max1, max2);
234
+ }
235
+ }
236
+
237
+ static inline bool
238
+ evoasm_domain_contains(evoasm_domain_t *domain, int64_t val) {
239
+ switch(domain->type) {
240
+ case EVOASM_DOMAIN_TYPE_RANGE: {
241
+ evoasm_range_domain_t *interval = (evoasm_range_domain_t *) domain;
242
+ return val >= interval->min && val <= interval->max;
243
+ }
244
+ case EVOASM_DOMAIN_TYPE_ENUM: {
245
+ size_t i;
246
+ evoasm_enum_domain_t *enm = (evoasm_enum_domain_t *) domain;
247
+ for(i = 0; i < enm->len; i++) {
248
+ if(enm->vals[i] == val) return true;
249
+ }
250
+ return false;
251
+ }
252
+ default:
253
+ evoasm_assert_not_reached();
254
+ return false;
255
+ }
256
+ }
257
+
258
+ static inline bool
259
+ evoasm_domain_is_empty(evoasm_domain_t *domain) {
260
+ switch(domain->type) {
261
+ case EVOASM_DOMAIN_TYPE_ENUM:
262
+ return ((evoasm_enum_domain_t *) domain)->len == 0;
263
+ case EVOASM_DOMAIN_TYPE_RANGE: {
264
+ evoasm_range_domain_t *interval = (evoasm_range_domain_t *) domain;
265
+ return interval->min >= interval->max;
266
+ }
267
+ case EVOASM_DOMAIN_TYPE_INT64:
268
+ case EVOASM_DOMAIN_TYPE_INT32:
269
+ case EVOASM_DOMAIN_TYPE_INT16:
270
+ case EVOASM_DOMAIN_TYPE_INT8:
271
+ return false;
272
+ default:
273
+ evoasm_assert_not_reached();
274
+ }
275
+ return false;
276
+ }
277
+
278
+ void
279
+ evoasm_domain_log(evoasm_domain_t *domain, evoasm_log_level_t log_level);