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,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)