PyNerva 0.0.7__py3-none-any.whl
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.
- nervapy/__init__.py +50 -0
- nervapy/abi.py +91 -0
- nervapy/arm/__init__.py +124 -0
- nervapy/arm/__main__.py +0 -0
- nervapy/arm/abi.py +138 -0
- nervapy/arm/formats.py +49 -0
- nervapy/arm/function.py +2465 -0
- nervapy/arm/generic.py +10796 -0
- nervapy/arm/instructions.py +519 -0
- nervapy/arm/isa.py +409 -0
- nervapy/arm/literal_pool.py +331 -0
- nervapy/arm/microarchitecture.py +211 -0
- nervapy/arm/pseudo.py +652 -0
- nervapy/arm/registers.py +1458 -0
- nervapy/arm/vfpneon.py +4092 -0
- nervapy/arm.py +13 -0
- nervapy/c/__init__.py +1 -0
- nervapy/c/types.py +436 -0
- nervapy/codegen.py +99 -0
- nervapy/common/__init__.py +4 -0
- nervapy/common/function.py +5 -0
- nervapy/common/regalloc.py +121 -0
- nervapy/constant_data.py +282 -0
- nervapy/encoder.py +246 -0
- nervapy/formats/__init__.py +2 -0
- nervapy/formats/elf/__init__.py +4 -0
- nervapy/formats/elf/file.py +178 -0
- nervapy/formats/elf/image.py +106 -0
- nervapy/formats/elf/section.py +422 -0
- nervapy/formats/elf/symbol.py +281 -0
- nervapy/formats/macho/__init__.py +2 -0
- nervapy/formats/macho/file.py +123 -0
- nervapy/formats/macho/image.py +143 -0
- nervapy/formats/macho/section.py +322 -0
- nervapy/formats/macho/symbol.py +158 -0
- nervapy/formats/mscoff/__init__.py +8 -0
- nervapy/formats/mscoff/image.py +132 -0
- nervapy/formats/mscoff/section.py +181 -0
- nervapy/formats/mscoff/symbol.py +148 -0
- nervapy/function.py +136 -0
- nervapy/literal.py +731 -0
- nervapy/loader.py +188 -0
- nervapy/name.py +159 -0
- nervapy/parse.py +52 -0
- nervapy/stream.py +58 -0
- nervapy/util.py +126 -0
- nervapy/writer.py +518 -0
- nervapy/x86_64/__init__.py +324 -0
- nervapy/x86_64/__main__.py +407 -0
- nervapy/x86_64/abi.py +517 -0
- nervapy/x86_64/amd.py +6464 -0
- nervapy/x86_64/avx.py +102029 -0
- nervapy/x86_64/crypto.py +1533 -0
- nervapy/x86_64/encoding.py +424 -0
- nervapy/x86_64/fma.py +19138 -0
- nervapy/x86_64/function.py +2707 -0
- nervapy/x86_64/generic.py +23384 -0
- nervapy/x86_64/instructions.py +500 -0
- nervapy/x86_64/isa.py +476 -0
- nervapy/x86_64/lower.py +126 -0
- nervapy/x86_64/mask.py +2593 -0
- nervapy/x86_64/meta.py +143 -0
- nervapy/x86_64/mmxsse.py +17265 -0
- nervapy/x86_64/nacl.py +327 -0
- nervapy/x86_64/operand.py +1204 -0
- nervapy/x86_64/options.py +21 -0
- nervapy/x86_64/pseudo.py +686 -0
- nervapy/x86_64/registers.py +1225 -0
- nervapy/x86_64/types.py +17 -0
- nervapy/x86_64/uarch.py +580 -0
- pynerva-0.0.7.dist-info/METADATA +310 -0
- pynerva-0.0.7.dist-info/RECORD +74 -0
- pynerva-0.0.7.dist-info/WHEEL +4 -0
- pynerva-0.0.7.dist-info/licenses/LICENSE.rst +15 -0
nervapy/x86_64/crypto.py
ADDED
|
@@ -0,0 +1,1533 @@
|
|
|
1
|
+
# This file is auto-generated by /codegen/x86_64.py
|
|
2
|
+
# Instruction data is based on package opcodes 0.3.14
|
|
3
|
+
|
|
4
|
+
import inspect
|
|
5
|
+
|
|
6
|
+
import nervapy.stream
|
|
7
|
+
import nervapy.x86_64.isa
|
|
8
|
+
import nervapy.x86_64.options
|
|
9
|
+
from nervapy.util import is_sint8, is_sint32
|
|
10
|
+
from nervapy.x86_64.encoding import (evex, modrm_sib_disp, optional_rex, rex,
|
|
11
|
+
vex2, vex3)
|
|
12
|
+
from nervapy.x86_64.instructions import BranchInstruction, Instruction
|
|
13
|
+
from nervapy.x86_64.operand import (check_operand, format_operand_type, is_al,
|
|
14
|
+
is_ax, is_cl, is_eax, is_er, is_evex_vmx,
|
|
15
|
+
is_evex_vmy, is_evex_xmm, is_evex_ymm,
|
|
16
|
+
is_imm, is_imm4, is_imm8, is_imm16,
|
|
17
|
+
is_imm32, is_imm64, is_k, is_kk, is_label,
|
|
18
|
+
is_m, is_m8, is_m16, is_m16kz, is_m32,
|
|
19
|
+
is_m32k, is_m32kz, is_m64, is_m64_m32bcst,
|
|
20
|
+
is_m64k, is_m64kz, is_m80, is_m128,
|
|
21
|
+
is_m128_m32bcst, is_m128_m64bcst,
|
|
22
|
+
is_m128kz, is_m256, is_m256_m32bcst,
|
|
23
|
+
is_m256_m64bcst, is_m256kz, is_m512,
|
|
24
|
+
is_m512_m32bcst, is_m512_m64bcst,
|
|
25
|
+
is_m512kz, is_mm, is_r8, is_r8rex, is_r16,
|
|
26
|
+
is_r32, is_r64, is_rax, is_rel8, is_rel32,
|
|
27
|
+
is_sae, is_vmx, is_vmxk, is_vmy, is_vmyk,
|
|
28
|
+
is_vmz, is_vmzk, is_xmm, is_xmm0, is_xmmk,
|
|
29
|
+
is_xmmkz, is_ymm, is_ymmk, is_ymmkz,
|
|
30
|
+
is_zmm, is_zmmk, is_zmmkz)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class AESDEC(Instruction):
|
|
34
|
+
"""Perform One Round of an AES Decryption Flow"""
|
|
35
|
+
|
|
36
|
+
def __init__(self, *args, **kwargs):
|
|
37
|
+
"""Supported forms:
|
|
38
|
+
|
|
39
|
+
* AESDEC(xmm, xmm/m128) [AES]
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
origin = kwargs.get("origin")
|
|
43
|
+
prototype = kwargs.get("prototype")
|
|
44
|
+
if (
|
|
45
|
+
origin is None
|
|
46
|
+
and prototype is None
|
|
47
|
+
and nervapy.x86_64.options.get_debug_level() > 0
|
|
48
|
+
):
|
|
49
|
+
origin = inspect.stack()
|
|
50
|
+
super(AESDEC, self).__init__("AESDEC", origin=origin, prototype=prototype)
|
|
51
|
+
self.operands = tuple(map(check_operand, args))
|
|
52
|
+
if len(self.operands) != 2:
|
|
53
|
+
raise SyntaxError('Instruction "AESDEC" requires 2 operands')
|
|
54
|
+
self.go_name = "AESDEC"
|
|
55
|
+
self.in_regs = (False, True)
|
|
56
|
+
self.out_regs = (True, False)
|
|
57
|
+
self.out_operands = (True, False)
|
|
58
|
+
self.avx_mode = False
|
|
59
|
+
self.isa_extensions = frozenset([nervapy.x86_64.isa.aes])
|
|
60
|
+
if is_xmm(self.operands[0]) and is_xmm(self.operands[1]):
|
|
61
|
+
self.encodings.append(
|
|
62
|
+
(
|
|
63
|
+
0x20,
|
|
64
|
+
lambda op, rex=False: bytearray([0x66])
|
|
65
|
+
+ optional_rex(op[0].hcode, op[1], rex)
|
|
66
|
+
+ bytearray(
|
|
67
|
+
[0x0F, 0x38, 0xDE, 0xC0 | op[0].lcode << 3 | op[1].lcode]
|
|
68
|
+
),
|
|
69
|
+
)
|
|
70
|
+
)
|
|
71
|
+
elif is_xmm(self.operands[0]) and is_m128(self.operands[1]):
|
|
72
|
+
self.encodings.append(
|
|
73
|
+
(
|
|
74
|
+
0x30,
|
|
75
|
+
lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66])
|
|
76
|
+
+ optional_rex(op[0].hcode, op[1].address, rex)
|
|
77
|
+
+ bytearray([0x0F, 0x38, 0xDE])
|
|
78
|
+
+ modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp),
|
|
79
|
+
)
|
|
80
|
+
)
|
|
81
|
+
else:
|
|
82
|
+
raise SyntaxError(
|
|
83
|
+
"Invalid operand types: AESDEC "
|
|
84
|
+
+ ", ".join(map(format_operand_type, self.operands))
|
|
85
|
+
)
|
|
86
|
+
if nervapy.stream.active_stream is not None:
|
|
87
|
+
nervapy.stream.active_stream.add_instruction(self)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class AESDECLAST(Instruction):
|
|
91
|
+
"""Perform Last Round of an AES Decryption Flow"""
|
|
92
|
+
|
|
93
|
+
def __init__(self, *args, **kwargs):
|
|
94
|
+
"""Supported forms:
|
|
95
|
+
|
|
96
|
+
* AESDECLAST(xmm, xmm/m128) [AES]
|
|
97
|
+
"""
|
|
98
|
+
|
|
99
|
+
origin = kwargs.get("origin")
|
|
100
|
+
prototype = kwargs.get("prototype")
|
|
101
|
+
if (
|
|
102
|
+
origin is None
|
|
103
|
+
and prototype is None
|
|
104
|
+
and nervapy.x86_64.options.get_debug_level() > 0
|
|
105
|
+
):
|
|
106
|
+
origin = inspect.stack()
|
|
107
|
+
super(AESDECLAST, self).__init__(
|
|
108
|
+
"AESDECLAST", origin=origin, prototype=prototype
|
|
109
|
+
)
|
|
110
|
+
self.operands = tuple(map(check_operand, args))
|
|
111
|
+
if len(self.operands) != 2:
|
|
112
|
+
raise SyntaxError('Instruction "AESDECLAST" requires 2 operands')
|
|
113
|
+
self.go_name = "AESDECLAST"
|
|
114
|
+
self.in_regs = (False, True)
|
|
115
|
+
self.out_regs = (True, False)
|
|
116
|
+
self.out_operands = (True, False)
|
|
117
|
+
self.avx_mode = False
|
|
118
|
+
self.isa_extensions = frozenset([nervapy.x86_64.isa.aes])
|
|
119
|
+
if is_xmm(self.operands[0]) and is_xmm(self.operands[1]):
|
|
120
|
+
self.encodings.append(
|
|
121
|
+
(
|
|
122
|
+
0x20,
|
|
123
|
+
lambda op, rex=False: bytearray([0x66])
|
|
124
|
+
+ optional_rex(op[0].hcode, op[1], rex)
|
|
125
|
+
+ bytearray(
|
|
126
|
+
[0x0F, 0x38, 0xDF, 0xC0 | op[0].lcode << 3 | op[1].lcode]
|
|
127
|
+
),
|
|
128
|
+
)
|
|
129
|
+
)
|
|
130
|
+
elif is_xmm(self.operands[0]) and is_m128(self.operands[1]):
|
|
131
|
+
self.encodings.append(
|
|
132
|
+
(
|
|
133
|
+
0x30,
|
|
134
|
+
lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66])
|
|
135
|
+
+ optional_rex(op[0].hcode, op[1].address, rex)
|
|
136
|
+
+ bytearray([0x0F, 0x38, 0xDF])
|
|
137
|
+
+ modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp),
|
|
138
|
+
)
|
|
139
|
+
)
|
|
140
|
+
else:
|
|
141
|
+
raise SyntaxError(
|
|
142
|
+
"Invalid operand types: AESDECLAST "
|
|
143
|
+
+ ", ".join(map(format_operand_type, self.operands))
|
|
144
|
+
)
|
|
145
|
+
if nervapy.stream.active_stream is not None:
|
|
146
|
+
nervapy.stream.active_stream.add_instruction(self)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
class AESENC(Instruction):
|
|
150
|
+
"""Perform One Round of an AES Encryption Flow"""
|
|
151
|
+
|
|
152
|
+
def __init__(self, *args, **kwargs):
|
|
153
|
+
"""Supported forms:
|
|
154
|
+
|
|
155
|
+
* AESENC(xmm, xmm/m128) [AES]
|
|
156
|
+
"""
|
|
157
|
+
|
|
158
|
+
origin = kwargs.get("origin")
|
|
159
|
+
prototype = kwargs.get("prototype")
|
|
160
|
+
if (
|
|
161
|
+
origin is None
|
|
162
|
+
and prototype is None
|
|
163
|
+
and nervapy.x86_64.options.get_debug_level() > 0
|
|
164
|
+
):
|
|
165
|
+
origin = inspect.stack()
|
|
166
|
+
super(AESENC, self).__init__("AESENC", origin=origin, prototype=prototype)
|
|
167
|
+
self.operands = tuple(map(check_operand, args))
|
|
168
|
+
if len(self.operands) != 2:
|
|
169
|
+
raise SyntaxError('Instruction "AESENC" requires 2 operands')
|
|
170
|
+
self.go_name = "AESENC"
|
|
171
|
+
self.in_regs = (True, True)
|
|
172
|
+
self.out_regs = (True, False)
|
|
173
|
+
self.out_operands = (True, False)
|
|
174
|
+
self.avx_mode = False
|
|
175
|
+
self.isa_extensions = frozenset([nervapy.x86_64.isa.aes])
|
|
176
|
+
if is_xmm(self.operands[0]) and is_xmm(self.operands[1]):
|
|
177
|
+
self.encodings.append(
|
|
178
|
+
(
|
|
179
|
+
0x20,
|
|
180
|
+
lambda op, rex=False: bytearray([0x66])
|
|
181
|
+
+ optional_rex(op[0].hcode, op[1], rex)
|
|
182
|
+
+ bytearray(
|
|
183
|
+
[0x0F, 0x38, 0xDC, 0xC0 | op[0].lcode << 3 | op[1].lcode]
|
|
184
|
+
),
|
|
185
|
+
)
|
|
186
|
+
)
|
|
187
|
+
elif is_xmm(self.operands[0]) and is_m128(self.operands[1]):
|
|
188
|
+
self.encodings.append(
|
|
189
|
+
(
|
|
190
|
+
0x30,
|
|
191
|
+
lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66])
|
|
192
|
+
+ optional_rex(op[0].hcode, op[1].address, rex)
|
|
193
|
+
+ bytearray([0x0F, 0x38, 0xDC])
|
|
194
|
+
+ modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp),
|
|
195
|
+
)
|
|
196
|
+
)
|
|
197
|
+
else:
|
|
198
|
+
raise SyntaxError(
|
|
199
|
+
"Invalid operand types: AESENC "
|
|
200
|
+
+ ", ".join(map(format_operand_type, self.operands))
|
|
201
|
+
)
|
|
202
|
+
if nervapy.stream.active_stream is not None:
|
|
203
|
+
nervapy.stream.active_stream.add_instruction(self)
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
class AESENCLAST(Instruction):
|
|
207
|
+
"""Perform Last Round of an AES Encryption Flow"""
|
|
208
|
+
|
|
209
|
+
def __init__(self, *args, **kwargs):
|
|
210
|
+
"""Supported forms:
|
|
211
|
+
|
|
212
|
+
* AESENCLAST(xmm, xmm/m128) [AES]
|
|
213
|
+
"""
|
|
214
|
+
|
|
215
|
+
origin = kwargs.get("origin")
|
|
216
|
+
prototype = kwargs.get("prototype")
|
|
217
|
+
if (
|
|
218
|
+
origin is None
|
|
219
|
+
and prototype is None
|
|
220
|
+
and nervapy.x86_64.options.get_debug_level() > 0
|
|
221
|
+
):
|
|
222
|
+
origin = inspect.stack()
|
|
223
|
+
super(AESENCLAST, self).__init__(
|
|
224
|
+
"AESENCLAST", origin=origin, prototype=prototype
|
|
225
|
+
)
|
|
226
|
+
self.operands = tuple(map(check_operand, args))
|
|
227
|
+
if len(self.operands) != 2:
|
|
228
|
+
raise SyntaxError('Instruction "AESENCLAST" requires 2 operands')
|
|
229
|
+
self.go_name = "AESENCLAST"
|
|
230
|
+
self.in_regs = (True, True)
|
|
231
|
+
self.out_regs = (True, False)
|
|
232
|
+
self.out_operands = (True, False)
|
|
233
|
+
self.avx_mode = False
|
|
234
|
+
self.isa_extensions = frozenset([nervapy.x86_64.isa.aes])
|
|
235
|
+
if is_xmm(self.operands[0]) and is_xmm(self.operands[1]):
|
|
236
|
+
self.encodings.append(
|
|
237
|
+
(
|
|
238
|
+
0x20,
|
|
239
|
+
lambda op, rex=False: bytearray([0x66])
|
|
240
|
+
+ optional_rex(op[0].hcode, op[1], rex)
|
|
241
|
+
+ bytearray(
|
|
242
|
+
[0x0F, 0x38, 0xDD, 0xC0 | op[0].lcode << 3 | op[1].lcode]
|
|
243
|
+
),
|
|
244
|
+
)
|
|
245
|
+
)
|
|
246
|
+
elif is_xmm(self.operands[0]) and is_m128(self.operands[1]):
|
|
247
|
+
self.encodings.append(
|
|
248
|
+
(
|
|
249
|
+
0x30,
|
|
250
|
+
lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66])
|
|
251
|
+
+ optional_rex(op[0].hcode, op[1].address, rex)
|
|
252
|
+
+ bytearray([0x0F, 0x38, 0xDD])
|
|
253
|
+
+ modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp),
|
|
254
|
+
)
|
|
255
|
+
)
|
|
256
|
+
else:
|
|
257
|
+
raise SyntaxError(
|
|
258
|
+
"Invalid operand types: AESENCLAST "
|
|
259
|
+
+ ", ".join(map(format_operand_type, self.operands))
|
|
260
|
+
)
|
|
261
|
+
if nervapy.stream.active_stream is not None:
|
|
262
|
+
nervapy.stream.active_stream.add_instruction(self)
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
class AESIMC(Instruction):
|
|
266
|
+
"""Perform the AES InvMixColumn Transformation"""
|
|
267
|
+
|
|
268
|
+
def __init__(self, *args, **kwargs):
|
|
269
|
+
"""Supported forms:
|
|
270
|
+
|
|
271
|
+
* AESIMC(xmm, xmm/m128) [AES]
|
|
272
|
+
"""
|
|
273
|
+
|
|
274
|
+
origin = kwargs.get("origin")
|
|
275
|
+
prototype = kwargs.get("prototype")
|
|
276
|
+
if (
|
|
277
|
+
origin is None
|
|
278
|
+
and prototype is None
|
|
279
|
+
and nervapy.x86_64.options.get_debug_level() > 0
|
|
280
|
+
):
|
|
281
|
+
origin = inspect.stack()
|
|
282
|
+
super(AESIMC, self).__init__("AESIMC", origin=origin, prototype=prototype)
|
|
283
|
+
self.operands = tuple(map(check_operand, args))
|
|
284
|
+
if len(self.operands) != 2:
|
|
285
|
+
raise SyntaxError('Instruction "AESIMC" requires 2 operands')
|
|
286
|
+
self.go_name = "AESIMC"
|
|
287
|
+
self.in_regs = (False, True)
|
|
288
|
+
self.out_regs = (True, False)
|
|
289
|
+
self.out_operands = (True, False)
|
|
290
|
+
self.avx_mode = False
|
|
291
|
+
self.isa_extensions = frozenset([nervapy.x86_64.isa.aes])
|
|
292
|
+
if is_xmm(self.operands[0]) and is_xmm(self.operands[1]):
|
|
293
|
+
self.encodings.append(
|
|
294
|
+
(
|
|
295
|
+
0x20,
|
|
296
|
+
lambda op, rex=False: bytearray([0x66])
|
|
297
|
+
+ optional_rex(op[0].hcode, op[1], rex)
|
|
298
|
+
+ bytearray(
|
|
299
|
+
[0x0F, 0x38, 0xDB, 0xC0 | op[0].lcode << 3 | op[1].lcode]
|
|
300
|
+
),
|
|
301
|
+
)
|
|
302
|
+
)
|
|
303
|
+
elif is_xmm(self.operands[0]) and is_m128(self.operands[1]):
|
|
304
|
+
self.encodings.append(
|
|
305
|
+
(
|
|
306
|
+
0x30,
|
|
307
|
+
lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66])
|
|
308
|
+
+ optional_rex(op[0].hcode, op[1].address, rex)
|
|
309
|
+
+ bytearray([0x0F, 0x38, 0xDB])
|
|
310
|
+
+ modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp),
|
|
311
|
+
)
|
|
312
|
+
)
|
|
313
|
+
else:
|
|
314
|
+
raise SyntaxError(
|
|
315
|
+
"Invalid operand types: AESIMC "
|
|
316
|
+
+ ", ".join(map(format_operand_type, self.operands))
|
|
317
|
+
)
|
|
318
|
+
if nervapy.stream.active_stream is not None:
|
|
319
|
+
nervapy.stream.active_stream.add_instruction(self)
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
class AESKEYGENASSIST(Instruction):
|
|
323
|
+
"""AES Round Key Generation Assist"""
|
|
324
|
+
|
|
325
|
+
def __init__(self, *args, **kwargs):
|
|
326
|
+
"""Supported forms:
|
|
327
|
+
|
|
328
|
+
* AESKEYGENASSIST(xmm, xmm/m128, imm8) [AES]
|
|
329
|
+
"""
|
|
330
|
+
|
|
331
|
+
origin = kwargs.get("origin")
|
|
332
|
+
prototype = kwargs.get("prototype")
|
|
333
|
+
if (
|
|
334
|
+
origin is None
|
|
335
|
+
and prototype is None
|
|
336
|
+
and nervapy.x86_64.options.get_debug_level() > 0
|
|
337
|
+
):
|
|
338
|
+
origin = inspect.stack()
|
|
339
|
+
super(AESKEYGENASSIST, self).__init__(
|
|
340
|
+
"AESKEYGENASSIST", origin=origin, prototype=prototype
|
|
341
|
+
)
|
|
342
|
+
self.operands = tuple(map(check_operand, args))
|
|
343
|
+
if len(self.operands) != 3:
|
|
344
|
+
raise SyntaxError('Instruction "AESKEYGENASSIST" requires 3 operands')
|
|
345
|
+
self.go_name = "AESKEYGENASSIST"
|
|
346
|
+
self.in_regs = (False, True, False)
|
|
347
|
+
self.out_regs = (True, False, False)
|
|
348
|
+
self.out_operands = (True, False, False)
|
|
349
|
+
self.avx_mode = False
|
|
350
|
+
self.isa_extensions = frozenset([nervapy.x86_64.isa.aes])
|
|
351
|
+
if (
|
|
352
|
+
is_xmm(self.operands[0])
|
|
353
|
+
and is_xmm(self.operands[1])
|
|
354
|
+
and is_imm(self.operands[2])
|
|
355
|
+
):
|
|
356
|
+
if not is_imm8(self.operands[2]):
|
|
357
|
+
raise ValueError("Argument #2 can not be encoded as imm8")
|
|
358
|
+
self.encodings.append(
|
|
359
|
+
(
|
|
360
|
+
0x20,
|
|
361
|
+
lambda op, rex=False: bytearray([0x66])
|
|
362
|
+
+ optional_rex(op[0].hcode, op[1], rex)
|
|
363
|
+
+ bytearray(
|
|
364
|
+
[
|
|
365
|
+
0x0F,
|
|
366
|
+
0x3A,
|
|
367
|
+
0xDF,
|
|
368
|
+
0xC0 | op[0].lcode << 3 | op[1].lcode,
|
|
369
|
+
op[2] & 0xFF,
|
|
370
|
+
]
|
|
371
|
+
),
|
|
372
|
+
)
|
|
373
|
+
)
|
|
374
|
+
elif (
|
|
375
|
+
is_xmm(self.operands[0])
|
|
376
|
+
and is_m128(self.operands[1])
|
|
377
|
+
and is_imm(self.operands[2])
|
|
378
|
+
):
|
|
379
|
+
if not is_imm8(self.operands[2]):
|
|
380
|
+
raise ValueError("Argument #2 can not be encoded as imm8")
|
|
381
|
+
self.encodings.append(
|
|
382
|
+
(
|
|
383
|
+
0x30,
|
|
384
|
+
lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66])
|
|
385
|
+
+ optional_rex(op[0].hcode, op[1].address, rex)
|
|
386
|
+
+ bytearray([0x0F, 0x3A, 0xDF])
|
|
387
|
+
+ modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)
|
|
388
|
+
+ bytearray([op[2] & 0xFF]),
|
|
389
|
+
)
|
|
390
|
+
)
|
|
391
|
+
else:
|
|
392
|
+
raise SyntaxError(
|
|
393
|
+
"Invalid operand types: AESKEYGENASSIST "
|
|
394
|
+
+ ", ".join(map(format_operand_type, self.operands))
|
|
395
|
+
)
|
|
396
|
+
if nervapy.stream.active_stream is not None:
|
|
397
|
+
nervapy.stream.active_stream.add_instruction(self)
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
class VAESDEC(Instruction):
|
|
401
|
+
"""Perform One Round of an AES Decryption Flow"""
|
|
402
|
+
|
|
403
|
+
def __init__(self, *args, **kwargs):
|
|
404
|
+
"""Supported forms:
|
|
405
|
+
|
|
406
|
+
* VAESDEC(xmm, xmm, xmm/m128) [AVX and AES]
|
|
407
|
+
"""
|
|
408
|
+
|
|
409
|
+
origin = kwargs.get("origin")
|
|
410
|
+
prototype = kwargs.get("prototype")
|
|
411
|
+
if (
|
|
412
|
+
origin is None
|
|
413
|
+
and prototype is None
|
|
414
|
+
and nervapy.x86_64.options.get_debug_level() > 0
|
|
415
|
+
):
|
|
416
|
+
origin = inspect.stack()
|
|
417
|
+
super(VAESDEC, self).__init__("VAESDEC", origin=origin, prototype=prototype)
|
|
418
|
+
self.operands = tuple(map(check_operand, args))
|
|
419
|
+
if len(self.operands) != 3:
|
|
420
|
+
raise SyntaxError('Instruction "VAESDEC" requires 3 operands')
|
|
421
|
+
self.in_regs = (False, True, True)
|
|
422
|
+
self.out_regs = (True, False, False)
|
|
423
|
+
self.out_operands = (True, False, False)
|
|
424
|
+
self.avx_mode = True
|
|
425
|
+
self.isa_extensions = frozenset(
|
|
426
|
+
[nervapy.x86_64.isa.avx, nervapy.x86_64.isa.aes]
|
|
427
|
+
)
|
|
428
|
+
if (
|
|
429
|
+
is_xmm(self.operands[0])
|
|
430
|
+
and is_xmm(self.operands[1])
|
|
431
|
+
and is_xmm(self.operands[2])
|
|
432
|
+
):
|
|
433
|
+
self.encodings.append(
|
|
434
|
+
(
|
|
435
|
+
0x00,
|
|
436
|
+
lambda op: bytearray(
|
|
437
|
+
[
|
|
438
|
+
0xC4,
|
|
439
|
+
0xE2 ^ (op[0].hcode << 7) ^ (op[2].hcode << 5),
|
|
440
|
+
0x79 ^ (op[1].hlcode << 3),
|
|
441
|
+
0xDE,
|
|
442
|
+
0xC0 | op[0].lcode << 3 | op[2].lcode,
|
|
443
|
+
]
|
|
444
|
+
),
|
|
445
|
+
)
|
|
446
|
+
)
|
|
447
|
+
elif (
|
|
448
|
+
is_xmm(self.operands[0])
|
|
449
|
+
and is_xmm(self.operands[1])
|
|
450
|
+
and is_m128(self.operands[2])
|
|
451
|
+
):
|
|
452
|
+
self.encodings.append(
|
|
453
|
+
(
|
|
454
|
+
0x10,
|
|
455
|
+
lambda op, sib=False, min_disp=0: vex3(
|
|
456
|
+
0xC4, 0b10, 0x01, op[0].hcode, op[2].address, op[1].hlcode
|
|
457
|
+
)
|
|
458
|
+
+ bytearray([0xDE])
|
|
459
|
+
+ modrm_sib_disp(op[0].lcode, op[2].address, sib, min_disp),
|
|
460
|
+
)
|
|
461
|
+
)
|
|
462
|
+
else:
|
|
463
|
+
raise SyntaxError(
|
|
464
|
+
"Invalid operand types: VAESDEC "
|
|
465
|
+
+ ", ".join(map(format_operand_type, self.operands))
|
|
466
|
+
)
|
|
467
|
+
if nervapy.stream.active_stream is not None:
|
|
468
|
+
nervapy.stream.active_stream.add_instruction(self)
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
class VAESDECLAST(Instruction):
|
|
472
|
+
"""Perform Last Round of an AES Decryption Flow"""
|
|
473
|
+
|
|
474
|
+
def __init__(self, *args, **kwargs):
|
|
475
|
+
"""Supported forms:
|
|
476
|
+
|
|
477
|
+
* VAESDECLAST(xmm, xmm, xmm/m128) [AVX and AES]
|
|
478
|
+
"""
|
|
479
|
+
|
|
480
|
+
origin = kwargs.get("origin")
|
|
481
|
+
prototype = kwargs.get("prototype")
|
|
482
|
+
if (
|
|
483
|
+
origin is None
|
|
484
|
+
and prototype is None
|
|
485
|
+
and nervapy.x86_64.options.get_debug_level() > 0
|
|
486
|
+
):
|
|
487
|
+
origin = inspect.stack()
|
|
488
|
+
super(VAESDECLAST, self).__init__(
|
|
489
|
+
"VAESDECLAST", origin=origin, prototype=prototype
|
|
490
|
+
)
|
|
491
|
+
self.operands = tuple(map(check_operand, args))
|
|
492
|
+
if len(self.operands) != 3:
|
|
493
|
+
raise SyntaxError('Instruction "VAESDECLAST" requires 3 operands')
|
|
494
|
+
self.in_regs = (False, True, True)
|
|
495
|
+
self.out_regs = (True, False, False)
|
|
496
|
+
self.out_operands = (True, False, False)
|
|
497
|
+
self.avx_mode = True
|
|
498
|
+
self.isa_extensions = frozenset(
|
|
499
|
+
[nervapy.x86_64.isa.avx, nervapy.x86_64.isa.aes]
|
|
500
|
+
)
|
|
501
|
+
if (
|
|
502
|
+
is_xmm(self.operands[0])
|
|
503
|
+
and is_xmm(self.operands[1])
|
|
504
|
+
and is_xmm(self.operands[2])
|
|
505
|
+
):
|
|
506
|
+
self.encodings.append(
|
|
507
|
+
(
|
|
508
|
+
0x00,
|
|
509
|
+
lambda op: bytearray(
|
|
510
|
+
[
|
|
511
|
+
0xC4,
|
|
512
|
+
0xE2 ^ (op[0].hcode << 7) ^ (op[2].hcode << 5),
|
|
513
|
+
0x79 ^ (op[1].hlcode << 3),
|
|
514
|
+
0xDF,
|
|
515
|
+
0xC0 | op[0].lcode << 3 | op[2].lcode,
|
|
516
|
+
]
|
|
517
|
+
),
|
|
518
|
+
)
|
|
519
|
+
)
|
|
520
|
+
elif (
|
|
521
|
+
is_xmm(self.operands[0])
|
|
522
|
+
and is_xmm(self.operands[1])
|
|
523
|
+
and is_m128(self.operands[2])
|
|
524
|
+
):
|
|
525
|
+
self.encodings.append(
|
|
526
|
+
(
|
|
527
|
+
0x10,
|
|
528
|
+
lambda op, sib=False, min_disp=0: vex3(
|
|
529
|
+
0xC4, 0b10, 0x01, op[0].hcode, op[2].address, op[1].hlcode
|
|
530
|
+
)
|
|
531
|
+
+ bytearray([0xDF])
|
|
532
|
+
+ modrm_sib_disp(op[0].lcode, op[2].address, sib, min_disp),
|
|
533
|
+
)
|
|
534
|
+
)
|
|
535
|
+
else:
|
|
536
|
+
raise SyntaxError(
|
|
537
|
+
"Invalid operand types: VAESDECLAST "
|
|
538
|
+
+ ", ".join(map(format_operand_type, self.operands))
|
|
539
|
+
)
|
|
540
|
+
if nervapy.stream.active_stream is not None:
|
|
541
|
+
nervapy.stream.active_stream.add_instruction(self)
|
|
542
|
+
|
|
543
|
+
|
|
544
|
+
class VAESENC(Instruction):
|
|
545
|
+
"""Perform One Round of an AES Encryption Flow"""
|
|
546
|
+
|
|
547
|
+
def __init__(self, *args, **kwargs):
|
|
548
|
+
"""Supported forms:
|
|
549
|
+
|
|
550
|
+
* VAESENC(xmm, xmm, xmm/m128) [AVX and AES]
|
|
551
|
+
"""
|
|
552
|
+
|
|
553
|
+
origin = kwargs.get("origin")
|
|
554
|
+
prototype = kwargs.get("prototype")
|
|
555
|
+
if (
|
|
556
|
+
origin is None
|
|
557
|
+
and prototype is None
|
|
558
|
+
and nervapy.x86_64.options.get_debug_level() > 0
|
|
559
|
+
):
|
|
560
|
+
origin = inspect.stack()
|
|
561
|
+
super(VAESENC, self).__init__("VAESENC", origin=origin, prototype=prototype)
|
|
562
|
+
self.operands = tuple(map(check_operand, args))
|
|
563
|
+
if len(self.operands) != 3:
|
|
564
|
+
raise SyntaxError('Instruction "VAESENC" requires 3 operands')
|
|
565
|
+
self.in_regs = (False, True, True)
|
|
566
|
+
self.out_regs = (True, False, False)
|
|
567
|
+
self.out_operands = (True, False, False)
|
|
568
|
+
self.avx_mode = True
|
|
569
|
+
self.isa_extensions = frozenset(
|
|
570
|
+
[nervapy.x86_64.isa.avx, nervapy.x86_64.isa.aes]
|
|
571
|
+
)
|
|
572
|
+
if (
|
|
573
|
+
is_xmm(self.operands[0])
|
|
574
|
+
and is_xmm(self.operands[1])
|
|
575
|
+
and is_xmm(self.operands[2])
|
|
576
|
+
):
|
|
577
|
+
self.encodings.append(
|
|
578
|
+
(
|
|
579
|
+
0x00,
|
|
580
|
+
lambda op: bytearray(
|
|
581
|
+
[
|
|
582
|
+
0xC4,
|
|
583
|
+
0xE2 ^ (op[0].hcode << 7) ^ (op[2].hcode << 5),
|
|
584
|
+
0x79 ^ (op[1].hlcode << 3),
|
|
585
|
+
0xDC,
|
|
586
|
+
0xC0 | op[0].lcode << 3 | op[2].lcode,
|
|
587
|
+
]
|
|
588
|
+
),
|
|
589
|
+
)
|
|
590
|
+
)
|
|
591
|
+
elif (
|
|
592
|
+
is_xmm(self.operands[0])
|
|
593
|
+
and is_xmm(self.operands[1])
|
|
594
|
+
and is_m128(self.operands[2])
|
|
595
|
+
):
|
|
596
|
+
self.encodings.append(
|
|
597
|
+
(
|
|
598
|
+
0x10,
|
|
599
|
+
lambda op, sib=False, min_disp=0: vex3(
|
|
600
|
+
0xC4, 0b10, 0x01, op[0].hcode, op[2].address, op[1].hlcode
|
|
601
|
+
)
|
|
602
|
+
+ bytearray([0xDC])
|
|
603
|
+
+ modrm_sib_disp(op[0].lcode, op[2].address, sib, min_disp),
|
|
604
|
+
)
|
|
605
|
+
)
|
|
606
|
+
else:
|
|
607
|
+
raise SyntaxError(
|
|
608
|
+
"Invalid operand types: VAESENC "
|
|
609
|
+
+ ", ".join(map(format_operand_type, self.operands))
|
|
610
|
+
)
|
|
611
|
+
if nervapy.stream.active_stream is not None:
|
|
612
|
+
nervapy.stream.active_stream.add_instruction(self)
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
class VAESENCLAST(Instruction):
|
|
616
|
+
"""Perform Last Round of an AES Encryption Flow"""
|
|
617
|
+
|
|
618
|
+
def __init__(self, *args, **kwargs):
|
|
619
|
+
"""Supported forms:
|
|
620
|
+
|
|
621
|
+
* VAESENCLAST(xmm, xmm, xmm/m128) [AVX and AES]
|
|
622
|
+
"""
|
|
623
|
+
|
|
624
|
+
origin = kwargs.get("origin")
|
|
625
|
+
prototype = kwargs.get("prototype")
|
|
626
|
+
if (
|
|
627
|
+
origin is None
|
|
628
|
+
and prototype is None
|
|
629
|
+
and nervapy.x86_64.options.get_debug_level() > 0
|
|
630
|
+
):
|
|
631
|
+
origin = inspect.stack()
|
|
632
|
+
super(VAESENCLAST, self).__init__(
|
|
633
|
+
"VAESENCLAST", origin=origin, prototype=prototype
|
|
634
|
+
)
|
|
635
|
+
self.operands = tuple(map(check_operand, args))
|
|
636
|
+
if len(self.operands) != 3:
|
|
637
|
+
raise SyntaxError('Instruction "VAESENCLAST" requires 3 operands')
|
|
638
|
+
self.in_regs = (False, True, True)
|
|
639
|
+
self.out_regs = (True, False, False)
|
|
640
|
+
self.out_operands = (True, False, False)
|
|
641
|
+
self.avx_mode = True
|
|
642
|
+
self.isa_extensions = frozenset(
|
|
643
|
+
[nervapy.x86_64.isa.avx, nervapy.x86_64.isa.aes]
|
|
644
|
+
)
|
|
645
|
+
if (
|
|
646
|
+
is_xmm(self.operands[0])
|
|
647
|
+
and is_xmm(self.operands[1])
|
|
648
|
+
and is_xmm(self.operands[2])
|
|
649
|
+
):
|
|
650
|
+
self.encodings.append(
|
|
651
|
+
(
|
|
652
|
+
0x00,
|
|
653
|
+
lambda op: bytearray(
|
|
654
|
+
[
|
|
655
|
+
0xC4,
|
|
656
|
+
0xE2 ^ (op[0].hcode << 7) ^ (op[2].hcode << 5),
|
|
657
|
+
0x79 ^ (op[1].hlcode << 3),
|
|
658
|
+
0xDD,
|
|
659
|
+
0xC0 | op[0].lcode << 3 | op[2].lcode,
|
|
660
|
+
]
|
|
661
|
+
),
|
|
662
|
+
)
|
|
663
|
+
)
|
|
664
|
+
elif (
|
|
665
|
+
is_xmm(self.operands[0])
|
|
666
|
+
and is_xmm(self.operands[1])
|
|
667
|
+
and is_m128(self.operands[2])
|
|
668
|
+
):
|
|
669
|
+
self.encodings.append(
|
|
670
|
+
(
|
|
671
|
+
0x10,
|
|
672
|
+
lambda op, sib=False, min_disp=0: vex3(
|
|
673
|
+
0xC4, 0b10, 0x01, op[0].hcode, op[2].address, op[1].hlcode
|
|
674
|
+
)
|
|
675
|
+
+ bytearray([0xDD])
|
|
676
|
+
+ modrm_sib_disp(op[0].lcode, op[2].address, sib, min_disp),
|
|
677
|
+
)
|
|
678
|
+
)
|
|
679
|
+
else:
|
|
680
|
+
raise SyntaxError(
|
|
681
|
+
"Invalid operand types: VAESENCLAST "
|
|
682
|
+
+ ", ".join(map(format_operand_type, self.operands))
|
|
683
|
+
)
|
|
684
|
+
if nervapy.stream.active_stream is not None:
|
|
685
|
+
nervapy.stream.active_stream.add_instruction(self)
|
|
686
|
+
|
|
687
|
+
|
|
688
|
+
class VAESIMC(Instruction):
|
|
689
|
+
"""Perform the AES InvMixColumn Transformation"""
|
|
690
|
+
|
|
691
|
+
def __init__(self, *args, **kwargs):
|
|
692
|
+
"""Supported forms:
|
|
693
|
+
|
|
694
|
+
* VAESIMC(xmm, xmm/m128) [AVX and AES]
|
|
695
|
+
"""
|
|
696
|
+
|
|
697
|
+
origin = kwargs.get("origin")
|
|
698
|
+
prototype = kwargs.get("prototype")
|
|
699
|
+
if (
|
|
700
|
+
origin is None
|
|
701
|
+
and prototype is None
|
|
702
|
+
and nervapy.x86_64.options.get_debug_level() > 0
|
|
703
|
+
):
|
|
704
|
+
origin = inspect.stack()
|
|
705
|
+
super(VAESIMC, self).__init__("VAESIMC", origin=origin, prototype=prototype)
|
|
706
|
+
self.operands = tuple(map(check_operand, args))
|
|
707
|
+
if len(self.operands) != 2:
|
|
708
|
+
raise SyntaxError('Instruction "VAESIMC" requires 2 operands')
|
|
709
|
+
self.in_regs = (False, True)
|
|
710
|
+
self.out_regs = (True, False)
|
|
711
|
+
self.out_operands = (True, False)
|
|
712
|
+
self.avx_mode = True
|
|
713
|
+
self.isa_extensions = frozenset(
|
|
714
|
+
[nervapy.x86_64.isa.avx, nervapy.x86_64.isa.aes]
|
|
715
|
+
)
|
|
716
|
+
if is_xmm(self.operands[0]) and is_xmm(self.operands[1]):
|
|
717
|
+
self.encodings.append(
|
|
718
|
+
(
|
|
719
|
+
0x00,
|
|
720
|
+
lambda op: bytearray(
|
|
721
|
+
[
|
|
722
|
+
0xC4,
|
|
723
|
+
0xE2 ^ (op[0].hcode << 7) ^ (op[1].hcode << 5),
|
|
724
|
+
0x79,
|
|
725
|
+
0xDB,
|
|
726
|
+
0xC0 | op[0].lcode << 3 | op[1].lcode,
|
|
727
|
+
]
|
|
728
|
+
),
|
|
729
|
+
)
|
|
730
|
+
)
|
|
731
|
+
elif is_xmm(self.operands[0]) and is_m128(self.operands[1]):
|
|
732
|
+
self.encodings.append(
|
|
733
|
+
(
|
|
734
|
+
0x10,
|
|
735
|
+
lambda op, sib=False, min_disp=0: vex3(
|
|
736
|
+
0xC4, 0b10, 0x01, op[0].hcode, op[1].address
|
|
737
|
+
)
|
|
738
|
+
+ bytearray([0xDB])
|
|
739
|
+
+ modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp),
|
|
740
|
+
)
|
|
741
|
+
)
|
|
742
|
+
else:
|
|
743
|
+
raise SyntaxError(
|
|
744
|
+
"Invalid operand types: VAESIMC "
|
|
745
|
+
+ ", ".join(map(format_operand_type, self.operands))
|
|
746
|
+
)
|
|
747
|
+
if nervapy.stream.active_stream is not None:
|
|
748
|
+
nervapy.stream.active_stream.add_instruction(self)
|
|
749
|
+
|
|
750
|
+
|
|
751
|
+
class VAESKEYGENASSIST(Instruction):
|
|
752
|
+
"""AES Round Key Generation Assist"""
|
|
753
|
+
|
|
754
|
+
def __init__(self, *args, **kwargs):
|
|
755
|
+
"""Supported forms:
|
|
756
|
+
|
|
757
|
+
* VAESKEYGENASSIST(xmm, xmm/m128, imm8) [AVX and AES]
|
|
758
|
+
"""
|
|
759
|
+
|
|
760
|
+
origin = kwargs.get("origin")
|
|
761
|
+
prototype = kwargs.get("prototype")
|
|
762
|
+
if (
|
|
763
|
+
origin is None
|
|
764
|
+
and prototype is None
|
|
765
|
+
and nervapy.x86_64.options.get_debug_level() > 0
|
|
766
|
+
):
|
|
767
|
+
origin = inspect.stack()
|
|
768
|
+
super(VAESKEYGENASSIST, self).__init__(
|
|
769
|
+
"VAESKEYGENASSIST", origin=origin, prototype=prototype
|
|
770
|
+
)
|
|
771
|
+
self.operands = tuple(map(check_operand, args))
|
|
772
|
+
if len(self.operands) != 3:
|
|
773
|
+
raise SyntaxError('Instruction "VAESKEYGENASSIST" requires 3 operands')
|
|
774
|
+
self.in_regs = (False, True, False)
|
|
775
|
+
self.out_regs = (True, False, False)
|
|
776
|
+
self.out_operands = (True, False, False)
|
|
777
|
+
self.avx_mode = True
|
|
778
|
+
self.isa_extensions = frozenset(
|
|
779
|
+
[nervapy.x86_64.isa.avx, nervapy.x86_64.isa.aes]
|
|
780
|
+
)
|
|
781
|
+
if (
|
|
782
|
+
is_xmm(self.operands[0])
|
|
783
|
+
and is_xmm(self.operands[1])
|
|
784
|
+
and is_imm(self.operands[2])
|
|
785
|
+
):
|
|
786
|
+
if not is_imm8(self.operands[2]):
|
|
787
|
+
raise ValueError("Argument #2 can not be encoded as imm8")
|
|
788
|
+
self.encodings.append(
|
|
789
|
+
(
|
|
790
|
+
0x00,
|
|
791
|
+
lambda op: bytearray(
|
|
792
|
+
[
|
|
793
|
+
0xC4,
|
|
794
|
+
0xE3 ^ (op[0].hcode << 7) ^ (op[1].hcode << 5),
|
|
795
|
+
0x79,
|
|
796
|
+
0xDF,
|
|
797
|
+
0xC0 | op[0].lcode << 3 | op[1].lcode,
|
|
798
|
+
op[2] & 0xFF,
|
|
799
|
+
]
|
|
800
|
+
),
|
|
801
|
+
)
|
|
802
|
+
)
|
|
803
|
+
elif (
|
|
804
|
+
is_xmm(self.operands[0])
|
|
805
|
+
and is_m128(self.operands[1])
|
|
806
|
+
and is_imm(self.operands[2])
|
|
807
|
+
):
|
|
808
|
+
if not is_imm8(self.operands[2]):
|
|
809
|
+
raise ValueError("Argument #2 can not be encoded as imm8")
|
|
810
|
+
self.encodings.append(
|
|
811
|
+
(
|
|
812
|
+
0x10,
|
|
813
|
+
lambda op, sib=False, min_disp=0: vex3(
|
|
814
|
+
0xC4, 0b11, 0x01, op[0].hcode, op[1].address
|
|
815
|
+
)
|
|
816
|
+
+ bytearray([0xDF])
|
|
817
|
+
+ modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)
|
|
818
|
+
+ bytearray([op[2] & 0xFF]),
|
|
819
|
+
)
|
|
820
|
+
)
|
|
821
|
+
else:
|
|
822
|
+
raise SyntaxError(
|
|
823
|
+
"Invalid operand types: VAESKEYGENASSIST "
|
|
824
|
+
+ ", ".join(map(format_operand_type, self.operands))
|
|
825
|
+
)
|
|
826
|
+
if nervapy.stream.active_stream is not None:
|
|
827
|
+
nervapy.stream.active_stream.add_instruction(self)
|
|
828
|
+
|
|
829
|
+
|
|
830
|
+
class SHA1MSG1(Instruction):
|
|
831
|
+
"""Perform an Intermediate Calculation for the Next Four SHA1 Message Doublewords"""
|
|
832
|
+
|
|
833
|
+
def __init__(self, *args, **kwargs):
|
|
834
|
+
"""Supported forms:
|
|
835
|
+
|
|
836
|
+
* SHA1MSG1(xmm, xmm/m128) [SHA]
|
|
837
|
+
"""
|
|
838
|
+
|
|
839
|
+
origin = kwargs.get("origin")
|
|
840
|
+
prototype = kwargs.get("prototype")
|
|
841
|
+
if (
|
|
842
|
+
origin is None
|
|
843
|
+
and prototype is None
|
|
844
|
+
and nervapy.x86_64.options.get_debug_level() > 0
|
|
845
|
+
):
|
|
846
|
+
origin = inspect.stack()
|
|
847
|
+
super(SHA1MSG1, self).__init__("SHA1MSG1", origin=origin, prototype=prototype)
|
|
848
|
+
self.operands = tuple(map(check_operand, args))
|
|
849
|
+
if len(self.operands) != 2:
|
|
850
|
+
raise SyntaxError('Instruction "SHA1MSG1" requires 2 operands')
|
|
851
|
+
self.in_regs = (True, True)
|
|
852
|
+
self.out_regs = (True, False)
|
|
853
|
+
self.out_operands = (True, False)
|
|
854
|
+
self.avx_mode = False
|
|
855
|
+
self.isa_extensions = frozenset([nervapy.x86_64.isa.sha])
|
|
856
|
+
if is_xmm(self.operands[0]) and is_xmm(self.operands[1]):
|
|
857
|
+
self.encodings.append(
|
|
858
|
+
(
|
|
859
|
+
0x20,
|
|
860
|
+
lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex)
|
|
861
|
+
+ bytearray(
|
|
862
|
+
[0x0F, 0x38, 0xC9, 0xC0 | op[0].lcode << 3 | op[1].lcode]
|
|
863
|
+
),
|
|
864
|
+
)
|
|
865
|
+
)
|
|
866
|
+
elif is_xmm(self.operands[0]) and is_m128(self.operands[1]):
|
|
867
|
+
self.encodings.append(
|
|
868
|
+
(
|
|
869
|
+
0x30,
|
|
870
|
+
lambda op, rex=False, sib=False, min_disp=0: optional_rex(
|
|
871
|
+
op[0].hcode, op[1].address, rex
|
|
872
|
+
)
|
|
873
|
+
+ bytearray([0x0F, 0x38, 0xC9])
|
|
874
|
+
+ modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp),
|
|
875
|
+
)
|
|
876
|
+
)
|
|
877
|
+
else:
|
|
878
|
+
raise SyntaxError(
|
|
879
|
+
"Invalid operand types: SHA1MSG1 "
|
|
880
|
+
+ ", ".join(map(format_operand_type, self.operands))
|
|
881
|
+
)
|
|
882
|
+
if nervapy.stream.active_stream is not None:
|
|
883
|
+
nervapy.stream.active_stream.add_instruction(self)
|
|
884
|
+
|
|
885
|
+
|
|
886
|
+
class SHA1MSG2(Instruction):
|
|
887
|
+
"""Perform a Final Calculation for the Next Four SHA1 Message Doublewords"""
|
|
888
|
+
|
|
889
|
+
def __init__(self, *args, **kwargs):
|
|
890
|
+
"""Supported forms:
|
|
891
|
+
|
|
892
|
+
* SHA1MSG2(xmm, xmm/m128) [SHA]
|
|
893
|
+
"""
|
|
894
|
+
|
|
895
|
+
origin = kwargs.get("origin")
|
|
896
|
+
prototype = kwargs.get("prototype")
|
|
897
|
+
if (
|
|
898
|
+
origin is None
|
|
899
|
+
and prototype is None
|
|
900
|
+
and nervapy.x86_64.options.get_debug_level() > 0
|
|
901
|
+
):
|
|
902
|
+
origin = inspect.stack()
|
|
903
|
+
super(SHA1MSG2, self).__init__("SHA1MSG2", origin=origin, prototype=prototype)
|
|
904
|
+
self.operands = tuple(map(check_operand, args))
|
|
905
|
+
if len(self.operands) != 2:
|
|
906
|
+
raise SyntaxError('Instruction "SHA1MSG2" requires 2 operands')
|
|
907
|
+
self.in_regs = (True, True)
|
|
908
|
+
self.out_regs = (True, False)
|
|
909
|
+
self.out_operands = (True, False)
|
|
910
|
+
self.avx_mode = False
|
|
911
|
+
self.isa_extensions = frozenset([nervapy.x86_64.isa.sha])
|
|
912
|
+
if is_xmm(self.operands[0]) and is_xmm(self.operands[1]):
|
|
913
|
+
self.encodings.append(
|
|
914
|
+
(
|
|
915
|
+
0x20,
|
|
916
|
+
lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex)
|
|
917
|
+
+ bytearray(
|
|
918
|
+
[0x0F, 0x38, 0xCA, 0xC0 | op[0].lcode << 3 | op[1].lcode]
|
|
919
|
+
),
|
|
920
|
+
)
|
|
921
|
+
)
|
|
922
|
+
elif is_xmm(self.operands[0]) and is_m128(self.operands[1]):
|
|
923
|
+
self.encodings.append(
|
|
924
|
+
(
|
|
925
|
+
0x30,
|
|
926
|
+
lambda op, rex=False, sib=False, min_disp=0: optional_rex(
|
|
927
|
+
op[0].hcode, op[1].address, rex
|
|
928
|
+
)
|
|
929
|
+
+ bytearray([0x0F, 0x38, 0xCA])
|
|
930
|
+
+ modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp),
|
|
931
|
+
)
|
|
932
|
+
)
|
|
933
|
+
else:
|
|
934
|
+
raise SyntaxError(
|
|
935
|
+
"Invalid operand types: SHA1MSG2 "
|
|
936
|
+
+ ", ".join(map(format_operand_type, self.operands))
|
|
937
|
+
)
|
|
938
|
+
if nervapy.stream.active_stream is not None:
|
|
939
|
+
nervapy.stream.active_stream.add_instruction(self)
|
|
940
|
+
|
|
941
|
+
|
|
942
|
+
class SHA1NEXTE(Instruction):
|
|
943
|
+
"""Calculate SHA1 State Variable E after Four Rounds"""
|
|
944
|
+
|
|
945
|
+
def __init__(self, *args, **kwargs):
|
|
946
|
+
"""Supported forms:
|
|
947
|
+
|
|
948
|
+
* SHA1NEXTE(xmm, xmm/m128) [SHA]
|
|
949
|
+
"""
|
|
950
|
+
|
|
951
|
+
origin = kwargs.get("origin")
|
|
952
|
+
prototype = kwargs.get("prototype")
|
|
953
|
+
if (
|
|
954
|
+
origin is None
|
|
955
|
+
and prototype is None
|
|
956
|
+
and nervapy.x86_64.options.get_debug_level() > 0
|
|
957
|
+
):
|
|
958
|
+
origin = inspect.stack()
|
|
959
|
+
super(SHA1NEXTE, self).__init__("SHA1NEXTE", origin=origin, prototype=prototype)
|
|
960
|
+
self.operands = tuple(map(check_operand, args))
|
|
961
|
+
if len(self.operands) != 2:
|
|
962
|
+
raise SyntaxError('Instruction "SHA1NEXTE" requires 2 operands')
|
|
963
|
+
self.in_regs = (True, True)
|
|
964
|
+
self.out_regs = (True, False)
|
|
965
|
+
self.out_operands = (True, False)
|
|
966
|
+
self.avx_mode = False
|
|
967
|
+
self.isa_extensions = frozenset([nervapy.x86_64.isa.sha])
|
|
968
|
+
if is_xmm(self.operands[0]) and is_xmm(self.operands[1]):
|
|
969
|
+
self.encodings.append(
|
|
970
|
+
(
|
|
971
|
+
0x20,
|
|
972
|
+
lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex)
|
|
973
|
+
+ bytearray(
|
|
974
|
+
[0x0F, 0x38, 0xC8, 0xC0 | op[0].lcode << 3 | op[1].lcode]
|
|
975
|
+
),
|
|
976
|
+
)
|
|
977
|
+
)
|
|
978
|
+
elif is_xmm(self.operands[0]) and is_m128(self.operands[1]):
|
|
979
|
+
self.encodings.append(
|
|
980
|
+
(
|
|
981
|
+
0x30,
|
|
982
|
+
lambda op, rex=False, sib=False, min_disp=0: optional_rex(
|
|
983
|
+
op[0].hcode, op[1].address, rex
|
|
984
|
+
)
|
|
985
|
+
+ bytearray([0x0F, 0x38, 0xC8])
|
|
986
|
+
+ modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp),
|
|
987
|
+
)
|
|
988
|
+
)
|
|
989
|
+
else:
|
|
990
|
+
raise SyntaxError(
|
|
991
|
+
"Invalid operand types: SHA1NEXTE "
|
|
992
|
+
+ ", ".join(map(format_operand_type, self.operands))
|
|
993
|
+
)
|
|
994
|
+
if nervapy.stream.active_stream is not None:
|
|
995
|
+
nervapy.stream.active_stream.add_instruction(self)
|
|
996
|
+
|
|
997
|
+
|
|
998
|
+
class SHA1RNDS4(Instruction):
|
|
999
|
+
"""Perform Four Rounds of SHA1 Operation"""
|
|
1000
|
+
|
|
1001
|
+
def __init__(self, *args, **kwargs):
|
|
1002
|
+
"""Supported forms:
|
|
1003
|
+
|
|
1004
|
+
* SHA1RNDS4(xmm, xmm/m128, imm8) [SHA]
|
|
1005
|
+
"""
|
|
1006
|
+
|
|
1007
|
+
origin = kwargs.get("origin")
|
|
1008
|
+
prototype = kwargs.get("prototype")
|
|
1009
|
+
if (
|
|
1010
|
+
origin is None
|
|
1011
|
+
and prototype is None
|
|
1012
|
+
and nervapy.x86_64.options.get_debug_level() > 0
|
|
1013
|
+
):
|
|
1014
|
+
origin = inspect.stack()
|
|
1015
|
+
super(SHA1RNDS4, self).__init__("SHA1RNDS4", origin=origin, prototype=prototype)
|
|
1016
|
+
self.operands = tuple(map(check_operand, args))
|
|
1017
|
+
if len(self.operands) != 3:
|
|
1018
|
+
raise SyntaxError('Instruction "SHA1RNDS4" requires 3 operands')
|
|
1019
|
+
self.in_regs = (True, True, False)
|
|
1020
|
+
self.out_regs = (True, False, False)
|
|
1021
|
+
self.out_operands = (True, False, False)
|
|
1022
|
+
self.avx_mode = False
|
|
1023
|
+
self.isa_extensions = frozenset([nervapy.x86_64.isa.sha])
|
|
1024
|
+
if (
|
|
1025
|
+
is_xmm(self.operands[0])
|
|
1026
|
+
and is_xmm(self.operands[1])
|
|
1027
|
+
and is_imm(self.operands[2])
|
|
1028
|
+
):
|
|
1029
|
+
if not is_imm8(self.operands[2]):
|
|
1030
|
+
raise ValueError("Argument #2 can not be encoded as imm8")
|
|
1031
|
+
self.encodings.append(
|
|
1032
|
+
(
|
|
1033
|
+
0x20,
|
|
1034
|
+
lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex)
|
|
1035
|
+
+ bytearray(
|
|
1036
|
+
[
|
|
1037
|
+
0x0F,
|
|
1038
|
+
0x3A,
|
|
1039
|
+
0xCC,
|
|
1040
|
+
0xC0 | op[0].lcode << 3 | op[1].lcode,
|
|
1041
|
+
op[2] & 0xFF,
|
|
1042
|
+
]
|
|
1043
|
+
),
|
|
1044
|
+
)
|
|
1045
|
+
)
|
|
1046
|
+
elif (
|
|
1047
|
+
is_xmm(self.operands[0])
|
|
1048
|
+
and is_m128(self.operands[1])
|
|
1049
|
+
and is_imm(self.operands[2])
|
|
1050
|
+
):
|
|
1051
|
+
if not is_imm8(self.operands[2]):
|
|
1052
|
+
raise ValueError("Argument #2 can not be encoded as imm8")
|
|
1053
|
+
self.encodings.append(
|
|
1054
|
+
(
|
|
1055
|
+
0x30,
|
|
1056
|
+
lambda op, rex=False, sib=False, min_disp=0: optional_rex(
|
|
1057
|
+
op[0].hcode, op[1].address, rex
|
|
1058
|
+
)
|
|
1059
|
+
+ bytearray([0x0F, 0x3A, 0xCC])
|
|
1060
|
+
+ modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)
|
|
1061
|
+
+ bytearray([op[2] & 0xFF]),
|
|
1062
|
+
)
|
|
1063
|
+
)
|
|
1064
|
+
else:
|
|
1065
|
+
raise SyntaxError(
|
|
1066
|
+
"Invalid operand types: SHA1RNDS4 "
|
|
1067
|
+
+ ", ".join(map(format_operand_type, self.operands))
|
|
1068
|
+
)
|
|
1069
|
+
if nervapy.stream.active_stream is not None:
|
|
1070
|
+
nervapy.stream.active_stream.add_instruction(self)
|
|
1071
|
+
|
|
1072
|
+
|
|
1073
|
+
class SHA256MSG1(Instruction):
|
|
1074
|
+
"""Perform an Intermediate Calculation for the Next Four SHA256 Message Doublewords"""
|
|
1075
|
+
|
|
1076
|
+
def __init__(self, *args, **kwargs):
|
|
1077
|
+
"""Supported forms:
|
|
1078
|
+
|
|
1079
|
+
* SHA256MSG1(xmm, xmm/m128) [SHA]
|
|
1080
|
+
"""
|
|
1081
|
+
|
|
1082
|
+
origin = kwargs.get("origin")
|
|
1083
|
+
prototype = kwargs.get("prototype")
|
|
1084
|
+
if (
|
|
1085
|
+
origin is None
|
|
1086
|
+
and prototype is None
|
|
1087
|
+
and nervapy.x86_64.options.get_debug_level() > 0
|
|
1088
|
+
):
|
|
1089
|
+
origin = inspect.stack()
|
|
1090
|
+
super(SHA256MSG1, self).__init__(
|
|
1091
|
+
"SHA256MSG1", origin=origin, prototype=prototype
|
|
1092
|
+
)
|
|
1093
|
+
self.operands = tuple(map(check_operand, args))
|
|
1094
|
+
if len(self.operands) != 2:
|
|
1095
|
+
raise SyntaxError('Instruction "SHA256MSG1" requires 2 operands')
|
|
1096
|
+
self.in_regs = (True, True)
|
|
1097
|
+
self.out_regs = (True, False)
|
|
1098
|
+
self.out_operands = (True, False)
|
|
1099
|
+
self.avx_mode = False
|
|
1100
|
+
self.isa_extensions = frozenset([nervapy.x86_64.isa.sha])
|
|
1101
|
+
if is_xmm(self.operands[0]) and is_xmm(self.operands[1]):
|
|
1102
|
+
self.encodings.append(
|
|
1103
|
+
(
|
|
1104
|
+
0x20,
|
|
1105
|
+
lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex)
|
|
1106
|
+
+ bytearray(
|
|
1107
|
+
[0x0F, 0x38, 0xCC, 0xC0 | op[0].lcode << 3 | op[1].lcode]
|
|
1108
|
+
),
|
|
1109
|
+
)
|
|
1110
|
+
)
|
|
1111
|
+
elif is_xmm(self.operands[0]) and is_m128(self.operands[1]):
|
|
1112
|
+
self.encodings.append(
|
|
1113
|
+
(
|
|
1114
|
+
0x30,
|
|
1115
|
+
lambda op, rex=False, sib=False, min_disp=0: optional_rex(
|
|
1116
|
+
op[0].hcode, op[1].address, rex
|
|
1117
|
+
)
|
|
1118
|
+
+ bytearray([0x0F, 0x38, 0xCC])
|
|
1119
|
+
+ modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp),
|
|
1120
|
+
)
|
|
1121
|
+
)
|
|
1122
|
+
else:
|
|
1123
|
+
raise SyntaxError(
|
|
1124
|
+
"Invalid operand types: SHA256MSG1 "
|
|
1125
|
+
+ ", ".join(map(format_operand_type, self.operands))
|
|
1126
|
+
)
|
|
1127
|
+
if nervapy.stream.active_stream is not None:
|
|
1128
|
+
nervapy.stream.active_stream.add_instruction(self)
|
|
1129
|
+
|
|
1130
|
+
|
|
1131
|
+
class SHA256MSG2(Instruction):
|
|
1132
|
+
"""Perform a Final Calculation for the Next Four SHA256 Message Doublewords"""
|
|
1133
|
+
|
|
1134
|
+
def __init__(self, *args, **kwargs):
|
|
1135
|
+
"""Supported forms:
|
|
1136
|
+
|
|
1137
|
+
* SHA256MSG2(xmm, xmm/m128) [SHA]
|
|
1138
|
+
"""
|
|
1139
|
+
|
|
1140
|
+
origin = kwargs.get("origin")
|
|
1141
|
+
prototype = kwargs.get("prototype")
|
|
1142
|
+
if (
|
|
1143
|
+
origin is None
|
|
1144
|
+
and prototype is None
|
|
1145
|
+
and nervapy.x86_64.options.get_debug_level() > 0
|
|
1146
|
+
):
|
|
1147
|
+
origin = inspect.stack()
|
|
1148
|
+
super(SHA256MSG2, self).__init__(
|
|
1149
|
+
"SHA256MSG2", origin=origin, prototype=prototype
|
|
1150
|
+
)
|
|
1151
|
+
self.operands = tuple(map(check_operand, args))
|
|
1152
|
+
if len(self.operands) != 2:
|
|
1153
|
+
raise SyntaxError('Instruction "SHA256MSG2" requires 2 operands')
|
|
1154
|
+
self.in_regs = (True, True)
|
|
1155
|
+
self.out_regs = (True, False)
|
|
1156
|
+
self.out_operands = (True, False)
|
|
1157
|
+
self.avx_mode = False
|
|
1158
|
+
self.isa_extensions = frozenset([nervapy.x86_64.isa.sha])
|
|
1159
|
+
if is_xmm(self.operands[0]) and is_xmm(self.operands[1]):
|
|
1160
|
+
self.encodings.append(
|
|
1161
|
+
(
|
|
1162
|
+
0x20,
|
|
1163
|
+
lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex)
|
|
1164
|
+
+ bytearray(
|
|
1165
|
+
[0x0F, 0x38, 0xCD, 0xC0 | op[0].lcode << 3 | op[1].lcode]
|
|
1166
|
+
),
|
|
1167
|
+
)
|
|
1168
|
+
)
|
|
1169
|
+
elif is_xmm(self.operands[0]) and is_m128(self.operands[1]):
|
|
1170
|
+
self.encodings.append(
|
|
1171
|
+
(
|
|
1172
|
+
0x30,
|
|
1173
|
+
lambda op, rex=False, sib=False, min_disp=0: optional_rex(
|
|
1174
|
+
op[0].hcode, op[1].address, rex
|
|
1175
|
+
)
|
|
1176
|
+
+ bytearray([0x0F, 0x38, 0xCD])
|
|
1177
|
+
+ modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp),
|
|
1178
|
+
)
|
|
1179
|
+
)
|
|
1180
|
+
else:
|
|
1181
|
+
raise SyntaxError(
|
|
1182
|
+
"Invalid operand types: SHA256MSG2 "
|
|
1183
|
+
+ ", ".join(map(format_operand_type, self.operands))
|
|
1184
|
+
)
|
|
1185
|
+
if nervapy.stream.active_stream is not None:
|
|
1186
|
+
nervapy.stream.active_stream.add_instruction(self)
|
|
1187
|
+
|
|
1188
|
+
|
|
1189
|
+
class SHA256RNDS2(Instruction):
|
|
1190
|
+
"""Perform Two Rounds of SHA256 Operation"""
|
|
1191
|
+
|
|
1192
|
+
def __init__(self, *args, **kwargs):
|
|
1193
|
+
"""Supported forms:
|
|
1194
|
+
|
|
1195
|
+
* SHA256RNDS2(xmm, xmm/m128, xmm0) [SHA]
|
|
1196
|
+
"""
|
|
1197
|
+
|
|
1198
|
+
origin = kwargs.get("origin")
|
|
1199
|
+
prototype = kwargs.get("prototype")
|
|
1200
|
+
if (
|
|
1201
|
+
origin is None
|
|
1202
|
+
and prototype is None
|
|
1203
|
+
and nervapy.x86_64.options.get_debug_level() > 0
|
|
1204
|
+
):
|
|
1205
|
+
origin = inspect.stack()
|
|
1206
|
+
super(SHA256RNDS2, self).__init__(
|
|
1207
|
+
"SHA256RNDS2", origin=origin, prototype=prototype
|
|
1208
|
+
)
|
|
1209
|
+
self.operands = tuple(map(check_operand, args))
|
|
1210
|
+
if len(self.operands) != 3:
|
|
1211
|
+
raise SyntaxError('Instruction "SHA256RNDS2" requires 3 operands')
|
|
1212
|
+
self.in_regs = (True, True, True)
|
|
1213
|
+
self.out_regs = (True, False, False)
|
|
1214
|
+
self.out_operands = (True, False, False)
|
|
1215
|
+
self.avx_mode = False
|
|
1216
|
+
self.isa_extensions = frozenset([nervapy.x86_64.isa.sha])
|
|
1217
|
+
if (
|
|
1218
|
+
is_xmm(self.operands[0])
|
|
1219
|
+
and is_xmm(self.operands[1])
|
|
1220
|
+
and is_xmm0(self.operands[2])
|
|
1221
|
+
):
|
|
1222
|
+
self.encodings.append(
|
|
1223
|
+
(
|
|
1224
|
+
0x20,
|
|
1225
|
+
lambda op, rex=False: optional_rex(op[0].hcode, op[1], rex)
|
|
1226
|
+
+ bytearray(
|
|
1227
|
+
[0x0F, 0x38, 0xCB, 0xC0 | op[0].lcode << 3 | op[1].lcode]
|
|
1228
|
+
),
|
|
1229
|
+
)
|
|
1230
|
+
)
|
|
1231
|
+
elif (
|
|
1232
|
+
is_xmm(self.operands[0])
|
|
1233
|
+
and is_m128(self.operands[1])
|
|
1234
|
+
and is_xmm0(self.operands[2])
|
|
1235
|
+
):
|
|
1236
|
+
self.encodings.append(
|
|
1237
|
+
(
|
|
1238
|
+
0x30,
|
|
1239
|
+
lambda op, rex=False, sib=False, min_disp=0: optional_rex(
|
|
1240
|
+
op[0].hcode, op[1].address, rex
|
|
1241
|
+
)
|
|
1242
|
+
+ bytearray([0x0F, 0x38, 0xCB])
|
|
1243
|
+
+ modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp),
|
|
1244
|
+
)
|
|
1245
|
+
)
|
|
1246
|
+
else:
|
|
1247
|
+
raise SyntaxError(
|
|
1248
|
+
"Invalid operand types: SHA256RNDS2 "
|
|
1249
|
+
+ ", ".join(map(format_operand_type, self.operands))
|
|
1250
|
+
)
|
|
1251
|
+
if nervapy.stream.active_stream is not None:
|
|
1252
|
+
nervapy.stream.active_stream.add_instruction(self)
|
|
1253
|
+
|
|
1254
|
+
|
|
1255
|
+
class PCLMULQDQ(Instruction):
|
|
1256
|
+
"""Carry-Less Quadword Multiplication"""
|
|
1257
|
+
|
|
1258
|
+
def __init__(self, *args, **kwargs):
|
|
1259
|
+
"""Supported forms:
|
|
1260
|
+
|
|
1261
|
+
* PCLMULQDQ(xmm, xmm/m128, imm8) [PCLMULQDQ]
|
|
1262
|
+
"""
|
|
1263
|
+
|
|
1264
|
+
origin = kwargs.get("origin")
|
|
1265
|
+
prototype = kwargs.get("prototype")
|
|
1266
|
+
if (
|
|
1267
|
+
origin is None
|
|
1268
|
+
and prototype is None
|
|
1269
|
+
and nervapy.x86_64.options.get_debug_level() > 0
|
|
1270
|
+
):
|
|
1271
|
+
origin = inspect.stack()
|
|
1272
|
+
super(PCLMULQDQ, self).__init__("PCLMULQDQ", origin=origin, prototype=prototype)
|
|
1273
|
+
self.operands = tuple(map(check_operand, args))
|
|
1274
|
+
if len(self.operands) != 3:
|
|
1275
|
+
raise SyntaxError('Instruction "PCLMULQDQ" requires 3 operands')
|
|
1276
|
+
self.go_name = "PCLMULQDQ"
|
|
1277
|
+
self.in_regs = (True, True, False)
|
|
1278
|
+
self.out_regs = (True, False, False)
|
|
1279
|
+
self.out_operands = (True, False, False)
|
|
1280
|
+
self.avx_mode = False
|
|
1281
|
+
self.isa_extensions = frozenset([nervapy.x86_64.isa.pclmulqdq])
|
|
1282
|
+
if (
|
|
1283
|
+
is_xmm(self.operands[0])
|
|
1284
|
+
and is_xmm(self.operands[1])
|
|
1285
|
+
and is_imm(self.operands[2])
|
|
1286
|
+
):
|
|
1287
|
+
if not is_imm8(self.operands[2]):
|
|
1288
|
+
raise ValueError("Argument #2 can not be encoded as imm8")
|
|
1289
|
+
self.encodings.append(
|
|
1290
|
+
(
|
|
1291
|
+
0x20,
|
|
1292
|
+
lambda op, rex=False: bytearray([0x66])
|
|
1293
|
+
+ optional_rex(op[0].hcode, op[1], rex)
|
|
1294
|
+
+ bytearray(
|
|
1295
|
+
[
|
|
1296
|
+
0x0F,
|
|
1297
|
+
0x3A,
|
|
1298
|
+
0x44,
|
|
1299
|
+
0xC0 | op[0].lcode << 3 | op[1].lcode,
|
|
1300
|
+
op[2] & 0xFF,
|
|
1301
|
+
]
|
|
1302
|
+
),
|
|
1303
|
+
)
|
|
1304
|
+
)
|
|
1305
|
+
elif (
|
|
1306
|
+
is_xmm(self.operands[0])
|
|
1307
|
+
and is_m128(self.operands[1])
|
|
1308
|
+
and is_imm(self.operands[2])
|
|
1309
|
+
):
|
|
1310
|
+
if not is_imm8(self.operands[2]):
|
|
1311
|
+
raise ValueError("Argument #2 can not be encoded as imm8")
|
|
1312
|
+
self.encodings.append(
|
|
1313
|
+
(
|
|
1314
|
+
0x30,
|
|
1315
|
+
lambda op, rex=False, sib=False, min_disp=0: bytearray([0x66])
|
|
1316
|
+
+ optional_rex(op[0].hcode, op[1].address, rex)
|
|
1317
|
+
+ bytearray([0x0F, 0x3A, 0x44])
|
|
1318
|
+
+ modrm_sib_disp(op[0].lcode, op[1].address, sib, min_disp)
|
|
1319
|
+
+ bytearray([op[2] & 0xFF]),
|
|
1320
|
+
)
|
|
1321
|
+
)
|
|
1322
|
+
else:
|
|
1323
|
+
raise SyntaxError(
|
|
1324
|
+
"Invalid operand types: PCLMULQDQ "
|
|
1325
|
+
+ ", ".join(map(format_operand_type, self.operands))
|
|
1326
|
+
)
|
|
1327
|
+
if nervapy.stream.active_stream is not None:
|
|
1328
|
+
nervapy.stream.active_stream.add_instruction(self)
|
|
1329
|
+
|
|
1330
|
+
|
|
1331
|
+
class VPCLMULQDQ(Instruction):
|
|
1332
|
+
"""Carry-Less Quadword Multiplication"""
|
|
1333
|
+
|
|
1334
|
+
def __init__(self, *args, **kwargs):
|
|
1335
|
+
"""Supported forms:
|
|
1336
|
+
|
|
1337
|
+
* VPCLMULQDQ(xmm, xmm, xmm/m128, imm8) [AVX and PCLMULQDQ]
|
|
1338
|
+
"""
|
|
1339
|
+
|
|
1340
|
+
origin = kwargs.get("origin")
|
|
1341
|
+
prototype = kwargs.get("prototype")
|
|
1342
|
+
if (
|
|
1343
|
+
origin is None
|
|
1344
|
+
and prototype is None
|
|
1345
|
+
and nervapy.x86_64.options.get_debug_level() > 0
|
|
1346
|
+
):
|
|
1347
|
+
origin = inspect.stack()
|
|
1348
|
+
super(VPCLMULQDQ, self).__init__(
|
|
1349
|
+
"VPCLMULQDQ", origin=origin, prototype=prototype
|
|
1350
|
+
)
|
|
1351
|
+
self.operands = tuple(map(check_operand, args))
|
|
1352
|
+
if len(self.operands) != 4:
|
|
1353
|
+
raise SyntaxError('Instruction "VPCLMULQDQ" requires 4 operands')
|
|
1354
|
+
self.in_regs = (False, True, True, False)
|
|
1355
|
+
self.out_regs = (True, False, False, False)
|
|
1356
|
+
self.out_operands = (True, False, False, False)
|
|
1357
|
+
self.avx_mode = True
|
|
1358
|
+
self.isa_extensions = frozenset(
|
|
1359
|
+
[nervapy.x86_64.isa.avx, nervapy.x86_64.isa.pclmulqdq]
|
|
1360
|
+
)
|
|
1361
|
+
if (
|
|
1362
|
+
is_xmm(self.operands[0])
|
|
1363
|
+
and is_xmm(self.operands[1])
|
|
1364
|
+
and is_xmm(self.operands[2])
|
|
1365
|
+
and is_imm(self.operands[3])
|
|
1366
|
+
):
|
|
1367
|
+
if not is_imm8(self.operands[3]):
|
|
1368
|
+
raise ValueError("Argument #3 can not be encoded as imm8")
|
|
1369
|
+
self.encodings.append(
|
|
1370
|
+
(
|
|
1371
|
+
0x00,
|
|
1372
|
+
lambda op: bytearray(
|
|
1373
|
+
[
|
|
1374
|
+
0xC4,
|
|
1375
|
+
0xE3 ^ (op[0].hcode << 7) ^ (op[2].hcode << 5),
|
|
1376
|
+
0x79 ^ (op[1].hlcode << 3),
|
|
1377
|
+
0x44,
|
|
1378
|
+
0xC0 | op[0].lcode << 3 | op[2].lcode,
|
|
1379
|
+
op[3] & 0xFF,
|
|
1380
|
+
]
|
|
1381
|
+
),
|
|
1382
|
+
)
|
|
1383
|
+
)
|
|
1384
|
+
elif (
|
|
1385
|
+
is_xmm(self.operands[0])
|
|
1386
|
+
and is_xmm(self.operands[1])
|
|
1387
|
+
and is_m128(self.operands[2])
|
|
1388
|
+
and is_imm(self.operands[3])
|
|
1389
|
+
):
|
|
1390
|
+
if not is_imm8(self.operands[3]):
|
|
1391
|
+
raise ValueError("Argument #3 can not be encoded as imm8")
|
|
1392
|
+
self.encodings.append(
|
|
1393
|
+
(
|
|
1394
|
+
0x10,
|
|
1395
|
+
lambda op, sib=False, min_disp=0: vex3(
|
|
1396
|
+
0xC4, 0b11, 0x01, op[0].hcode, op[2].address, op[1].hlcode
|
|
1397
|
+
)
|
|
1398
|
+
+ bytearray([0x44])
|
|
1399
|
+
+ modrm_sib_disp(op[0].lcode, op[2].address, sib, min_disp)
|
|
1400
|
+
+ bytearray([op[3] & 0xFF]),
|
|
1401
|
+
)
|
|
1402
|
+
)
|
|
1403
|
+
else:
|
|
1404
|
+
raise SyntaxError(
|
|
1405
|
+
"Invalid operand types: VPCLMULQDQ "
|
|
1406
|
+
+ ", ".join(map(format_operand_type, self.operands))
|
|
1407
|
+
)
|
|
1408
|
+
if nervapy.stream.active_stream is not None:
|
|
1409
|
+
nervapy.stream.active_stream.add_instruction(self)
|
|
1410
|
+
|
|
1411
|
+
|
|
1412
|
+
class RDRAND(Instruction):
|
|
1413
|
+
"""Read Random Number"""
|
|
1414
|
+
|
|
1415
|
+
def __init__(self, *args, **kwargs):
|
|
1416
|
+
"""Supported forms:
|
|
1417
|
+
|
|
1418
|
+
* RDRAND(r16) [RDRAND]
|
|
1419
|
+
* RDRAND(r32) [RDRAND]
|
|
1420
|
+
* RDRAND(r64) [RDRAND]
|
|
1421
|
+
"""
|
|
1422
|
+
|
|
1423
|
+
origin = kwargs.get("origin")
|
|
1424
|
+
prototype = kwargs.get("prototype")
|
|
1425
|
+
if (
|
|
1426
|
+
origin is None
|
|
1427
|
+
and prototype is None
|
|
1428
|
+
and nervapy.x86_64.options.get_debug_level() > 0
|
|
1429
|
+
):
|
|
1430
|
+
origin = inspect.stack()
|
|
1431
|
+
super(RDRAND, self).__init__("RDRAND", origin=origin, prototype=prototype)
|
|
1432
|
+
self.operands = tuple(map(check_operand, args))
|
|
1433
|
+
if len(self.operands) != 1:
|
|
1434
|
+
raise SyntaxError('Instruction "RDRAND" requires 1 operands')
|
|
1435
|
+
self.in_regs = (False,)
|
|
1436
|
+
self.out_regs = (True,)
|
|
1437
|
+
self.out_operands = (True,)
|
|
1438
|
+
self.isa_extensions = frozenset([nervapy.x86_64.isa.rdrand])
|
|
1439
|
+
if is_r16(self.operands[0]):
|
|
1440
|
+
self.encodings.append(
|
|
1441
|
+
(
|
|
1442
|
+
0x20,
|
|
1443
|
+
lambda op, rex=False: bytearray([0x66])
|
|
1444
|
+
+ optional_rex(0, op[0], rex)
|
|
1445
|
+
+ bytearray([0x0F, 0xC7, 0xF0 | op[0].lcode]),
|
|
1446
|
+
)
|
|
1447
|
+
)
|
|
1448
|
+
elif is_r32(self.operands[0]):
|
|
1449
|
+
self.encodings.append(
|
|
1450
|
+
(
|
|
1451
|
+
0x20,
|
|
1452
|
+
lambda op, rex=False: optional_rex(0, op[0], rex)
|
|
1453
|
+
+ bytearray([0x0F, 0xC7, 0xF0 | op[0].lcode]),
|
|
1454
|
+
)
|
|
1455
|
+
)
|
|
1456
|
+
elif is_r64(self.operands[0]):
|
|
1457
|
+
self.encodings.append(
|
|
1458
|
+
(
|
|
1459
|
+
0x00,
|
|
1460
|
+
lambda op: bytearray(
|
|
1461
|
+
[0x48 | op[0].hcode, 0x0F, 0xC7, 0xF0 | op[0].lcode]
|
|
1462
|
+
),
|
|
1463
|
+
)
|
|
1464
|
+
)
|
|
1465
|
+
else:
|
|
1466
|
+
raise SyntaxError(
|
|
1467
|
+
"Invalid operand types: RDRAND "
|
|
1468
|
+
+ ", ".join(map(format_operand_type, self.operands))
|
|
1469
|
+
)
|
|
1470
|
+
if nervapy.stream.active_stream is not None:
|
|
1471
|
+
nervapy.stream.active_stream.add_instruction(self)
|
|
1472
|
+
|
|
1473
|
+
|
|
1474
|
+
class RDSEED(Instruction):
|
|
1475
|
+
"""Read Random SEED"""
|
|
1476
|
+
|
|
1477
|
+
def __init__(self, *args, **kwargs):
|
|
1478
|
+
"""Supported forms:
|
|
1479
|
+
|
|
1480
|
+
* RDSEED(r16) [RDSEED]
|
|
1481
|
+
* RDSEED(r32) [RDSEED]
|
|
1482
|
+
* RDSEED(r64) [RDSEED]
|
|
1483
|
+
"""
|
|
1484
|
+
|
|
1485
|
+
origin = kwargs.get("origin")
|
|
1486
|
+
prototype = kwargs.get("prototype")
|
|
1487
|
+
if (
|
|
1488
|
+
origin is None
|
|
1489
|
+
and prototype is None
|
|
1490
|
+
and nervapy.x86_64.options.get_debug_level() > 0
|
|
1491
|
+
):
|
|
1492
|
+
origin = inspect.stack()
|
|
1493
|
+
super(RDSEED, self).__init__("RDSEED", origin=origin, prototype=prototype)
|
|
1494
|
+
self.operands = tuple(map(check_operand, args))
|
|
1495
|
+
if len(self.operands) != 1:
|
|
1496
|
+
raise SyntaxError('Instruction "RDSEED" requires 1 operands')
|
|
1497
|
+
self.in_regs = (False,)
|
|
1498
|
+
self.out_regs = (True,)
|
|
1499
|
+
self.out_operands = (True,)
|
|
1500
|
+
self.isa_extensions = frozenset([nervapy.x86_64.isa.rdseed])
|
|
1501
|
+
if is_r16(self.operands[0]):
|
|
1502
|
+
self.encodings.append(
|
|
1503
|
+
(
|
|
1504
|
+
0x20,
|
|
1505
|
+
lambda op, rex=False: bytearray([0x66])
|
|
1506
|
+
+ optional_rex(0, op[0], rex)
|
|
1507
|
+
+ bytearray([0x0F, 0xC7, 0xF8 | op[0].lcode]),
|
|
1508
|
+
)
|
|
1509
|
+
)
|
|
1510
|
+
elif is_r32(self.operands[0]):
|
|
1511
|
+
self.encodings.append(
|
|
1512
|
+
(
|
|
1513
|
+
0x20,
|
|
1514
|
+
lambda op, rex=False: optional_rex(0, op[0], rex)
|
|
1515
|
+
+ bytearray([0x0F, 0xC7, 0xF8 | op[0].lcode]),
|
|
1516
|
+
)
|
|
1517
|
+
)
|
|
1518
|
+
elif is_r64(self.operands[0]):
|
|
1519
|
+
self.encodings.append(
|
|
1520
|
+
(
|
|
1521
|
+
0x00,
|
|
1522
|
+
lambda op: bytearray(
|
|
1523
|
+
[0x48 | op[0].hcode, 0x0F, 0xC7, 0xF8 | op[0].lcode]
|
|
1524
|
+
),
|
|
1525
|
+
)
|
|
1526
|
+
)
|
|
1527
|
+
else:
|
|
1528
|
+
raise SyntaxError(
|
|
1529
|
+
"Invalid operand types: RDSEED "
|
|
1530
|
+
+ ", ".join(map(format_operand_type, self.operands))
|
|
1531
|
+
)
|
|
1532
|
+
if nervapy.stream.active_stream is not None:
|
|
1533
|
+
nervapy.stream.active_stream.add_instruction(self)
|