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.
- checksums.yaml +4 -4
- data/.gdbinit +41 -0
- data/.gitignore +1 -2
- data/.gitmodules +3 -0
- data/.rubocop.yml +8 -0
- data/Gemfile +4 -0
- data/LICENSE.md +660 -0
- data/Makefile +1 -1
- data/README.md +17 -9
- data/Rakefile +39 -107
- data/bin/gdb +1 -1
- data/bin/gdb_loop +4 -0
- data/docs/FindingInstructions.md +17 -0
- data/docs/JIT.md +14 -0
- data/docs/SymbolicRegression.md +102 -0
- data/docs/Visualization.md +29 -0
- data/docs/examples/bit_insts.rb +44 -0
- data/docs/examples/jit.rb +26 -0
- data/docs/examples/loss.gif +0 -0
- data/docs/examples/program.png +0 -0
- data/docs/examples/sym_reg.rb +64 -0
- data/docs/examples/vis.rb +38 -0
- data/evoasm.gemspec +21 -15
- data/ext/evoasm_ext/Rakefile +3 -0
- data/ext/evoasm_ext/compile.rake +35 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-alloc.c +226 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-alloc.h +84 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-arch.c +52 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-arch.h +101 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-bitmap.h +158 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-buf.c +204 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-buf.h +109 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-domain.c +124 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-domain.h +279 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-error.c +65 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-error.h +108 -0
- data/ext/evoasm_ext/{evoasm-log.c → libevoasm/src/evoasm-log.c} +36 -18
- data/ext/evoasm_ext/libevoasm/src/evoasm-log.h +93 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-param.c +22 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-param.h +33 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-pop-params.c +192 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-pop-params.h +60 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-pop.c +1323 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-pop.h +107 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-program-io.c +116 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-program-io.h +60 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-program.c +1827 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-program.h +167 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-rand.c +65 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-rand.h +76 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-signal.c +106 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-signal.h +58 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-util.h +112 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-x64.c +925 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-x64.h +277 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm.c +28 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm.h +35 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-enums.h +2077 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-insts.c +191203 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-insts.h +1713 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-misc.c +348 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-misc.h +93 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-params.c +51 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-params.h +509 -0
- data/lib/evoasm.rb +28 -11
- data/lib/evoasm/buffer.rb +105 -0
- data/lib/evoasm/capstone.rb +100 -0
- data/lib/evoasm/domain.rb +116 -0
- data/lib/evoasm/error.rb +37 -16
- data/lib/evoasm/exception_error.rb +19 -0
- data/lib/evoasm/ffi_ext.rb +53 -0
- data/lib/evoasm/libevoasm.rb +286 -0
- data/lib/evoasm/libevoasm/x64_enums.rb +1967 -0
- data/lib/evoasm/parameter.rb +20 -0
- data/lib/evoasm/population.rb +145 -0
- data/lib/evoasm/population/parameters.rb +227 -0
- data/lib/evoasm/population/plotter.rb +89 -0
- data/lib/evoasm/prng.rb +64 -0
- data/lib/evoasm/program.rb +195 -12
- data/lib/evoasm/program/io.rb +144 -0
- data/lib/evoasm/test.rb +8 -0
- data/lib/evoasm/version.rb +1 -1
- data/lib/evoasm/x64.rb +115 -0
- data/lib/evoasm/x64/cpu_state.rb +95 -0
- data/lib/evoasm/x64/instruction.rb +109 -0
- data/lib/evoasm/x64/operand.rb +156 -0
- data/lib/evoasm/x64/parameters.rb +211 -0
- data/test/helpers/population_helper.rb +128 -0
- data/test/helpers/test_helper.rb +1 -0
- data/test/helpers/x64_helper.rb +24 -0
- data/test/integration/bitwise_reverse_test.rb +41 -0
- data/test/integration/gcd_test.rb +52 -0
- data/test/integration/popcnt_test.rb +46 -0
- data/test/integration/sym_reg_test.rb +68 -0
- data/test/unit/evoasm/buffer_test.rb +48 -0
- data/test/unit/evoasm/capstone_test.rb +18 -0
- data/test/unit/evoasm/domain_test.rb +55 -0
- data/test/unit/evoasm/population/parameters_test.rb +106 -0
- data/test/unit/evoasm/population_test.rb +96 -0
- data/test/unit/evoasm/prng_test.rb +47 -0
- data/test/unit/evoasm/x64/cpu_state_test.rb +73 -0
- data/test/unit/evoasm/x64/encoding_test.rb +320 -0
- data/test/unit/evoasm/x64/instruction_access_test.rb +177 -0
- data/test/unit/evoasm/x64/instruction_encoding_test.rb +780 -0
- data/test/unit/evoasm/x64/instruction_test.rb +62 -0
- data/test/unit/evoasm/x64/parameters_test.rb +65 -0
- data/test/unit/evoasm/x64_test.rb +52 -0
- metadata +195 -89
- data/Gemfile.rake +0 -8
- data/Gemfile.rake.lock +0 -51
- data/LICENSE.txt +0 -373
- data/data/tables/README.md +0 -19
- data/data/tables/x64.csv +0 -1684
- data/data/templates/evoasm-x64.c.erb +0 -319
- data/data/templates/evoasm-x64.h.erb +0 -126
- data/examples/abs.yml +0 -20
- data/examples/popcnt.yml +0 -17
- data/examples/sym_reg.yml +0 -26
- data/exe/evoasm-search +0 -13
- data/ext/evoasm_ext/evoasm-alloc.c +0 -145
- data/ext/evoasm_ext/evoasm-alloc.h +0 -59
- data/ext/evoasm_ext/evoasm-arch.c +0 -44
- data/ext/evoasm_ext/evoasm-arch.h +0 -161
- data/ext/evoasm_ext/evoasm-bitmap.h +0 -114
- data/ext/evoasm_ext/evoasm-buf.c +0 -130
- data/ext/evoasm_ext/evoasm-buf.h +0 -47
- data/ext/evoasm_ext/evoasm-error.c +0 -31
- data/ext/evoasm_ext/evoasm-error.h +0 -75
- data/ext/evoasm_ext/evoasm-free-list.c.tmpl +0 -121
- data/ext/evoasm_ext/evoasm-free-list.h.tmpl +0 -86
- data/ext/evoasm_ext/evoasm-log.h +0 -69
- data/ext/evoasm_ext/evoasm-misc.c +0 -23
- data/ext/evoasm_ext/evoasm-misc.h +0 -282
- data/ext/evoasm_ext/evoasm-param.h +0 -37
- data/ext/evoasm_ext/evoasm-search.c +0 -2145
- data/ext/evoasm_ext/evoasm-search.h +0 -214
- data/ext/evoasm_ext/evoasm-util.h +0 -40
- data/ext/evoasm_ext/evoasm-x64.c +0 -275624
- data/ext/evoasm_ext/evoasm-x64.h +0 -5436
- data/ext/evoasm_ext/evoasm.c +0 -7
- data/ext/evoasm_ext/evoasm.h +0 -23
- data/ext/evoasm_ext/evoasm_ext.c +0 -1757
- data/ext/evoasm_ext/extconf.rb +0 -31
- data/lib/evoasm/cli.rb +0 -6
- data/lib/evoasm/cli/search.rb +0 -127
- data/lib/evoasm/core_ext.rb +0 -1
- data/lib/evoasm/core_ext/array.rb +0 -9
- data/lib/evoasm/core_ext/integer.rb +0 -10
- data/lib/evoasm/core_ext/kwstruct.rb +0 -13
- data/lib/evoasm/core_ext/range.rb +0 -5
- data/lib/evoasm/examples.rb +0 -27
- data/lib/evoasm/gen.rb +0 -8
- data/lib/evoasm/gen/enum.rb +0 -169
- data/lib/evoasm/gen/name_util.rb +0 -80
- data/lib/evoasm/gen/state.rb +0 -176
- data/lib/evoasm/gen/state_dsl.rb +0 -152
- data/lib/evoasm/gen/strio.rb +0 -27
- data/lib/evoasm/gen/translator.rb +0 -1102
- data/lib/evoasm/gen/version.rb +0 -5
- data/lib/evoasm/gen/x64.rb +0 -237
- data/lib/evoasm/gen/x64/funcs.rb +0 -495
- data/lib/evoasm/gen/x64/inst.rb +0 -781
- data/lib/evoasm/search.rb +0 -40
- data/lib/evoasm/tasks/gen_task.rb +0 -86
- data/lib/evoasm/tasks/template_task.rb +0 -52
- data/test/test_helper.rb +0 -1
- data/test/x64/test_helper.rb +0 -19
- 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);
|