evoasm 0.0.2.pre7 → 0.1.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
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,112 @@
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
+ #define EVOASM_MAX(a,b) (((a) > (b)) ? (a) : (b))
21
+ #define EVOASM_MIN(a,b) (((a) < (b)) ? (a) : (b))
22
+ #define EVOASM_CLAMP(x, min, max) (((x) > (max)) ? (max) : (((x) < (min)) ? (min) : (x)))
23
+
24
+ #define EVOASM_ALIGN_DOWN(s, a) ((s) &~ ((a) - 1))
25
+ #define EVOASM_ALIGN_UP(s, a) EVOASM_ALIGN_DOWN(((s) + (a) - 1), a)
26
+
27
+ #define EVOASM_ARY_LEN(ary) (sizeof(ary) / sizeof(ary[0]))
28
+
29
+ #ifdef __GNUC__
30
+ # define evoasm_unlikely(e) (__builtin_expect(e, 0))
31
+ # define evoasm_likely(e) (__builtin_expect(e, 1))
32
+ # define evoasm_used __attribute__((used))
33
+ # define evoasm_printf(x, y) __attribute__((__format__(__printf__, x, y)))
34
+ #else
35
+ # define evoasm_unlikely(e) (e)
36
+ # define evoasm_likely(e) (e)
37
+ # define evoasm_used
38
+ # define evoasm_printf
39
+ #endif
40
+
41
+ #if defined(__GNUC__)
42
+ # define evoasm_check_return __attribute__((warn_unused_result))
43
+ # define evoasm_force_inline __attribute__((always_inline))
44
+ # define evoasm_packed(decl) decl __attribute__((__packed__))
45
+ # define evoasm_aligned(align) __attribute__ ((aligned(align)))
46
+ #elif defined(_MSC_VER)
47
+ # define evoasm_check_return _Check_return_
48
+ # define evoasm_force_inline __forceinline
49
+ # define evoasm_packed(decl) __pragma(pack(push, 1)) decl __pragma(pack(pop))
50
+ # define evoasm_aligned(align) __declspec(align(align))
51
+ #else
52
+ # define evoasm_check_return
53
+ # define evoasm_force_inline
54
+ # define evoasm_packed(decl)
55
+ # define evoasm_aligned(align)
56
+ #endif
57
+
58
+ #define EVOASM_MEMCPY_N(dst, src, n) memcpy(dst, src, (n) * sizeof(*(src)))
59
+ #define EVOASM_MEMSET_N(ptr, val, n) memset(ptr, val, (n) * sizeof(*(ptr)))
60
+
61
+ #define EVOASM_DEF_ALLOC_FUNC(type) \
62
+ evoasm_##type##_t *evoasm_##type##_alloc() { return evoasm_malloc(sizeof(evoasm_##type##_t)); }
63
+
64
+ #define EVOASM_DEF_FREE_FUNC(type) \
65
+ void evoasm_##type##_free(evoasm_##type##_t *ptr) { evoasm_free(ptr); }
66
+
67
+ #define EVOASM_DECL_ALLOC_FUNC(type) \
68
+ evoasm_##type##_t *evoasm_##type##_alloc();
69
+
70
+ #define EVOASM_DECL_FREE_FUNC(type) \
71
+ void evoasm_##type##_free(evoasm_##type##_t *ptr);
72
+
73
+ #define EVOASM_DEF_ALLOC_FREE_FUNCS(type) \
74
+ EVOASM_DEF_ALLOC_FUNC(type) \
75
+ EVOASM_DEF_FREE_FUNC(type) \
76
+
77
+ #define EVOASM_DECL_ALLOC_FREE_FUNCS(type) \
78
+ EVOASM_DECL_ALLOC_FUNC(type) \
79
+ EVOASM_DECL_FREE_FUNC(type) \
80
+
81
+ #define EVOASM_DEF_ZERO_INIT_FUNC(type) \
82
+ void evoasm_##type##_init(evoasm_##type##_t *ptr) {\
83
+ static evoasm_##type##_t zero = {0}; \
84
+ *ptr = zero; \
85
+ }
86
+
87
+ #define EVOASM_DEF_EMPTY_DESTROY_FUNC(type) \
88
+ void evoasm_##type##_destroy(evoasm_##type##_t *ptr) {}
89
+
90
+ #define EVOASM_DEF_GETTER(type, field, value_type) \
91
+ value_type evoasm_##type##_get_##field(evoasm_##type##_t *ptr) { \
92
+ return (value_type) ptr->field; \
93
+ }
94
+
95
+ #define EVOASM_DEF_BOOL_GETTER(type, field) \
96
+ bool evoasm_##type##_is_##field(evoasm_##type##_t *ptr) { \
97
+ return ptr->field; \
98
+ }
99
+
100
+ #define EVOASM_DEF_SETTER(type, field, value_type, field_type) \
101
+ void evoasm_##type##_set_##field(evoasm_##type##_t *ptr, value_type value) { \
102
+ ptr->field = (field_type) value; \
103
+ }
104
+
105
+ #define EVOASM_SWAP(type, a, b) do { type s = (a); (a) = (b); (b) = s;} while (0)
106
+
107
+ #if defined(__linux__) || defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
108
+ #define EVOASM_UNIX
109
+ #endif
110
+
111
+ #define EVOASM_CB_CONTINUE true
112
+ #define EVOASM_CB_STOP false
@@ -0,0 +1,925 @@
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 "evoasm-x64.h"
19
+ #include "evoasm.h"
20
+ #include "evoasm-signal.h"
21
+
22
+ EVOASM_DEF_LOG_TAG("x64")
23
+
24
+ uint8_t evoasm_x64_reg_type_sizes[EVOASM_X64_REG_TYPE_NONE] = {0};
25
+
26
+ static evoasm_x64_reg_id_t evoasm_x64_sysv_callee_save_regs[] = {
27
+ EVOASM_X64_REG_BP,
28
+ EVOASM_X64_REG_B,
29
+ EVOASM_X64_REG_12,
30
+ EVOASM_X64_REG_13,
31
+ EVOASM_X64_REG_14,
32
+ EVOASM_X64_REG_15,
33
+ };
34
+
35
+ static evoasm_success_t
36
+ evoasm_x64_func_emit_prolog_or_epilog(evoasm_x64_abi_t abi, evoasm_buf_t *buf, bool prolog) {
37
+ size_t regs_len = EVOASM_ARY_LEN(evoasm_x64_sysv_callee_save_regs);
38
+ evoasm_x64_params_t params = {0};
39
+
40
+ for(size_t i = 0; i < regs_len; i++) {
41
+ evoasm_x64_reg_id_t reg = evoasm_x64_sysv_callee_save_regs[prolog ? i : (regs_len - 1 - i)];
42
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG0, reg);
43
+
44
+ if(prolog) {
45
+ EVOASM_X64_ENC(push_r64);
46
+ } else {
47
+ EVOASM_X64_ENC(pop_r64);
48
+ }
49
+ }
50
+
51
+ if(!prolog) {
52
+ EVOASM_X64_ENC(ret);
53
+ }
54
+
55
+ return true;
56
+
57
+ enc_failed:
58
+ return false;
59
+ }
60
+
61
+ evoasm_success_t
62
+ evoasm_x64_emit_func_prolog(evoasm_x64_abi_t abi, evoasm_buf_t *buf) {
63
+ return evoasm_x64_func_emit_prolog_or_epilog(abi, buf, true);
64
+ }
65
+
66
+ evoasm_success_t
67
+ evoasm_x64_emit_func_epilog(evoasm_x64_abi_t abi, evoasm_buf_t *buf) {
68
+ return evoasm_x64_func_emit_prolog_or_epilog(abi, buf, false);
69
+ }
70
+
71
+ evoasm_success_t
72
+ evoasm_x64_init() {
73
+ extern evoasm_arch_info_t _evoasm_arch_infos[EVOASM_ARCH_NONE];
74
+ extern evoasm_arch_id_t _evoasm_current_arch;
75
+ uint64_t features;
76
+ EVOASM_TRY(cpuid_failed, evoasm_x64_get_features, &features);
77
+
78
+ evoasm_x64_reg_type_sizes[EVOASM_X64_REG_TYPE_GP] = 8;
79
+ evoasm_x64_reg_type_sizes[EVOASM_X64_REG_TYPE_RFLAGS] = 8;
80
+ evoasm_x64_reg_type_sizes[EVOASM_X64_REG_TYPE_IP] = 8;
81
+ evoasm_x64_reg_type_sizes[EVOASM_X64_REG_TYPE_MXCSR] = 4;
82
+
83
+ #ifdef EVOASM_X64_ENABLE_AVX512
84
+ uint64_t avx512 = EVOASM_X64_FEATURE_AVX512F |
85
+ EVOASM_X64_FEATURE_AVX512DQ |
86
+ EVOASM_X64_FEATURE_AVX512IFMA |
87
+ EVOASM_X64_FEATURE_AVX512PF |
88
+ EVOASM_X64_FEATURE_AVX512ER |
89
+ EVOASM_X64_FEATURE_AVX512CD |
90
+ EVOASM_X64_FEATURE_AVX512BW |
91
+ EVOASM_X64_FEATURE_AVX512VL;
92
+
93
+ if(x64->features & avx512) {
94
+ evoasm_x64_reg_type_sizes[EVOASM_X64_REG_TYPE_XMM] = 64;
95
+ evoasm_x64_reg_type_sizes[EVOASM_X64_REG_TYPE_ZMM] = 64;
96
+ }
97
+ else
98
+ #endif
99
+ if(features & EVOASM_X64_FEATURE_AVX2) {
100
+ evoasm_x64_reg_type_sizes[EVOASM_X64_REG_TYPE_XMM] = 32;
101
+ } else {
102
+ evoasm_x64_reg_type_sizes[EVOASM_X64_REG_TYPE_XMM] = 16;
103
+ }
104
+
105
+ _evoasm_arch_infos[EVOASM_ARCH_X64].features = features;
106
+ _evoasm_current_arch = EVOASM_ARCH_X64;
107
+
108
+ evoasm_signal_install();
109
+
110
+ return true;
111
+
112
+ cpuid_failed:
113
+ return false;
114
+ }
115
+
116
+ evoasm_x64_inst_t *
117
+ evoasm_x64_inst(evoasm_x64_inst_id_t inst_id) {
118
+ return evoasm_x64_inst_(inst_id);
119
+ }
120
+
121
+ evoasm_success_t
122
+ evoasm_x64_inst_enc(evoasm_x64_inst_t *inst, evoasm_x64_params_t *params, evoasm_buf_ref_t *buf_ref) {
123
+ return evoasm_x64_inst_enc_(inst, params, buf_ref);
124
+ }
125
+
126
+ evoasm_success_t
127
+ evoasm_x64_inst_enc_basic(evoasm_x64_inst_t *inst, evoasm_x64_basic_params_t *params, evoasm_buf_ref_t *buf_ref) {
128
+ return evoasm_x64_inst_enc_basic_(inst, params, buf_ref);
129
+ }
130
+
131
+ evoasm_success_t
132
+ evoasm_x64_enc(evoasm_x64_inst_id_t inst_id, evoasm_x64_params_t *params, evoasm_buf_ref_t *buf_ref) {
133
+ return evoasm_x64_enc_(inst_id, params, buf_ref);
134
+ }
135
+
136
+ evoasm_success_t
137
+ evoasm_x64_enc_basic(evoasm_x64_inst_id_t inst_id, evoasm_x64_basic_params_t *params, evoasm_buf_ref_t *buf_ref) {
138
+ return evoasm_x64_enc_basic_(inst_id, params, buf_ref);
139
+ }
140
+
141
+ evoasm_x64_operand_t *
142
+ evoasm_x64_inst_get_operand(evoasm_x64_inst_t *inst, size_t idx) {
143
+ return &inst->operands[idx];
144
+ }
145
+
146
+ size_t
147
+ evoasm_x64_inst_get_n_operands(evoasm_x64_inst_t *inst) {
148
+ return inst->n_operands;
149
+ }
150
+
151
+ #define EVOASM_X64_OPERAND_DEF_GETTER(field, type) EVOASM_DEF_GETTER(x64_operand, field, type)
152
+ #define EVOASM_X64_OPERAND_DEF_BOOL_GETTER(field) EVOASM_DEF_BOOL_GETTER(x64_operand, field)
153
+
154
+ EVOASM_X64_OPERAND_DEF_BOOL_GETTER(read)
155
+
156
+ EVOASM_X64_OPERAND_DEF_BOOL_GETTER(written)
157
+
158
+ EVOASM_X64_OPERAND_DEF_BOOL_GETTER(implicit)
159
+
160
+ EVOASM_X64_OPERAND_DEF_BOOL_GETTER(maybe_written)
161
+
162
+ EVOASM_X64_OPERAND_DEF_BOOL_GETTER(mnem)
163
+ EVOASM_X64_OPERAND_DEF_GETTER(word, evoasm_x64_operand_word_t)
164
+
165
+ EVOASM_X64_OPERAND_DEF_GETTER(type, evoasm_x64_operand_type_t)
166
+
167
+ EVOASM_X64_OPERAND_DEF_GETTER(reg_type, evoasm_x64_reg_type_t)
168
+
169
+ EVOASM_X64_OPERAND_DEF_GETTER(imm, int8_t)
170
+
171
+ EVOASM_X64_OPERAND_DEF_GETTER(param_idx, size_t)
172
+
173
+
174
+ evoasm_x64_reg_id_t
175
+ evoasm_x64_operand_get_reg_id(evoasm_x64_operand_t *operand) {
176
+ return evoasm_x64_operand_get_reg_id_(operand);
177
+ }
178
+
179
+ evoasm_x64_operand_size_t
180
+ evoasm_x64_operand_get_size(evoasm_x64_operand_t *operand) {
181
+ return (evoasm_x64_operand_size_t) operand->size;
182
+ }
183
+
184
+ evoasm_x64_operand_size_t
185
+ evoasm_x64_operand_get_reg_size(evoasm_x64_operand_t *operand) {
186
+ return evoasm_x64_operand_get_reg_size_(operand);
187
+ }
188
+
189
+ evoasm_x64_operand_size_t
190
+ evoasm_x64_operand_get_index_reg_size(evoasm_x64_operand_t *operand) {
191
+ return (evoasm_x64_operand_size_t) operand->size;
192
+ }
193
+
194
+ evoasm_x64_operand_size_t evoasm_x64_operand_get_mem_size(evoasm_x64_operand_t *operand) {
195
+ if(operand->type != EVOASM_X64_OPERAND_TYPE_MEM && operand->type != EVOASM_X64_OPERAND_TYPE_RM && operand->type != EVOASM_X64_OPERAND_TYPE_VSIB) {
196
+ return EVOASM_X64_OPERAND_SIZE_NONE;
197
+ }
198
+
199
+ switch(operand->word) {
200
+ case EVOASM_X64_OPERAND_WORD_LB:
201
+ case EVOASM_X64_OPERAND_WORD_HB:
202
+ return EVOASM_X64_OPERAND_SIZE_8;
203
+ case EVOASM_X64_OPERAND_WORD_W:
204
+ return EVOASM_X64_OPERAND_SIZE_16;
205
+ case EVOASM_X64_OPERAND_WORD_DW:
206
+ return EVOASM_X64_OPERAND_SIZE_32;
207
+ case EVOASM_X64_OPERAND_WORD_LQW:
208
+ case EVOASM_X64_OPERAND_WORD_HQW:
209
+ return EVOASM_X64_OPERAND_SIZE_64;
210
+ case EVOASM_X64_OPERAND_WORD_DQW:
211
+ return EVOASM_X64_OPERAND_SIZE_128;
212
+ case EVOASM_X64_OPERAND_WORD_VW:
213
+ switch(evoasm_x64_reg_type_sizes[EVOASM_X64_REG_TYPE_XMM]) {
214
+ case 16:
215
+ return EVOASM_X64_OPERAND_SIZE_128;
216
+ case 32:
217
+ return EVOASM_X64_OPERAND_SIZE_256;
218
+ case 64:
219
+ return EVOASM_X64_OPERAND_SIZE_512;
220
+ default:
221
+ evoasm_assert_not_reached();
222
+ }
223
+ default:
224
+ evoasm_assert_not_reached();
225
+ }
226
+ }
227
+
228
+ evoasm_param_t *
229
+ evoasm_x64_inst_get_param(evoasm_x64_inst_t *inst, size_t idx) {
230
+ return &inst->params[idx];
231
+ }
232
+
233
+ size_t
234
+ evoasm_x64_inst_get_n_params(evoasm_x64_inst_t *inst) {
235
+ return inst->n_params;
236
+ }
237
+
238
+ bool
239
+ evoasm_x64_inst_is_basic(evoasm_x64_inst_t *inst) {
240
+ return inst->basic_enc_func != NULL;
241
+ }
242
+
243
+ const char *
244
+ evoasm_x64_inst_get_mnem(evoasm_x64_inst_t *inst) {
245
+ return (const char *) inst->mnem;
246
+ }
247
+
248
+ void
249
+ evoasm_x64_params_init(evoasm_x64_params_t *params) {
250
+ static evoasm_x64_params_t zero_params = {0};
251
+ *params = zero_params;
252
+ }
253
+
254
+ void
255
+ evoasm_x64_basic_params_init(evoasm_x64_basic_params_t *params) {
256
+ static evoasm_x64_basic_params_t zero_params = {0};
257
+ *params = zero_params;
258
+ }
259
+
260
+ static bool
261
+ evoasm_x64_is_useful_inst(evoasm_x64_inst_id_t inst) {
262
+ switch(inst) {
263
+ case EVOASM_X64_INST_CRC32_R32_RM8:
264
+ case EVOASM_X64_INST_CRC32_R32_RM16:
265
+ case EVOASM_X64_INST_CRC32_R32_RM32:
266
+ case EVOASM_X64_INST_CRC32_R64_RM8:
267
+ case EVOASM_X64_INST_CRC32_R64_RM64:
268
+ case EVOASM_X64_INST_CPUID:
269
+ case EVOASM_X64_INST_RDRAND_R16:
270
+ case EVOASM_X64_INST_RDRAND_R32:
271
+ case EVOASM_X64_INST_RDRAND_R64:
272
+ case EVOASM_X64_INST_RDSEED_R16:
273
+ case EVOASM_X64_INST_RDSEED_R32:
274
+ case EVOASM_X64_INST_RDSEED_R64:
275
+ case EVOASM_X64_INST_AESDEC_XMM_XMMM128:
276
+ case EVOASM_X64_INST_AESDECLAST_XMM_XMMM128:
277
+ case EVOASM_X64_INST_AESENC_XMM_XMMM128:
278
+ case EVOASM_X64_INST_AESENCLAST_XMM_XMMM128:
279
+ case EVOASM_X64_INST_AESIMC_XMM_XMMM128:
280
+ case EVOASM_X64_INST_AESKEYGENASSIST_XMM_XMMM128_IMM8:
281
+ case EVOASM_X64_INST_LOOP_REL8:
282
+ case EVOASM_X64_INST_LOOPE_REL8:
283
+ case EVOASM_X64_INST_LOOPNE_REL8:
284
+ return false;
285
+ default:
286
+ return true;
287
+ }
288
+ }
289
+
290
+ size_t
291
+ evoasm_x64_insts(uint64_t flags, uint64_t features, uint64_t operand_types, uint64_t reg_types,
292
+ evoasm_x64_inst_id_t *insts) {
293
+ size_t len = 0;
294
+ bool include_useless = (flags & EVOASM_X64_INSTS_FLAG_INCLUDE_USELESS) != 0;
295
+ bool only_basic = (flags & EVOASM_X64_INSTS_FLAG_ONLY_BASIC) != 0;
296
+
297
+ for(size_t i = 0; i < EVOASM_X64_INST_NONE; i++) {
298
+ if(!include_useless && !evoasm_x64_is_useful_inst((evoasm_x64_inst_id_t) i)) goto skip;
299
+
300
+ evoasm_x64_inst_t *inst = (evoasm_x64_inst_t *) &EVOASM_X64_INSTS_VAR_NAME[i];
301
+ if(only_basic && !evoasm_x64_inst_is_basic(inst)) goto skip;
302
+
303
+ if((inst->features & ~features) != 0) goto skip;
304
+
305
+ if(!include_useless && inst->n_operands == 0) goto skip;
306
+
307
+ for(size_t j = 0; j < inst->n_operands; j++) {
308
+ evoasm_x64_operand_t *operand = &inst->operands[j];
309
+
310
+ if(((1ull << operand->type) & operand_types) == 0) goto skip;
311
+
312
+ if(operand->type == EVOASM_X64_OPERAND_TYPE_REG ||
313
+ operand->type == EVOASM_X64_OPERAND_TYPE_RM) {
314
+ if(!include_useless &&
315
+ (operand->reg_id == EVOASM_X64_REG_SP ||
316
+ operand->reg_id == EVOASM_X64_REG_IP))
317
+ goto skip;
318
+
319
+ if(((1ull << operand->reg_type) & reg_types) == 0) goto skip;
320
+ }
321
+ }
322
+
323
+ insts[len++] = (evoasm_x64_inst_id_t) i;
324
+ skip:;
325
+ }
326
+ return len;
327
+ }
328
+
329
+
330
+ static uint64_t *
331
+ evoasm_x64_cpu_state_get_reg_data(evoasm_x64_cpu_state_t *cpu_state, evoasm_x64_reg_id_t reg) {
332
+ switch(reg) {
333
+ case EVOASM_X64_REG_A:
334
+ return cpu_state->rax;
335
+ case EVOASM_X64_REG_C:
336
+ return cpu_state->rcx;
337
+ case EVOASM_X64_REG_D:
338
+ return cpu_state->rdx;
339
+ case EVOASM_X64_REG_B:
340
+ return cpu_state->rbx;
341
+ case EVOASM_X64_REG_SP:
342
+ return cpu_state->rsp;
343
+ case EVOASM_X64_REG_BP:
344
+ return cpu_state->rbp;
345
+ case EVOASM_X64_REG_SI:
346
+ return cpu_state->rsi;
347
+ case EVOASM_X64_REG_DI:
348
+ return cpu_state->rdi;
349
+ case EVOASM_X64_REG_8:
350
+ return cpu_state->r8;
351
+ case EVOASM_X64_REG_9:
352
+ return cpu_state->r9;
353
+ case EVOASM_X64_REG_10:
354
+ return cpu_state->r10;
355
+ case EVOASM_X64_REG_11:
356
+ return cpu_state->r11;
357
+ case EVOASM_X64_REG_12:
358
+ return cpu_state->r12;
359
+ case EVOASM_X64_REG_13:
360
+ return cpu_state->r13;
361
+ case EVOASM_X64_REG_14:
362
+ return cpu_state->r14;
363
+ case EVOASM_X64_REG_15:
364
+ return cpu_state->r15;
365
+ case EVOASM_X64_REG_MM0:
366
+ return cpu_state->mm0;
367
+ case EVOASM_X64_REG_MM1:
368
+ return cpu_state->mm1;
369
+ case EVOASM_X64_REG_MM2:
370
+ return cpu_state->mm2;
371
+ case EVOASM_X64_REG_MM3:
372
+ return cpu_state->mm3;
373
+ case EVOASM_X64_REG_MM4:
374
+ return cpu_state->mm4;
375
+ case EVOASM_X64_REG_MM5:
376
+ return cpu_state->mm5;
377
+ case EVOASM_X64_REG_MM6:
378
+ return cpu_state->mm6;
379
+ case EVOASM_X64_REG_MM7:
380
+ return cpu_state->mm7;
381
+ case EVOASM_X64_REG_XMM0:
382
+ return cpu_state->xmm0;
383
+ case EVOASM_X64_REG_XMM1:
384
+ return cpu_state->xmm1;
385
+ case EVOASM_X64_REG_XMM2:
386
+ return cpu_state->xmm2;
387
+ case EVOASM_X64_REG_XMM3:
388
+ return cpu_state->xmm3;
389
+ case EVOASM_X64_REG_XMM4:
390
+ return cpu_state->xmm4;
391
+ case EVOASM_X64_REG_XMM5:
392
+ return cpu_state->xmm5;
393
+ case EVOASM_X64_REG_XMM6:
394
+ return cpu_state->xmm6;
395
+ case EVOASM_X64_REG_XMM7:
396
+ return cpu_state->xmm7;
397
+ case EVOASM_X64_REG_XMM8:
398
+ return cpu_state->xmm8;
399
+ case EVOASM_X64_REG_XMM9:
400
+ return cpu_state->xmm9;
401
+ case EVOASM_X64_REG_XMM10:
402
+ return cpu_state->xmm10;
403
+ case EVOASM_X64_REG_XMM11:
404
+ return cpu_state->xmm11;
405
+ case EVOASM_X64_REG_XMM12:
406
+ return cpu_state->xmm12;
407
+ case EVOASM_X64_REG_XMM13:
408
+ return cpu_state->xmm13;
409
+ case EVOASM_X64_REG_XMM14:
410
+ return cpu_state->xmm14;
411
+ case EVOASM_X64_REG_XMM15:
412
+ return cpu_state->xmm15;
413
+ case EVOASM_X64_REG_ZMM16:
414
+ return cpu_state->zmm16;
415
+ case EVOASM_X64_REG_ZMM17:
416
+ return cpu_state->zmm17;
417
+ case EVOASM_X64_REG_ZMM18:
418
+ return cpu_state->zmm18;
419
+ case EVOASM_X64_REG_ZMM19:
420
+ return cpu_state->zmm19;
421
+ case EVOASM_X64_REG_ZMM20:
422
+ return cpu_state->zmm20;
423
+ case EVOASM_X64_REG_ZMM21:
424
+ return cpu_state->zmm21;
425
+ case EVOASM_X64_REG_ZMM22:
426
+ return cpu_state->zmm22;
427
+ case EVOASM_X64_REG_ZMM23:
428
+ return cpu_state->zmm23;
429
+ case EVOASM_X64_REG_ZMM24:
430
+ return cpu_state->zmm24;
431
+ case EVOASM_X64_REG_ZMM25:
432
+ return cpu_state->zmm25;
433
+ case EVOASM_X64_REG_ZMM26:
434
+ return cpu_state->zmm26;
435
+ case EVOASM_X64_REG_ZMM27:
436
+ return cpu_state->zmm27;
437
+ case EVOASM_X64_REG_ZMM28:
438
+ return cpu_state->zmm28;
439
+ case EVOASM_X64_REG_ZMM29:
440
+ return cpu_state->zmm29;
441
+ case EVOASM_X64_REG_ZMM30:
442
+ return cpu_state->zmm30;
443
+ case EVOASM_X64_REG_ZMM31:
444
+ return cpu_state->zmm31;
445
+ case EVOASM_X64_REG_RFLAGS:
446
+ return cpu_state->rflags;
447
+ case EVOASM_X64_REG_IP:
448
+ return cpu_state->ip;
449
+ case EVOASM_X64_REG_MXCSR:
450
+ return cpu_state->mxcsr;
451
+ default:
452
+ evoasm_assert_not_reached();
453
+ }
454
+ }
455
+
456
+ static evoasm_success_t
457
+ evoasm_x64_emit_rip_load_store(uint8_t *data,
458
+ evoasm_x64_reg_id_t tmp_reg1,
459
+ evoasm_x64_reg_id_t tmp_reg2,
460
+ evoasm_buf_t *buf,
461
+ bool load) {
462
+
463
+ evoasm_x64_params_t params = {0};
464
+
465
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG0, tmp_reg1);
466
+ EVOASM_X64_SET(EVOASM_X64_PARAM_IMM0, (evoasm_param_val_t) (uintptr_t) data);
467
+ EVOASM_X64_ENC(mov_r64_imm64);
468
+
469
+ if(load) {
470
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG_BASE, tmp_reg1);
471
+ EVOASM_X64_ENC(jmp_rm64);
472
+ } else {
473
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG0, tmp_reg2);
474
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG_BASE, EVOASM_X64_REG_IP);
475
+ EVOASM_X64_ENC(lea_r64_m64);
476
+
477
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG_BASE, tmp_reg1);
478
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG1, tmp_reg2);
479
+ EVOASM_X64_ENC(mov_rm64_r64);
480
+ }
481
+ return true;
482
+
483
+ enc_failed:
484
+ return false;
485
+ }
486
+
487
+ static evoasm_success_t
488
+ evoasm_x64_emit_pop_push(evoasm_x64_reg_id_t reg_id, evoasm_buf_t *buf, bool pop) {
489
+ evoasm_x64_params_t params = {0};
490
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG0, reg_id);
491
+ if(pop) {
492
+ EVOASM_X64_ENC(pop_r64);
493
+ } else {
494
+ EVOASM_X64_ENC(push_r64);
495
+ }
496
+
497
+ return true;
498
+
499
+ enc_failed:
500
+ return false;
501
+ }
502
+
503
+ evoasm_success_t
504
+ evoasm_x64_emit_pop(evoasm_x64_reg_id_t reg_id, evoasm_buf_t *buf) {
505
+ return evoasm_x64_emit_pop_push(reg_id, buf, true);
506
+ }
507
+
508
+ evoasm_success_t
509
+ evoasm_x64_emit_push(evoasm_x64_reg_id_t reg_id, evoasm_buf_t *buf) {
510
+ return evoasm_x64_emit_pop_push(reg_id, buf, false);
511
+ }
512
+
513
+ static evoasm_success_t
514
+ evoasm_x64_emit_rflags_load_store(uint8_t *data,
515
+ evoasm_x64_reg_id_t tmp_reg1,
516
+ evoasm_x64_reg_id_t tmp_reg2,
517
+ evoasm_buf_t *buf,
518
+ bool load) {
519
+
520
+ evoasm_x64_params_t params = {0};
521
+
522
+
523
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG0, tmp_reg1);
524
+ EVOASM_X64_SET(EVOASM_X64_PARAM_IMM0, (evoasm_param_val_t) (uintptr_t) data);
525
+ EVOASM_X64_ENC(mov_r64_imm64);
526
+
527
+ if(load) {
528
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG0, tmp_reg2);
529
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG_BASE, tmp_reg1);
530
+ EVOASM_X64_ENC(mov_r64_rm64);
531
+ EVOASM_TRY(enc_failed, evoasm_x64_emit_push, tmp_reg2, buf);
532
+ EVOASM_X64_ENC(popfq);
533
+ } else {
534
+ EVOASM_X64_ENC(pushfq);
535
+ EVOASM_TRY(enc_failed, evoasm_x64_emit_pop, tmp_reg2, buf);
536
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG_BASE, tmp_reg1);
537
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG1, tmp_reg2);
538
+ EVOASM_X64_ENC(mov_rm64_r64);
539
+ }
540
+
541
+ return true;
542
+
543
+ enc_failed:
544
+ return false;
545
+ }
546
+
547
+
548
+ static evoasm_success_t
549
+ evoasm_x64_emit_mm_load_store(evoasm_reg_id_t reg,
550
+ uint8_t *data,
551
+ evoasm_x64_reg_id_t tmp_reg,
552
+ evoasm_buf_t *buf,
553
+ bool load) {
554
+
555
+ evoasm_x64_params_t params = {0};
556
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG0, tmp_reg);
557
+ EVOASM_X64_SET(EVOASM_X64_PARAM_IMM0, (evoasm_param_val_t) (uintptr_t) data);
558
+ EVOASM_X64_ENC(mov_r64_imm64);
559
+
560
+
561
+ if(load) {
562
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG0, reg);
563
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG_BASE, tmp_reg);
564
+ EVOASM_X64_ENC(movq_mm_mmm64);
565
+ } else {
566
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG_BASE, tmp_reg);
567
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG1, reg);
568
+ EVOASM_X64_ENC(movq_mmm64_mm);
569
+ }
570
+
571
+ return true;
572
+
573
+ enc_failed:
574
+ return false;
575
+ }
576
+
577
+ static evoasm_success_t
578
+ evoasm_x64_emit_gp_load_store(evoasm_reg_id_t reg,
579
+ uint8_t *data,
580
+ evoasm_x64_reg_id_t tmp_reg,
581
+ evoasm_buf_t *buf,
582
+ bool load) {
583
+
584
+ evoasm_x64_params_t params = {0};
585
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG0, tmp_reg);
586
+ EVOASM_X64_SET(EVOASM_X64_PARAM_IMM0, (evoasm_param_val_t) (uintptr_t) data);
587
+ EVOASM_X64_ENC(mov_r64_imm64);
588
+
589
+
590
+ if(load) {
591
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG0, reg);
592
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG_BASE, tmp_reg);
593
+ EVOASM_X64_ENC(mov_r64_rm64);
594
+ } else {
595
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG_BASE, tmp_reg);
596
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG1, reg);
597
+ EVOASM_X64_ENC(mov_rm64_r64);
598
+ }
599
+
600
+ return true;
601
+
602
+ enc_failed:
603
+ return false;
604
+ }
605
+
606
+ static evoasm_success_t
607
+ evoasm_x64_emit_xmm_load_store(evoasm_reg_id_t reg,
608
+ uint8_t *data,
609
+ evoasm_x64_reg_id_t tmp_reg,
610
+ evoasm_buf_t *buf,
611
+ bool load) {
612
+
613
+ evoasm_x64_params_t params = {0};
614
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG0, tmp_reg);
615
+ EVOASM_X64_SET(EVOASM_X64_PARAM_IMM0, (evoasm_param_val_t) (uintptr_t) data);
616
+ EVOASM_X64_ENC(mov_r64_imm64);
617
+
618
+ if(load) {
619
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG0, reg);
620
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG_BASE, tmp_reg);
621
+ } else {
622
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG_BASE, tmp_reg);
623
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG1, reg);
624
+ }
625
+
626
+ if(evoasm_x64_reg_type_sizes[EVOASM_X64_REG_TYPE_XMM] == 32) {
627
+ if(load) {
628
+ EVOASM_X64_ENC(vmovdqa_ymm_ymmm256);
629
+ } else {
630
+ EVOASM_X64_ENC(vmovdqa_ymmm256_ymm);
631
+ }
632
+ }
633
+ #ifdef EVOASM_X64_ENABLE_AVX512
634
+ else if(evoasm_x64_reg_type_sizes[EVOASM_X64_REG_TYPE_XMM] == 64) {
635
+ goto unsupported;
636
+ }
637
+ #endif
638
+ else {
639
+ if(load) {
640
+ EVOASM_X64_ENC(movdqa_xmm_xmmm128);
641
+ } else {
642
+ EVOASM_X64_ENC(movdqa_xmmm128_xmm);
643
+ }
644
+ }
645
+
646
+ return true;
647
+
648
+ enc_failed:
649
+ return false;
650
+ }
651
+
652
+
653
+ static evoasm_success_t
654
+ evoasm_x64_emit_mxcsr_load_store(uint8_t *data,
655
+ evoasm_x64_reg_id_t tmp_reg,
656
+ evoasm_buf_t *buf,
657
+ bool load) {
658
+
659
+ evoasm_x64_params_t params = {0};
660
+
661
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG0, tmp_reg);
662
+ EVOASM_X64_SET(EVOASM_X64_PARAM_IMM0, (evoasm_param_val_t) (uintptr_t) data);
663
+ EVOASM_X64_ENC(mov_r64_imm64);
664
+
665
+ EVOASM_X64_SET(EVOASM_X64_PARAM_REG_BASE, tmp_reg);
666
+ if(load) {
667
+ EVOASM_X64_ENC(ldmxcsr_m32);
668
+ } else {
669
+ EVOASM_X64_ENC(stmxcsr_m32);
670
+ }
671
+ return true;
672
+
673
+ enc_failed:
674
+ return false;
675
+ }
676
+
677
+
678
+ static evoasm_success_t
679
+ evoasm_x64_emit_load_store(evoasm_x64_reg_id_t reg_id,
680
+ uint8_t *data,
681
+ evoasm_x64_reg_id_t tmp_reg1,
682
+ evoasm_x64_reg_id_t tmp_reg2,
683
+ evoasm_buf_t *buf,
684
+ bool load) {
685
+
686
+ evoasm_x64_reg_type_t reg_type = evoasm_x64_get_reg_type(reg_id);
687
+
688
+ switch(reg_type) {
689
+ case EVOASM_X64_REG_TYPE_GP: {
690
+ EVOASM_TRY(enc_failed, evoasm_x64_emit_gp_load_store, reg_id, data, tmp_reg1, buf, load);
691
+ break;
692
+ }
693
+ case EVOASM_X64_REG_TYPE_XMM: {
694
+ EVOASM_TRY(enc_failed, evoasm_x64_emit_xmm_load_store, reg_id, data, tmp_reg1, buf, load);
695
+ break;
696
+ }
697
+ case EVOASM_X64_REG_TYPE_MM: {
698
+ EVOASM_TRY(enc_failed, evoasm_x64_emit_mm_load_store, reg_id, data, tmp_reg1, buf, load);
699
+ break;
700
+ }
701
+ case EVOASM_X64_REG_TYPE_IP: {
702
+ EVOASM_TRY(enc_failed, evoasm_x64_emit_rip_load_store, data, tmp_reg1, tmp_reg2, buf, load);
703
+ break;
704
+ }
705
+ case EVOASM_X64_REG_TYPE_RFLAGS: {
706
+ EVOASM_TRY(enc_failed, evoasm_x64_emit_rflags_load_store, data, tmp_reg1, tmp_reg2, buf, load);
707
+ break;
708
+ }
709
+ case EVOASM_X64_REG_TYPE_MXCSR: {
710
+ EVOASM_TRY(enc_failed, evoasm_x64_emit_mxcsr_load_store, data, tmp_reg1, buf, load);
711
+ break;
712
+ }
713
+ default: {
714
+ #ifdef EVOASM_X64_ENABLE_AVX512
715
+ unsupported:
716
+ #endif
717
+ evoasm_log_fatal("non-gpr register type (%d) (unimplemented)", reg_type);
718
+ evoasm_assert_not_reached();
719
+ }
720
+ }
721
+
722
+ return true;
723
+
724
+ enc_failed:
725
+ return false;
726
+ }
727
+
728
+ void
729
+ evoasm_x64_cpu_state_set(evoasm_x64_cpu_state_t *cpu_state, evoasm_x64_reg_id_t reg, const uint64_t *data,
730
+ size_t len) {
731
+ size_t bytes_len = EVOASM_MIN(evoasm_x64_reg_type_sizes[evoasm_x64_get_reg_type(reg)], len * sizeof(uint64_t));
732
+ memcpy(evoasm_x64_cpu_state_get_reg_data(cpu_state, reg), data, bytes_len);
733
+
734
+ if(reg == EVOASM_X64_REG_RFLAGS) {
735
+ /* Mask away dangerous and useless flags */
736
+ cpu_state->rflags[0] &= 0x8c5;
737
+ }
738
+ }
739
+
740
+ void
741
+ evoasm_x64_cpu_state_memset(evoasm_x64_cpu_state_t *cpu_state, int value) {
742
+ memset(cpu_state, value, sizeof(evoasm_x64_cpu_state_t));
743
+ }
744
+
745
+ size_t
746
+ evoasm_x64_cpu_state_get(evoasm_x64_cpu_state_t *cpu_state, evoasm_x64_reg_id_t reg, evoasm_x64_operand_word_t word, uint64_t *data, size_t len) {
747
+ size_t size = evoasm_x64_reg_type_sizes[evoasm_x64_get_reg_type(reg)];
748
+ size_t cpy_len = EVOASM_MIN(len * sizeof(uint64_t), size);
749
+ memcpy(data, evoasm_x64_cpu_state_get_reg_data(cpu_state, reg), cpy_len);
750
+
751
+ size_t n_elems = EVOASM_MAX(1, cpy_len / sizeof(uint64_t));
752
+ size_t clear_from_idx = n_elems;
753
+
754
+ if(reg == EVOASM_X64_REG_RFLAGS) {
755
+ /* Mask away dangerous and useless flags */
756
+ data[0] &= 0x8c5;
757
+ }
758
+
759
+ switch(word) {
760
+ case EVOASM_X64_OPERAND_WORD_LB:
761
+ data[0] &= 0x00FF;
762
+ clear_from_idx = 1;
763
+ break;
764
+ case EVOASM_X64_OPERAND_WORD_HB:
765
+ data[0] &= 0xFF00;
766
+ clear_from_idx = 1;
767
+ break;
768
+ case EVOASM_X64_OPERAND_WORD_W:
769
+ data[0] &= 0xFFFF;
770
+ clear_from_idx = 1;
771
+ break;
772
+ case EVOASM_X64_OPERAND_WORD_DW:
773
+ data[0] &= 0xFFFFFFFF;
774
+ clear_from_idx = 1;
775
+ break;
776
+ case EVOASM_X64_OPERAND_WORD_LQW:
777
+ data[0] &= 0xFFFFFFFFFFFFFFFF;
778
+ clear_from_idx = 1;
779
+ break;
780
+ case EVOASM_X64_OPERAND_WORD_HQW:
781
+ data[0] = 0;
782
+ clear_from_idx = 2;
783
+ break;
784
+ case EVOASM_X64_OPERAND_WORD_DQW:
785
+ clear_from_idx = 2;
786
+ break;
787
+ case EVOASM_X64_OPERAND_WORD_VW:
788
+ break;
789
+ case EVOASM_X64_OPERAND_WORD_NONE:
790
+ break;
791
+ default:
792
+ evoasm_assert_not_reached();
793
+ }
794
+
795
+ for(size_t i = clear_from_idx; i < n_elems; i++) data[i] = 0;
796
+
797
+ return n_elems;
798
+ }
799
+
800
+ bool
801
+ evoasm_x64_cpu_state_get_rflags_flag(evoasm_x64_cpu_state_t *cpu_state, evoasm_x64_rflags_flag_t flag) {
802
+ uint64_t rflags = cpu_state->rflags[0];
803
+
804
+ switch(flag) {
805
+ case EVOASM_X64_RFLAGS_FLAG_OF:
806
+ return (rflags & (1 << 11)) != 0;
807
+ case EVOASM_X64_RFLAGS_FLAG_SF:
808
+ return (rflags & (1 << 7)) != 0;
809
+ case EVOASM_X64_RFLAGS_FLAG_ZF:
810
+ return (rflags & (1 << 6)) != 0;
811
+ case EVOASM_X64_RFLAGS_FLAG_PF:
812
+ return (rflags & (1 << 2)) != 0;
813
+ case EVOASM_X64_RFLAGS_FLAG_CF:
814
+ return (rflags & (1 << 0)) != 0;
815
+ default:
816
+ evoasm_assert_not_reached();
817
+ }
818
+ }
819
+
820
+ void
821
+ evoasm_x64_cpu_state_clone(evoasm_x64_cpu_state_t *cpu_state, evoasm_x64_cpu_state_t *cloned_cpu_state) {
822
+ *cloned_cpu_state = *cpu_state;
823
+ }
824
+
825
+ static_assert(CHAR_BIT == 8, "CHAR_BIT must be 8");
826
+
827
+ void
828
+ evoasm_x64_cpu_state_xor(evoasm_x64_cpu_state_t *cpu_state,
829
+ evoasm_x64_cpu_state_t *other_cpu_state,
830
+ evoasm_x64_cpu_state_t *xored_cpu_state) {
831
+ size_t size = sizeof(evoasm_x64_cpu_state_t);
832
+ uint8_t *data = (uint8_t *) cpu_state;
833
+ uint8_t *other_data = (uint8_t *) other_cpu_state;
834
+ uint8_t *xored_data = (uint8_t *) xored_cpu_state;
835
+
836
+ for(size_t i = 0; i < size; i++) {
837
+ xored_data[i] = data[i] ^ other_data[i];
838
+ }
839
+ }
840
+
841
+ void
842
+ evoasm_x64_cpu_state_init(evoasm_x64_cpu_state_t *cpu_state, evoasm_x64_cpu_state_flags_t flags) {
843
+ static evoasm_x64_cpu_state_t zero_cpu_state = {0};
844
+ *cpu_state = zero_cpu_state;
845
+ cpu_state->flags = flags;
846
+ }
847
+
848
+
849
+ EVOASM_DEF_EMPTY_DESTROY_FUNC(x64_cpu_state)
850
+
851
+
852
+ evoasm_x64_cpu_state_t *
853
+ evoasm_x64_cpu_state_alloc() {
854
+ return evoasm_aligned_alloc(32, sizeof(evoasm_x64_cpu_state_t));
855
+ }
856
+
857
+ void
858
+ evoasm_x64_cpu_state_free(evoasm_x64_cpu_state_t *cpu_state) {
859
+ evoasm_free(cpu_state);
860
+ }
861
+
862
+ evoasm_success_t
863
+ evoasm_x64_cpu_state_emit_load_store(evoasm_x64_cpu_state_t *cpu_state,
864
+ evoasm_buf_t *buf, bool load) {
865
+
866
+ bool ip = cpu_state->flags & EVOASM_X64_CPU_STATE_FLAG_IP;
867
+ bool sp = cpu_state->flags & EVOASM_X64_CPU_STATE_FLAG_SP;
868
+ bool mxcsr = cpu_state->flags & EVOASM_X64_CPU_STATE_FLAG_MXCSR;
869
+ bool rflags = cpu_state->flags & EVOASM_X64_CPU_STATE_FLAG_RFLAGS;
870
+
871
+ static const evoasm_x64_reg_id_t tmp_reg1 = EVOASM_X64_REG_14;
872
+ static const evoasm_x64_reg_id_t tmp_reg2 = EVOASM_X64_REG_15;
873
+
874
+ EVOASM_TRY(enc_failed, evoasm_x64_emit_push, tmp_reg1, buf);
875
+ EVOASM_TRY(enc_failed, evoasm_x64_emit_push, tmp_reg2, buf);
876
+
877
+ for(evoasm_x64_reg_id_t reg_id = (evoasm_x64_reg_id_t) 0; reg_id < EVOASM_X64_REG_NONE; reg_id++) {
878
+ if(reg_id == tmp_reg1 || reg_id == tmp_reg2) continue;
879
+ #ifndef EVOASM_X64_ENABLE_AVX512
880
+ if(reg_id >= EVOASM_X64_REG_ZMM16) continue;
881
+ #endif
882
+
883
+ if(!ip && reg_id == EVOASM_X64_REG_IP) continue;
884
+ if(!sp && reg_id == EVOASM_X64_REG_SP) continue;
885
+ if(!mxcsr && reg_id == EVOASM_X64_REG_MXCSR) continue;
886
+ if(!rflags && reg_id == EVOASM_X64_REG_RFLAGS) continue;
887
+
888
+ uint8_t *data = (uint8_t *) evoasm_x64_cpu_state_get_reg_data(cpu_state, reg_id);
889
+ EVOASM_TRY(enc_failed, evoasm_x64_emit_load_store, reg_id, data, tmp_reg1, tmp_reg2, buf, load);
890
+ }
891
+
892
+ EVOASM_TRY(enc_failed, evoasm_x64_emit_pop, tmp_reg2, buf);
893
+ {
894
+ uint8_t *data = (uint8_t *) evoasm_x64_cpu_state_get_reg_data(cpu_state, tmp_reg2);
895
+ EVOASM_TRY(enc_failed, evoasm_x64_emit_load_store, tmp_reg2, data, tmp_reg1, EVOASM_X64_REG_NONE, buf, load);
896
+ }
897
+
898
+ EVOASM_TRY(enc_failed, evoasm_x64_emit_pop, tmp_reg1, buf);
899
+ EVOASM_TRY(enc_failed, evoasm_x64_emit_push, tmp_reg2, buf);
900
+ {
901
+ uint8_t *data = (uint8_t *) evoasm_x64_cpu_state_get_reg_data(cpu_state, tmp_reg1);
902
+ EVOASM_TRY(enc_failed, evoasm_x64_emit_load_store, tmp_reg1, data, tmp_reg2, EVOASM_X64_REG_NONE, buf, load);
903
+ }
904
+ EVOASM_TRY(enc_failed, evoasm_x64_emit_pop, tmp_reg2, buf);
905
+
906
+ return true;
907
+
908
+ enc_failed:
909
+ return false;
910
+
911
+ }
912
+
913
+ evoasm_success_t
914
+ evoasm_x64_cpu_state_emit_load(evoasm_x64_cpu_state_t *cpu_state, evoasm_buf_t *buf) {
915
+ return evoasm_x64_cpu_state_emit_load_store(cpu_state, buf, true);
916
+ }
917
+
918
+ evoasm_success_t
919
+ evoasm_x64_cpu_state_emit_store(evoasm_x64_cpu_state_t *cpu_state, evoasm_buf_t *buf) {
920
+ return evoasm_x64_cpu_state_emit_load_store(cpu_state, buf, false);
921
+ }
922
+
923
+ EVOASM_DEF_ALLOC_FREE_FUNCS(x64_params)
924
+
925
+ EVOASM_DEF_ALLOC_FREE_FUNCS(x64_basic_params)