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
|
@@ -0,0 +1,1204 @@
|
|
|
1
|
+
# This file is part of PeachPy package and is licensed under the Simplified BSD license.
|
|
2
|
+
# See license.rst for the full text of the license.
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def check_operand(operand):
|
|
6
|
+
"""Validates operand object as an instruction operand and converts it to a standard form"""
|
|
7
|
+
|
|
8
|
+
from copy import copy, deepcopy
|
|
9
|
+
|
|
10
|
+
from nervapy import Argument
|
|
11
|
+
from nervapy.literal import Constant
|
|
12
|
+
from nervapy.util import is_int, is_int64
|
|
13
|
+
from nervapy.x86_64.function import LocalVariable
|
|
14
|
+
from nervapy.x86_64.pseudo import Label
|
|
15
|
+
from nervapy.x86_64.registers import MaskedRegister, Register
|
|
16
|
+
|
|
17
|
+
if isinstance(operand, Register):
|
|
18
|
+
return copy(operand)
|
|
19
|
+
elif isinstance(operand, (MaskedRegister, MemoryOperand)):
|
|
20
|
+
return deepcopy(operand)
|
|
21
|
+
elif isinstance(operand, (Argument, RIPRelativeOffset, Label)):
|
|
22
|
+
return operand
|
|
23
|
+
elif is_int(operand):
|
|
24
|
+
if not is_int64(operand):
|
|
25
|
+
raise ValueError(
|
|
26
|
+
"The immediate operand %d is not representable as a 64-bit value"
|
|
27
|
+
)
|
|
28
|
+
return operand
|
|
29
|
+
elif isinstance(operand, list):
|
|
30
|
+
if len(operand) != 1:
|
|
31
|
+
raise ValueError(
|
|
32
|
+
"Memory operands must be represented by a list with only one element"
|
|
33
|
+
)
|
|
34
|
+
return MemoryOperand(operand[0])
|
|
35
|
+
elif isinstance(operand, Constant):
|
|
36
|
+
from copy import copy, deepcopy
|
|
37
|
+
|
|
38
|
+
operand = copy(operand)
|
|
39
|
+
import nervapy.common.function
|
|
40
|
+
|
|
41
|
+
if nervapy.common.function.active_function:
|
|
42
|
+
operand.name = deepcopy(
|
|
43
|
+
operand.name, nervapy.common.function.active_function._names_memo
|
|
44
|
+
)
|
|
45
|
+
return MemoryOperand(operand)
|
|
46
|
+
elif isinstance(operand, LocalVariable):
|
|
47
|
+
return MemoryOperand(operand)
|
|
48
|
+
elif isinstance(operand, set):
|
|
49
|
+
if len(operand) != 1:
|
|
50
|
+
raise ValueError(
|
|
51
|
+
"Rounding control & suppress-all-errors operands must be represented by a set "
|
|
52
|
+
"with only one element"
|
|
53
|
+
)
|
|
54
|
+
return next(iter(operand))
|
|
55
|
+
else:
|
|
56
|
+
raise TypeError("Unsupported operand: %s" % str(operand))
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def get_operand_registers(operand):
|
|
60
|
+
"""Returns a set of registers that comprise the operand"""
|
|
61
|
+
|
|
62
|
+
from nervapy.x86_64.registers import MaskedRegister, Register
|
|
63
|
+
|
|
64
|
+
if isinstance(operand, Register):
|
|
65
|
+
return [operand]
|
|
66
|
+
elif isinstance(operand, MaskedRegister):
|
|
67
|
+
return [operand.register, operand.mask.mask_register]
|
|
68
|
+
elif isinstance(operand, MemoryOperand) and isinstance(
|
|
69
|
+
operand.address, MemoryAddress
|
|
70
|
+
):
|
|
71
|
+
registers = list()
|
|
72
|
+
if operand.address.base is not None:
|
|
73
|
+
registers.append(operand.address.base)
|
|
74
|
+
if operand.address.index is not None:
|
|
75
|
+
registers.append(operand.address.index)
|
|
76
|
+
return registers
|
|
77
|
+
else:
|
|
78
|
+
return list()
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def format_operand(operand, assembly_format):
|
|
82
|
+
assert assembly_format in {
|
|
83
|
+
"peachpy",
|
|
84
|
+
"gas",
|
|
85
|
+
"nasm",
|
|
86
|
+
"go",
|
|
87
|
+
}, "Supported assembly formats are 'peachpy', 'gas', 'nasm', 'go'"
|
|
88
|
+
|
|
89
|
+
immediate_prefix_map = {"peachpy": "", "gas": "$", "nasm": "", "go": "$"}
|
|
90
|
+
|
|
91
|
+
from nervapy.util import is_int64
|
|
92
|
+
|
|
93
|
+
if is_int64(operand):
|
|
94
|
+
return immediate_prefix_map[assembly_format] + str(operand)
|
|
95
|
+
else:
|
|
96
|
+
return operand.format(assembly_format)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def format_operand_type(operand):
|
|
100
|
+
"""Returns string representation of the operand type in assembly language"""
|
|
101
|
+
from nervapy.util import is_int8, is_int16, is_int32, is_int64
|
|
102
|
+
from nervapy.x86_64.pseudo import Label
|
|
103
|
+
from nervapy.x86_64.registers import (GeneralPurposeRegister8,
|
|
104
|
+
GeneralPurposeRegister16,
|
|
105
|
+
GeneralPurposeRegister32,
|
|
106
|
+
GeneralPurposeRegister64,
|
|
107
|
+
MaskedRegister, MMXRegister,
|
|
108
|
+
XMMRegister, YMMRegister,
|
|
109
|
+
ZMMRegister, al, ax, cl, eax, rax,
|
|
110
|
+
xmm0)
|
|
111
|
+
|
|
112
|
+
if is_int8(operand):
|
|
113
|
+
return "imm8"
|
|
114
|
+
elif is_int16(operand):
|
|
115
|
+
return "imm16"
|
|
116
|
+
elif is_int32(operand):
|
|
117
|
+
return "imm32"
|
|
118
|
+
elif is_int64(operand):
|
|
119
|
+
return "imm64"
|
|
120
|
+
elif al == operand:
|
|
121
|
+
return "al"
|
|
122
|
+
elif ax == operand:
|
|
123
|
+
return "ax"
|
|
124
|
+
elif eax == operand:
|
|
125
|
+
return "eax"
|
|
126
|
+
elif rax == operand:
|
|
127
|
+
return "rax"
|
|
128
|
+
elif cl == operand:
|
|
129
|
+
return "cl"
|
|
130
|
+
elif xmm0 == operand:
|
|
131
|
+
return "xmm0"
|
|
132
|
+
elif isinstance(operand, GeneralPurposeRegister64):
|
|
133
|
+
return "r64"
|
|
134
|
+
elif isinstance(operand, GeneralPurposeRegister32):
|
|
135
|
+
return "r32"
|
|
136
|
+
elif isinstance(operand, GeneralPurposeRegister16):
|
|
137
|
+
return "r16"
|
|
138
|
+
elif isinstance(operand, GeneralPurposeRegister8):
|
|
139
|
+
return "r8"
|
|
140
|
+
elif isinstance(operand, MMXRegister):
|
|
141
|
+
return "mm"
|
|
142
|
+
elif isinstance(operand, XMMRegister):
|
|
143
|
+
return "xmm"
|
|
144
|
+
elif isinstance(operand, YMMRegister):
|
|
145
|
+
return "ymm"
|
|
146
|
+
elif isinstance(operand, ZMMRegister):
|
|
147
|
+
return "zmm"
|
|
148
|
+
elif isinstance(operand, MaskedRegister):
|
|
149
|
+
if operand.mask.is_zeroing:
|
|
150
|
+
return format_operand_type(operand.register) + "{k}{z}"
|
|
151
|
+
else:
|
|
152
|
+
return format_operand_type(operand.register) + "{k}"
|
|
153
|
+
elif isinstance(operand, MemoryOperand):
|
|
154
|
+
if operand.size is None:
|
|
155
|
+
return "m"
|
|
156
|
+
else:
|
|
157
|
+
if operand.mask is None:
|
|
158
|
+
return "m" + str(operand.size * 8)
|
|
159
|
+
elif operand.mask.is_zeroing:
|
|
160
|
+
return "m" + str(operand.size * 8) + "{k}{z}"
|
|
161
|
+
else:
|
|
162
|
+
return "m" + str(operand.size * 8) + "{k}"
|
|
163
|
+
elif isinstance(operand, RoundingControl):
|
|
164
|
+
return "{er}"
|
|
165
|
+
elif isinstance(operand, SuppressAllExceptions):
|
|
166
|
+
return "{sae}"
|
|
167
|
+
elif isinstance(operand, Label):
|
|
168
|
+
return "rel"
|
|
169
|
+
else:
|
|
170
|
+
return operand.__class__.__name__
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
class MemoryAddress:
|
|
174
|
+
"""An address expression involving a register, e.g. rax - 10, r8d * 4."""
|
|
175
|
+
|
|
176
|
+
def __init__(self, base=None, index=None, scale=None, displacement=0):
|
|
177
|
+
from nervapy.util import is_int, is_sint32
|
|
178
|
+
from nervapy.x86_64.registers import (GeneralPurposeRegister64,
|
|
179
|
+
MaskedRegister, XMMRegister,
|
|
180
|
+
YMMRegister, ZMMRegister)
|
|
181
|
+
|
|
182
|
+
# Check individual arguments
|
|
183
|
+
if base is not None and not isinstance(base, GeneralPurposeRegister64):
|
|
184
|
+
raise TypeError("Base register must be a 64-bit general-purpose register")
|
|
185
|
+
if (
|
|
186
|
+
index is not None
|
|
187
|
+
and not isinstance(
|
|
188
|
+
index, (GeneralPurposeRegister64, XMMRegister, YMMRegister, ZMMRegister)
|
|
189
|
+
)
|
|
190
|
+
and not (
|
|
191
|
+
isinstance(index, MaskedRegister)
|
|
192
|
+
and isinstance(index.register, (XMMRegister, YMMRegister, ZMMRegister))
|
|
193
|
+
and not index.mask.is_zeroing
|
|
194
|
+
)
|
|
195
|
+
):
|
|
196
|
+
raise TypeError(
|
|
197
|
+
"Index register must be a 64-bit general-purpose register or an XMM/YMM/ZMM register"
|
|
198
|
+
)
|
|
199
|
+
if scale is not None and not is_int(scale):
|
|
200
|
+
raise TypeError("Scale must be an integer")
|
|
201
|
+
if scale is not None and int(scale) not in {1, 2, 4, 8}:
|
|
202
|
+
raise TypeError("Scale must be 1, 2, 4, or 8")
|
|
203
|
+
if not is_sint32(displacement):
|
|
204
|
+
raise ValueError(
|
|
205
|
+
"Displacement value (%s) is not representable as a signed 32-bit integer"
|
|
206
|
+
% str(displacement)
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
# Check relations of arguments
|
|
210
|
+
if scale is not None and index is None or scale is None and index is not None:
|
|
211
|
+
raise ValueError(
|
|
212
|
+
"Either both of neither of scale and index must be defined"
|
|
213
|
+
)
|
|
214
|
+
if index is None and base is None:
|
|
215
|
+
raise ValueError("Either base or index * scale must be specified")
|
|
216
|
+
|
|
217
|
+
self.base = base
|
|
218
|
+
self.index = index
|
|
219
|
+
self.scale = None if scale is None else int(scale)
|
|
220
|
+
self.displacement = int(displacement)
|
|
221
|
+
|
|
222
|
+
def __add__(self, addend):
|
|
223
|
+
from nervapy.util import is_int, is_sint32
|
|
224
|
+
from nervapy.x86_64.registers import GeneralPurposeRegister64
|
|
225
|
+
|
|
226
|
+
if is_int(addend):
|
|
227
|
+
if not is_sint32(addend):
|
|
228
|
+
raise ValueError(
|
|
229
|
+
"The addend value (%d) is not representable as a signed 32-bit integer"
|
|
230
|
+
% addend
|
|
231
|
+
)
|
|
232
|
+
return MemoryAddress(
|
|
233
|
+
self.base, self.index, self.scale, self.displacement + addend
|
|
234
|
+
)
|
|
235
|
+
elif isinstance(addend, GeneralPurposeRegister64):
|
|
236
|
+
if self.base is not None:
|
|
237
|
+
raise TypeError(
|
|
238
|
+
"Can not add a general-purpose register to a memory operand with existing base"
|
|
239
|
+
)
|
|
240
|
+
if self.index.size != addend.size:
|
|
241
|
+
raise TypeError(
|
|
242
|
+
"Index (%s) and addend (%s) registers have different size"
|
|
243
|
+
% (str(self.index), str(addend))
|
|
244
|
+
)
|
|
245
|
+
return MemoryAddress(addend, self.index, self.scale, self.displacement)
|
|
246
|
+
elif isinstance(addend, MemoryAddress):
|
|
247
|
+
if self.base is not None and addend.base is not None:
|
|
248
|
+
raise ValueError(
|
|
249
|
+
"Can not add memory address: both address expressions use base registers"
|
|
250
|
+
)
|
|
251
|
+
if self.index is not None and addend.index is not None:
|
|
252
|
+
raise ValueError(
|
|
253
|
+
"Can not add memory address: both address expressions use index registers"
|
|
254
|
+
)
|
|
255
|
+
sum_base = self.base if self.base is not None else addend.base
|
|
256
|
+
sum_index, sum_scale = (
|
|
257
|
+
(self.index, self.scale)
|
|
258
|
+
if self.index is not None
|
|
259
|
+
else (addend.index, addend.scale)
|
|
260
|
+
)
|
|
261
|
+
return MemoryAddress(
|
|
262
|
+
sum_base, sum_index, sum_scale, self.displacement + addend.displacement
|
|
263
|
+
)
|
|
264
|
+
else:
|
|
265
|
+
raise TypeError("Can not add %s: unsupported addend type" % str(addend))
|
|
266
|
+
|
|
267
|
+
def __sub__(self, minuend):
|
|
268
|
+
from nervapy.util import is_int, is_sint32
|
|
269
|
+
|
|
270
|
+
if is_int(minuend):
|
|
271
|
+
if not is_sint32(-minuend):
|
|
272
|
+
raise ValueError(
|
|
273
|
+
"The addend value (%d) is not representable as a signed 32-bit integer"
|
|
274
|
+
% minuend
|
|
275
|
+
)
|
|
276
|
+
return MemoryAddress(
|
|
277
|
+
self.base, self.index, self.scale, self.displacement - minuend
|
|
278
|
+
)
|
|
279
|
+
else:
|
|
280
|
+
raise TypeError("Can not add %s: unsupported addend type" % str(minuend))
|
|
281
|
+
|
|
282
|
+
def __str__(self):
|
|
283
|
+
parts = []
|
|
284
|
+
if self.base is not None:
|
|
285
|
+
parts.append(str(self.base))
|
|
286
|
+
if self.index is not None:
|
|
287
|
+
parts.append(str(self.index) + "*" + str(self.scale))
|
|
288
|
+
if self.displacement >= 0:
|
|
289
|
+
if self.displacement > 0:
|
|
290
|
+
parts.append(str(self.displacement))
|
|
291
|
+
return " + ".join(parts)
|
|
292
|
+
else:
|
|
293
|
+
return " + ".join(parts) + " - " + str(-self.displacement)
|
|
294
|
+
|
|
295
|
+
def __repr__(self):
|
|
296
|
+
return str(self)
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
class MemoryOperand:
|
|
300
|
+
def __init__(self, address, size=None, mask=None, broadcast=None):
|
|
301
|
+
from nervapy.literal import Constant
|
|
302
|
+
from nervapy.x86_64.function import LocalVariable
|
|
303
|
+
from nervapy.x86_64.registers import (GeneralPurposeRegister64,
|
|
304
|
+
MaskedRegister, XMMRegister,
|
|
305
|
+
YMMRegister, ZMMRegister)
|
|
306
|
+
|
|
307
|
+
assert (
|
|
308
|
+
isinstance(
|
|
309
|
+
address,
|
|
310
|
+
(
|
|
311
|
+
GeneralPurposeRegister64,
|
|
312
|
+
XMMRegister,
|
|
313
|
+
YMMRegister,
|
|
314
|
+
ZMMRegister,
|
|
315
|
+
MemoryAddress,
|
|
316
|
+
Constant,
|
|
317
|
+
LocalVariable,
|
|
318
|
+
RIPRelativeOffset,
|
|
319
|
+
),
|
|
320
|
+
)
|
|
321
|
+
or isinstance(address, MaskedRegister)
|
|
322
|
+
and isinstance(address.register, (XMMRegister, YMMRegister, ZMMRegister))
|
|
323
|
+
and not address.mask.is_zeroing
|
|
324
|
+
), (
|
|
325
|
+
"Only MemoryAddress, 64-bit general-purpose registers, RIP-Relative addresses, XMM/YMM/ZMM registers, "
|
|
326
|
+
"and merge-masked XMM/YMM/ZMM registers may be specified as an address"
|
|
327
|
+
)
|
|
328
|
+
from nervapy.util import is_int
|
|
329
|
+
|
|
330
|
+
assert (
|
|
331
|
+
size is None
|
|
332
|
+
or is_int(size)
|
|
333
|
+
and int(size) in SizeSpecification._size_name_map
|
|
334
|
+
), ("Unsupported size: %d" % size)
|
|
335
|
+
|
|
336
|
+
self.symbol = None
|
|
337
|
+
self.size = size
|
|
338
|
+
self.mask = mask
|
|
339
|
+
self.broadcast = broadcast
|
|
340
|
+
|
|
341
|
+
if isinstance(address, MemoryAddress):
|
|
342
|
+
if isinstance(address.index, MaskedRegister):
|
|
343
|
+
self.address = MemoryAddress(
|
|
344
|
+
address.base,
|
|
345
|
+
address.index.register,
|
|
346
|
+
address.scale,
|
|
347
|
+
address.displacement,
|
|
348
|
+
)
|
|
349
|
+
assert (
|
|
350
|
+
mask is None
|
|
351
|
+
), "Mask argument can't be used when address index is a masked XMM/YMM/ZMM register"
|
|
352
|
+
self.mask = address.index.mask
|
|
353
|
+
else:
|
|
354
|
+
self.address = address
|
|
355
|
+
elif isinstance(address, MaskedRegister):
|
|
356
|
+
self.address = MemoryAddress(index=address.register, scale=1)
|
|
357
|
+
assert (
|
|
358
|
+
mask is None
|
|
359
|
+
), "Mask argument can't be used when address is a masked XMM/YMM/ZMM register"
|
|
360
|
+
self.mask = address.mask
|
|
361
|
+
elif isinstance(address, Constant):
|
|
362
|
+
self.address = RIPRelativeOffset(0)
|
|
363
|
+
self.symbol = address
|
|
364
|
+
self.size = address.size
|
|
365
|
+
elif isinstance(address, LocalVariable):
|
|
366
|
+
from nervapy.x86_64.registers import rsp
|
|
367
|
+
|
|
368
|
+
self.address = MemoryAddress(rsp, displacement=address.offset)
|
|
369
|
+
self.symbol = address
|
|
370
|
+
self.size = address.size
|
|
371
|
+
elif isinstance(address, RIPRelativeOffset):
|
|
372
|
+
self.address = address
|
|
373
|
+
else:
|
|
374
|
+
# Convert register to memory address expression
|
|
375
|
+
self.address = MemoryAddress(address)
|
|
376
|
+
|
|
377
|
+
def __str__(self):
|
|
378
|
+
if self.size is None:
|
|
379
|
+
return "[" + str(self.address) + "]"
|
|
380
|
+
else:
|
|
381
|
+
return (
|
|
382
|
+
SizeSpecification._size_name_map[self.size]
|
|
383
|
+
+ " ["
|
|
384
|
+
+ str(self.address)
|
|
385
|
+
+ "]"
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
def __repr__(self):
|
|
389
|
+
return str(self)
|
|
390
|
+
|
|
391
|
+
def __call__(self, mask):
|
|
392
|
+
from nervapy.x86_64.registers import KRegister, RegisterMask
|
|
393
|
+
|
|
394
|
+
if not isinstance(mask, (KRegister, RegisterMask)):
|
|
395
|
+
raise SyntaxError(
|
|
396
|
+
"zmm(mask) syntax requires mask to be a KRegister or KRegister.z"
|
|
397
|
+
)
|
|
398
|
+
if self.broadcast:
|
|
399
|
+
raise ValueError(
|
|
400
|
+
"mask can not be applied to memory operands with broadcasting"
|
|
401
|
+
)
|
|
402
|
+
if isinstance(mask, KRegister):
|
|
403
|
+
mask = RegisterMask(mask)
|
|
404
|
+
return MemoryOperand(self.address, self.size, mask)
|
|
405
|
+
|
|
406
|
+
def format(self, assembly_format):
|
|
407
|
+
assert assembly_format in {
|
|
408
|
+
"peachpy",
|
|
409
|
+
"gas",
|
|
410
|
+
"nasm",
|
|
411
|
+
"go",
|
|
412
|
+
}, "Supported assembly formats are 'peachpy', 'gas', 'nasm', 'go'"
|
|
413
|
+
|
|
414
|
+
if assembly_format == "go":
|
|
415
|
+
text = str(self.address.displacement)
|
|
416
|
+
if self.address.base is not None:
|
|
417
|
+
text += "(" + self.address.base.format(assembly_format) + ")"
|
|
418
|
+
if self.address.index is not None:
|
|
419
|
+
text += "(%s*%d)" % (
|
|
420
|
+
self.address.index.format(assembly_format),
|
|
421
|
+
self.address.scale,
|
|
422
|
+
)
|
|
423
|
+
return text
|
|
424
|
+
elif assembly_format == "gas":
|
|
425
|
+
if isinstance(self.address, RIPRelativeOffset):
|
|
426
|
+
return str(self.address.offset) + "(%rip)"
|
|
427
|
+
else:
|
|
428
|
+
base = self.address.base
|
|
429
|
+
if self.address.index is None:
|
|
430
|
+
return "{displacement}({base})".format(
|
|
431
|
+
displacement=self.address.displacement,
|
|
432
|
+
base=base.format(assembly_format),
|
|
433
|
+
)
|
|
434
|
+
else:
|
|
435
|
+
return "{displacement}({base},{index},{scale})".format(
|
|
436
|
+
displacement=self.address.displacement,
|
|
437
|
+
base="" if base is None else base.format(assembly_format),
|
|
438
|
+
index=self.address.index.format(assembly_format),
|
|
439
|
+
scale=self.address.scale,
|
|
440
|
+
)
|
|
441
|
+
else:
|
|
442
|
+
return str(self)
|
|
443
|
+
|
|
444
|
+
@property
|
|
445
|
+
def bcode(self):
|
|
446
|
+
return int(self.broadcast is not None)
|
|
447
|
+
|
|
448
|
+
@property
|
|
449
|
+
def kcode(self):
|
|
450
|
+
if self.mask is None:
|
|
451
|
+
return 0
|
|
452
|
+
else:
|
|
453
|
+
return self.mask.kcode
|
|
454
|
+
|
|
455
|
+
@property
|
|
456
|
+
def zcode(self):
|
|
457
|
+
if self.mask is None:
|
|
458
|
+
return 0
|
|
459
|
+
else:
|
|
460
|
+
return self.mask.zcode
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
class SizeSpecification:
|
|
464
|
+
_size_name_map = {
|
|
465
|
+
1: "byte",
|
|
466
|
+
2: "word",
|
|
467
|
+
4: "dword",
|
|
468
|
+
8: "qword",
|
|
469
|
+
10: "tword",
|
|
470
|
+
16: "oword",
|
|
471
|
+
32: "hword",
|
|
472
|
+
64: "zword",
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
def __init__(self, size):
|
|
476
|
+
from nervapy.util import is_int
|
|
477
|
+
|
|
478
|
+
assert is_int(size) and int(size) in SizeSpecification._size_name_map, (
|
|
479
|
+
"Unsupported size: %d" % size
|
|
480
|
+
)
|
|
481
|
+
self.size = size
|
|
482
|
+
|
|
483
|
+
def __str__(self):
|
|
484
|
+
return SizeSpecification._size_name_map[self.size]
|
|
485
|
+
|
|
486
|
+
def __getitem__(self, address):
|
|
487
|
+
return MemoryOperand(address, self.size)
|
|
488
|
+
|
|
489
|
+
@property
|
|
490
|
+
def to2(self):
|
|
491
|
+
if self.size not in [4, 8]:
|
|
492
|
+
raise ValueError(
|
|
493
|
+
"{1to2} broadcasting is only supported for dword and qword memory locations"
|
|
494
|
+
)
|
|
495
|
+
return BroadcastSpecification(self.size, 2)
|
|
496
|
+
|
|
497
|
+
@property
|
|
498
|
+
def to4(self):
|
|
499
|
+
if self.size not in [4, 8]:
|
|
500
|
+
raise ValueError(
|
|
501
|
+
"{1to4} broadcasting is only supported for dword and qword memory locations"
|
|
502
|
+
)
|
|
503
|
+
return BroadcastSpecification(self.size, 4)
|
|
504
|
+
|
|
505
|
+
@property
|
|
506
|
+
def to8(self):
|
|
507
|
+
if self.size not in [4, 8]:
|
|
508
|
+
raise ValueError(
|
|
509
|
+
"{1to8} broadcasting is only supported for dword and qword memory locations"
|
|
510
|
+
)
|
|
511
|
+
return BroadcastSpecification(self.size, 8)
|
|
512
|
+
|
|
513
|
+
@property
|
|
514
|
+
def to16(self):
|
|
515
|
+
if self.size != 4:
|
|
516
|
+
raise ValueError(
|
|
517
|
+
"{1to16} broadcasting is only supported for dword memory locations"
|
|
518
|
+
)
|
|
519
|
+
return BroadcastSpecification(self.size, 16)
|
|
520
|
+
|
|
521
|
+
|
|
522
|
+
class BroadcastSpecification:
|
|
523
|
+
def __init__(self, size, broadcast):
|
|
524
|
+
assert size in [4, 8]
|
|
525
|
+
assert broadcast in [2, 4, 8, 16]
|
|
526
|
+
assert size * broadcast in [16, 32, 64]
|
|
527
|
+
self.size = size
|
|
528
|
+
self.broadcast = broadcast
|
|
529
|
+
|
|
530
|
+
def __str__(self):
|
|
531
|
+
return SizeSpecification._size_name_map[self.size] + "{1to%d}" % self.broadcast
|
|
532
|
+
|
|
533
|
+
def __getitem__(self, address):
|
|
534
|
+
return MemoryOperand(address, self.size, broadcast=self.broadcast)
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
class RIPRelativeOffset:
|
|
538
|
+
def __init__(self, offset):
|
|
539
|
+
import nervapy.util
|
|
540
|
+
|
|
541
|
+
if not nervapy.util.is_sint32(offset):
|
|
542
|
+
raise ValueError("RIP-relative offset must be a 32-bit signed integer")
|
|
543
|
+
self.offset = offset
|
|
544
|
+
|
|
545
|
+
def __add__(self, extra_offset):
|
|
546
|
+
return RIPRelativeOffset(self.offset + extra_offset)
|
|
547
|
+
|
|
548
|
+
def __sub__(self, extra_offset):
|
|
549
|
+
return RIPRelativeOffset(self.offset - extra_offset)
|
|
550
|
+
|
|
551
|
+
def __str__(self):
|
|
552
|
+
return self.format("peachpy")
|
|
553
|
+
|
|
554
|
+
def format(self, assembly_format):
|
|
555
|
+
if assembly_format == "gas":
|
|
556
|
+
return "%d(%rip)" % self.offset
|
|
557
|
+
elif assembly_format == "go":
|
|
558
|
+
return "%d(IP)" % self.offset
|
|
559
|
+
else:
|
|
560
|
+
return "rip%+d" % self.offset
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
def is_al(operand):
|
|
564
|
+
from nervapy.x86_64.registers import GeneralPurposeRegister8, al
|
|
565
|
+
|
|
566
|
+
return isinstance(operand, GeneralPurposeRegister8) and (
|
|
567
|
+
operand.is_virtual or operand == al
|
|
568
|
+
)
|
|
569
|
+
|
|
570
|
+
|
|
571
|
+
def is_cl(operand):
|
|
572
|
+
from nervapy.x86_64.registers import GeneralPurposeRegister8, cl
|
|
573
|
+
|
|
574
|
+
return isinstance(operand, GeneralPurposeRegister8) and (
|
|
575
|
+
operand.is_virtual or operand == cl
|
|
576
|
+
)
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
def is_ax(operand):
|
|
580
|
+
from nervapy.x86_64.registers import GeneralPurposeRegister16, ax
|
|
581
|
+
|
|
582
|
+
return isinstance(operand, GeneralPurposeRegister16) and (
|
|
583
|
+
operand.is_virtual or operand == ax
|
|
584
|
+
)
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
def is_eax(operand):
|
|
588
|
+
from nervapy.x86_64.registers import GeneralPurposeRegister32, eax
|
|
589
|
+
|
|
590
|
+
return isinstance(operand, GeneralPurposeRegister32) and (
|
|
591
|
+
operand.is_virtual or operand == eax
|
|
592
|
+
)
|
|
593
|
+
|
|
594
|
+
|
|
595
|
+
def is_rax(operand):
|
|
596
|
+
from nervapy.x86_64.registers import GeneralPurposeRegister64, rax
|
|
597
|
+
|
|
598
|
+
return isinstance(operand, GeneralPurposeRegister64) and (
|
|
599
|
+
operand.is_virtual or operand == rax
|
|
600
|
+
)
|
|
601
|
+
|
|
602
|
+
|
|
603
|
+
def is_xmm0(operand):
|
|
604
|
+
from nervapy.x86_64.registers import XMMRegister, xmm0
|
|
605
|
+
|
|
606
|
+
return isinstance(operand, XMMRegister) and (operand.is_virtual or operand == xmm0)
|
|
607
|
+
|
|
608
|
+
|
|
609
|
+
def is_r8(operand):
|
|
610
|
+
import nervapy.x86_64.registers
|
|
611
|
+
|
|
612
|
+
return isinstance(operand, nervapy.x86_64.registers.GeneralPurposeRegister8)
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
def is_r8rex(operand):
|
|
616
|
+
import nervapy.x86_64.registers
|
|
617
|
+
|
|
618
|
+
return (
|
|
619
|
+
isinstance(operand, nervapy.x86_64.registers.GeneralPurposeRegister8)
|
|
620
|
+
and operand.physical_id >= 4
|
|
621
|
+
)
|
|
622
|
+
|
|
623
|
+
|
|
624
|
+
def is_r8h(operand):
|
|
625
|
+
import nervapy.x86_64.registers
|
|
626
|
+
|
|
627
|
+
return (
|
|
628
|
+
isinstance(operand, nervapy.x86_64.registers.GeneralPurposeRegister8)
|
|
629
|
+
and operand.mask == nervapy.x86_64.registers.GeneralPurposeRegister8._high_mask
|
|
630
|
+
)
|
|
631
|
+
|
|
632
|
+
|
|
633
|
+
def is_r16(operand):
|
|
634
|
+
import nervapy.x86_64.registers
|
|
635
|
+
|
|
636
|
+
return isinstance(operand, nervapy.x86_64.registers.GeneralPurposeRegister16)
|
|
637
|
+
|
|
638
|
+
|
|
639
|
+
def is_r32(operand):
|
|
640
|
+
import nervapy.x86_64.registers
|
|
641
|
+
|
|
642
|
+
return isinstance(operand, nervapy.x86_64.registers.GeneralPurposeRegister32)
|
|
643
|
+
|
|
644
|
+
|
|
645
|
+
def is_r64(operand):
|
|
646
|
+
import nervapy.x86_64.registers
|
|
647
|
+
|
|
648
|
+
return isinstance(operand, nervapy.x86_64.registers.GeneralPurposeRegister64)
|
|
649
|
+
|
|
650
|
+
|
|
651
|
+
def is_mm(operand):
|
|
652
|
+
import nervapy.x86_64.registers
|
|
653
|
+
|
|
654
|
+
return isinstance(operand, nervapy.x86_64.registers.MMXRegister)
|
|
655
|
+
|
|
656
|
+
|
|
657
|
+
def is_xmm(operand):
|
|
658
|
+
import nervapy.x86_64.registers
|
|
659
|
+
|
|
660
|
+
return isinstance(operand, nervapy.x86_64.registers.XMMRegister) and (
|
|
661
|
+
operand.physical_id is None or operand.physical_id < 16
|
|
662
|
+
)
|
|
663
|
+
|
|
664
|
+
|
|
665
|
+
def is_evex_xmm(operand):
|
|
666
|
+
import nervapy.x86_64.registers
|
|
667
|
+
|
|
668
|
+
return isinstance(operand, nervapy.x86_64.registers.XMMRegister)
|
|
669
|
+
|
|
670
|
+
|
|
671
|
+
def is_xmmk(operand):
|
|
672
|
+
import nervapy.x86_64.registers
|
|
673
|
+
|
|
674
|
+
return (
|
|
675
|
+
isinstance(operand, nervapy.x86_64.registers.XMMRegister)
|
|
676
|
+
or isinstance(operand, nervapy.x86_64.registers.MaskedRegister)
|
|
677
|
+
and isinstance(operand.register, nervapy.x86_64.registers.XMMRegister)
|
|
678
|
+
and not operand.mask.is_zeroing
|
|
679
|
+
)
|
|
680
|
+
|
|
681
|
+
|
|
682
|
+
def is_xmmkz(operand):
|
|
683
|
+
import nervapy.x86_64.registers
|
|
684
|
+
|
|
685
|
+
return (
|
|
686
|
+
isinstance(operand, nervapy.x86_64.registers.XMMRegister)
|
|
687
|
+
or isinstance(operand, nervapy.x86_64.registers.MaskedRegister)
|
|
688
|
+
and isinstance(operand.register, nervapy.x86_64.registers.XMMRegister)
|
|
689
|
+
)
|
|
690
|
+
|
|
691
|
+
|
|
692
|
+
def is_ymm(operand):
|
|
693
|
+
import nervapy.x86_64.registers
|
|
694
|
+
|
|
695
|
+
return isinstance(operand, nervapy.x86_64.registers.YMMRegister) and (
|
|
696
|
+
operand.physical_id is None or operand.physical_id < 16
|
|
697
|
+
)
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
def is_evex_ymm(operand):
|
|
701
|
+
import nervapy.x86_64.registers
|
|
702
|
+
|
|
703
|
+
return isinstance(operand, nervapy.x86_64.registers.YMMRegister)
|
|
704
|
+
|
|
705
|
+
|
|
706
|
+
def is_ymmk(operand):
|
|
707
|
+
import nervapy.x86_64.registers
|
|
708
|
+
|
|
709
|
+
return (
|
|
710
|
+
isinstance(operand, nervapy.x86_64.registers.YMMRegister)
|
|
711
|
+
or isinstance(operand, nervapy.x86_64.registers.MaskedRegister)
|
|
712
|
+
and isinstance(operand.register, nervapy.x86_64.registers.YMMRegister)
|
|
713
|
+
and not operand.mask.is_zeroing
|
|
714
|
+
)
|
|
715
|
+
|
|
716
|
+
|
|
717
|
+
def is_ymmkz(operand):
|
|
718
|
+
import nervapy.x86_64.registers
|
|
719
|
+
|
|
720
|
+
return (
|
|
721
|
+
isinstance(operand, nervapy.x86_64.registers.YMMRegister)
|
|
722
|
+
or isinstance(operand, nervapy.x86_64.registers.MaskedRegister)
|
|
723
|
+
and isinstance(operand.register, nervapy.x86_64.registers.YMMRegister)
|
|
724
|
+
)
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
def is_zmm(operand):
|
|
728
|
+
import nervapy.x86_64.registers
|
|
729
|
+
|
|
730
|
+
return isinstance(operand, nervapy.x86_64.registers.ZMMRegister)
|
|
731
|
+
|
|
732
|
+
|
|
733
|
+
def is_zmmk(operand):
|
|
734
|
+
import nervapy.x86_64.registers
|
|
735
|
+
|
|
736
|
+
return (
|
|
737
|
+
isinstance(operand, nervapy.x86_64.registers.ZMMRegister)
|
|
738
|
+
or isinstance(operand, nervapy.x86_64.registers.MaskedRegister)
|
|
739
|
+
and isinstance(operand.register, nervapy.x86_64.registers.ZMMRegister)
|
|
740
|
+
and not operand.mask.is_zeroing
|
|
741
|
+
)
|
|
742
|
+
|
|
743
|
+
|
|
744
|
+
def is_zmmkz(operand):
|
|
745
|
+
import nervapy.x86_64.registers
|
|
746
|
+
|
|
747
|
+
return (
|
|
748
|
+
isinstance(operand, nervapy.x86_64.registers.ZMMRegister)
|
|
749
|
+
or isinstance(operand, nervapy.x86_64.registers.MaskedRegister)
|
|
750
|
+
and isinstance(operand.register, nervapy.x86_64.registers.ZMMRegister)
|
|
751
|
+
)
|
|
752
|
+
|
|
753
|
+
|
|
754
|
+
def is_k(operand):
|
|
755
|
+
import nervapy.x86_64.registers
|
|
756
|
+
|
|
757
|
+
return isinstance(operand, nervapy.x86_64.registers.KRegister)
|
|
758
|
+
|
|
759
|
+
|
|
760
|
+
def is_kk(operand):
|
|
761
|
+
import nervapy.x86_64.registers
|
|
762
|
+
|
|
763
|
+
return (
|
|
764
|
+
isinstance(operand, nervapy.x86_64.registers.KRegister)
|
|
765
|
+
or isinstance(operand, nervapy.x86_64.registers.MaskedRegister)
|
|
766
|
+
and isinstance(operand.register, nervapy.x86_64.registers.KRegister)
|
|
767
|
+
and not operand.mask.is_zeroing
|
|
768
|
+
)
|
|
769
|
+
|
|
770
|
+
|
|
771
|
+
def is_m(operand):
|
|
772
|
+
if (
|
|
773
|
+
not isinstance(operand, MemoryOperand)
|
|
774
|
+
or operand.mask is not None
|
|
775
|
+
or operand.broadcast is not None
|
|
776
|
+
):
|
|
777
|
+
return False
|
|
778
|
+
# Check that the operand does not use vector index
|
|
779
|
+
from nervapy.x86_64.registers import GeneralPurposeRegister
|
|
780
|
+
|
|
781
|
+
return (
|
|
782
|
+
isinstance(operand.address, RIPRelativeOffset)
|
|
783
|
+
or operand.address.index is None
|
|
784
|
+
or isinstance(operand.address.index, GeneralPurposeRegister)
|
|
785
|
+
)
|
|
786
|
+
|
|
787
|
+
|
|
788
|
+
def is_mk(operand):
|
|
789
|
+
if not isinstance(operand, MemoryOperand) or operand.broadcast is not None:
|
|
790
|
+
return False
|
|
791
|
+
# Check that the no zero-masking applied to the operand
|
|
792
|
+
if operand.mask is not None and operand.mask.is_zeroing:
|
|
793
|
+
return False
|
|
794
|
+
# Check that the operand does not use vector index
|
|
795
|
+
from nervapy.x86_64.registers import GeneralPurposeRegister
|
|
796
|
+
|
|
797
|
+
return operand.address.index is None or isinstance(
|
|
798
|
+
operand.address.index, GeneralPurposeRegister
|
|
799
|
+
)
|
|
800
|
+
|
|
801
|
+
|
|
802
|
+
def is_mkz(operand):
|
|
803
|
+
if not isinstance(operand, MemoryOperand) or operand.broadcast is not None:
|
|
804
|
+
return False
|
|
805
|
+
# Check that the operand does not use vector index
|
|
806
|
+
from nervapy.x86_64.registers import GeneralPurposeRegister
|
|
807
|
+
|
|
808
|
+
return operand.address.index is None or isinstance(
|
|
809
|
+
operand.address.index, GeneralPurposeRegister
|
|
810
|
+
)
|
|
811
|
+
|
|
812
|
+
|
|
813
|
+
def is_vmx(operand):
|
|
814
|
+
from nervapy.x86_64.registers import XMMRegister
|
|
815
|
+
|
|
816
|
+
return (
|
|
817
|
+
isinstance(operand, MemoryOperand)
|
|
818
|
+
and isinstance(operand.address.index, XMMRegister)
|
|
819
|
+
and (operand.address.index is None or operand.address.index.physical_id < 16)
|
|
820
|
+
and operand.mask is None
|
|
821
|
+
)
|
|
822
|
+
|
|
823
|
+
|
|
824
|
+
def is_evex_vmx(operand):
|
|
825
|
+
from nervapy.x86_64.registers import XMMRegister
|
|
826
|
+
|
|
827
|
+
return (
|
|
828
|
+
isinstance(operand, MemoryOperand)
|
|
829
|
+
and isinstance(operand.address.index, XMMRegister)
|
|
830
|
+
and operand.mask is None
|
|
831
|
+
)
|
|
832
|
+
|
|
833
|
+
|
|
834
|
+
def is_vmxk(operand):
|
|
835
|
+
from nervapy.x86_64.registers import XMMRegister
|
|
836
|
+
|
|
837
|
+
return isinstance(operand, MemoryOperand) and isinstance(
|
|
838
|
+
operand.address.index, XMMRegister
|
|
839
|
+
)
|
|
840
|
+
|
|
841
|
+
|
|
842
|
+
def is_vmy(operand):
|
|
843
|
+
from nervapy.x86_64.registers import YMMRegister
|
|
844
|
+
|
|
845
|
+
return (
|
|
846
|
+
isinstance(operand, MemoryOperand)
|
|
847
|
+
and isinstance(operand.address.index, YMMRegister)
|
|
848
|
+
and (operand.address.index is None or operand.address.index.physical_id < 16)
|
|
849
|
+
and operand.mask is None
|
|
850
|
+
)
|
|
851
|
+
|
|
852
|
+
|
|
853
|
+
def is_evex_vmy(operand):
|
|
854
|
+
from nervapy.x86_64.registers import YMMRegister
|
|
855
|
+
|
|
856
|
+
return (
|
|
857
|
+
isinstance(operand, MemoryOperand)
|
|
858
|
+
and isinstance(operand.address.index, YMMRegister)
|
|
859
|
+
and operand.mask is None
|
|
860
|
+
)
|
|
861
|
+
|
|
862
|
+
|
|
863
|
+
def is_vmyk(operand):
|
|
864
|
+
from nervapy.x86_64.registers import YMMRegister
|
|
865
|
+
|
|
866
|
+
return isinstance(operand, MemoryOperand) and isinstance(
|
|
867
|
+
operand.address.index, YMMRegister
|
|
868
|
+
)
|
|
869
|
+
|
|
870
|
+
|
|
871
|
+
def is_vmz(operand):
|
|
872
|
+
from nervapy.x86_64.registers import ZMMRegister
|
|
873
|
+
|
|
874
|
+
return (
|
|
875
|
+
isinstance(operand, MemoryOperand)
|
|
876
|
+
and isinstance(operand.address.index, ZMMRegister)
|
|
877
|
+
and operand.mask is None
|
|
878
|
+
)
|
|
879
|
+
|
|
880
|
+
|
|
881
|
+
def is_vmzk(operand):
|
|
882
|
+
from nervapy.x86_64.registers import ZMMRegister
|
|
883
|
+
|
|
884
|
+
return isinstance(operand, MemoryOperand) and isinstance(
|
|
885
|
+
operand.address.index, ZMMRegister
|
|
886
|
+
)
|
|
887
|
+
|
|
888
|
+
|
|
889
|
+
def is_m8(operand, strict=False):
|
|
890
|
+
return is_m(operand) and (operand.size is None and not strict or operand.size == 1)
|
|
891
|
+
|
|
892
|
+
|
|
893
|
+
def is_m16(operand, strict=False):
|
|
894
|
+
import nervapy.literal
|
|
895
|
+
|
|
896
|
+
return (
|
|
897
|
+
is_m(operand)
|
|
898
|
+
and (operand.size is None and not strict or operand.size == 2)
|
|
899
|
+
or isinstance(operand, nervapy.literal.Constant)
|
|
900
|
+
and operand.size == 2
|
|
901
|
+
)
|
|
902
|
+
|
|
903
|
+
|
|
904
|
+
def is_m16kz(operand):
|
|
905
|
+
return is_mkz(operand) and (operand.size is None or operand.size == 2)
|
|
906
|
+
|
|
907
|
+
|
|
908
|
+
def is_m32(operand, strict=False):
|
|
909
|
+
import nervapy.literal
|
|
910
|
+
|
|
911
|
+
return (
|
|
912
|
+
is_m(operand)
|
|
913
|
+
and (operand.size is None and not strict or operand.size == 4)
|
|
914
|
+
or isinstance(operand, nervapy.literal.Constant)
|
|
915
|
+
and operand.size == 4
|
|
916
|
+
)
|
|
917
|
+
|
|
918
|
+
|
|
919
|
+
def is_m32k(operand):
|
|
920
|
+
return is_mk(operand) and (operand.size is None or operand.size == 4)
|
|
921
|
+
|
|
922
|
+
|
|
923
|
+
def is_m32kz(operand):
|
|
924
|
+
return is_mkz(operand) and (operand.size is None or operand.size == 4)
|
|
925
|
+
|
|
926
|
+
|
|
927
|
+
def is_m64(operand, strict=False):
|
|
928
|
+
import nervapy.literal
|
|
929
|
+
|
|
930
|
+
return (
|
|
931
|
+
is_m(operand)
|
|
932
|
+
and (operand.size is None and not strict or operand.size == 8)
|
|
933
|
+
or isinstance(operand, nervapy.literal.Constant)
|
|
934
|
+
and operand.size == 8
|
|
935
|
+
)
|
|
936
|
+
|
|
937
|
+
|
|
938
|
+
def is_m64k(operand):
|
|
939
|
+
return is_mk(operand) and (operand.size is None or operand.size == 8)
|
|
940
|
+
|
|
941
|
+
|
|
942
|
+
def is_m64kz(operand):
|
|
943
|
+
return is_mkz(operand) and (operand.size is None or operand.size == 8)
|
|
944
|
+
|
|
945
|
+
|
|
946
|
+
def is_m80(operand, strict=False):
|
|
947
|
+
return is_m(operand) and (operand.size is None and not strict or operand.size == 10)
|
|
948
|
+
|
|
949
|
+
|
|
950
|
+
def is_m128(operand, strict=False):
|
|
951
|
+
import nervapy.literal
|
|
952
|
+
|
|
953
|
+
return (
|
|
954
|
+
is_m(operand)
|
|
955
|
+
and (operand.size is None and not strict or operand.size == 16)
|
|
956
|
+
or isinstance(operand, nervapy.literal.Constant)
|
|
957
|
+
and operand.size == 16
|
|
958
|
+
)
|
|
959
|
+
|
|
960
|
+
|
|
961
|
+
def is_m128kz(operand):
|
|
962
|
+
return is_mkz(operand) and (operand.size is None or operand.size == 16)
|
|
963
|
+
|
|
964
|
+
|
|
965
|
+
def is_m256(operand, strict=False):
|
|
966
|
+
import nervapy.literal
|
|
967
|
+
|
|
968
|
+
return (
|
|
969
|
+
is_m(operand)
|
|
970
|
+
and (operand.size is None and not strict or operand.size == 32)
|
|
971
|
+
or isinstance(operand, nervapy.literal.Constant)
|
|
972
|
+
and operand.size == 32
|
|
973
|
+
)
|
|
974
|
+
|
|
975
|
+
|
|
976
|
+
def is_m256kz(operand):
|
|
977
|
+
return is_mkz(operand) and (operand.size is None or operand.size == 32)
|
|
978
|
+
|
|
979
|
+
|
|
980
|
+
def is_m512(operand, strict=False):
|
|
981
|
+
import nervapy.literal
|
|
982
|
+
|
|
983
|
+
return (
|
|
984
|
+
is_m(operand)
|
|
985
|
+
and (operand.size is None and not strict or operand.size == 64)
|
|
986
|
+
or isinstance(operand, nervapy.literal.Constant)
|
|
987
|
+
and operand.size == 64
|
|
988
|
+
)
|
|
989
|
+
|
|
990
|
+
|
|
991
|
+
def is_m512kz(operand):
|
|
992
|
+
return is_mkz(operand) and (operand.size is None or operand.size == 64)
|
|
993
|
+
|
|
994
|
+
|
|
995
|
+
def is_m64_m32bcst(operand):
|
|
996
|
+
return (
|
|
997
|
+
is_m64(operand)
|
|
998
|
+
or isinstance(operand, MemoryOperand)
|
|
999
|
+
and operand.size == 4
|
|
1000
|
+
and operand.broadcast == 2
|
|
1001
|
+
)
|
|
1002
|
+
|
|
1003
|
+
|
|
1004
|
+
def is_m128_m32bcst(operand):
|
|
1005
|
+
return (
|
|
1006
|
+
is_m128(operand)
|
|
1007
|
+
or isinstance(operand, MemoryOperand)
|
|
1008
|
+
and operand.size == 4
|
|
1009
|
+
and operand.broadcast == 4
|
|
1010
|
+
)
|
|
1011
|
+
|
|
1012
|
+
|
|
1013
|
+
def is_m256_m32bcst(operand):
|
|
1014
|
+
return (
|
|
1015
|
+
is_m256(operand)
|
|
1016
|
+
or isinstance(operand, MemoryOperand)
|
|
1017
|
+
and operand.size == 4
|
|
1018
|
+
and operand.broadcast == 8
|
|
1019
|
+
)
|
|
1020
|
+
|
|
1021
|
+
|
|
1022
|
+
def is_m512_m32bcst(operand):
|
|
1023
|
+
return (
|
|
1024
|
+
is_m512(operand)
|
|
1025
|
+
or isinstance(operand, MemoryOperand)
|
|
1026
|
+
and operand.size == 4
|
|
1027
|
+
and operand.broadcast == 16
|
|
1028
|
+
)
|
|
1029
|
+
|
|
1030
|
+
|
|
1031
|
+
def is_m128_m64bcst(operand):
|
|
1032
|
+
return (
|
|
1033
|
+
is_m128(operand)
|
|
1034
|
+
or isinstance(operand, MemoryOperand)
|
|
1035
|
+
and operand.size == 8
|
|
1036
|
+
and operand.broadcast == 2
|
|
1037
|
+
)
|
|
1038
|
+
|
|
1039
|
+
|
|
1040
|
+
def is_m256_m64bcst(operand):
|
|
1041
|
+
return (
|
|
1042
|
+
is_m256(operand)
|
|
1043
|
+
or isinstance(operand, MemoryOperand)
|
|
1044
|
+
and operand.size == 8
|
|
1045
|
+
and operand.broadcast == 4
|
|
1046
|
+
)
|
|
1047
|
+
|
|
1048
|
+
|
|
1049
|
+
def is_m512_m64bcst(operand):
|
|
1050
|
+
return (
|
|
1051
|
+
is_m512(operand)
|
|
1052
|
+
or isinstance(operand, MemoryOperand)
|
|
1053
|
+
and operand.size == 8
|
|
1054
|
+
and operand.broadcast == 8
|
|
1055
|
+
)
|
|
1056
|
+
|
|
1057
|
+
|
|
1058
|
+
def is_m32bcst(operand):
|
|
1059
|
+
return False
|
|
1060
|
+
|
|
1061
|
+
|
|
1062
|
+
def is_m64bcst(operand):
|
|
1063
|
+
return False
|
|
1064
|
+
|
|
1065
|
+
|
|
1066
|
+
def is_imm(operand):
|
|
1067
|
+
import nervapy.util
|
|
1068
|
+
|
|
1069
|
+
return nervapy.util.is_int(operand)
|
|
1070
|
+
|
|
1071
|
+
|
|
1072
|
+
def is_imm4(operand):
|
|
1073
|
+
import nervapy.util
|
|
1074
|
+
|
|
1075
|
+
return nervapy.util.is_int(operand) and 0 <= operand <= 15
|
|
1076
|
+
|
|
1077
|
+
|
|
1078
|
+
def is_imm8(operand, ext_size=None):
|
|
1079
|
+
import nervapy.util
|
|
1080
|
+
|
|
1081
|
+
if ext_size is None:
|
|
1082
|
+
return nervapy.util.is_int8(operand)
|
|
1083
|
+
else:
|
|
1084
|
+
sup = 2 ** (8 * ext_size)
|
|
1085
|
+
return nervapy.util.is_int(operand) and (
|
|
1086
|
+
-128 <= operand <= 127 or sup - 128 <= operand < sup
|
|
1087
|
+
)
|
|
1088
|
+
|
|
1089
|
+
|
|
1090
|
+
def is_imm16(operand, ext_size=None):
|
|
1091
|
+
import nervapy.util
|
|
1092
|
+
|
|
1093
|
+
if ext_size is None:
|
|
1094
|
+
return nervapy.util.is_int16(operand)
|
|
1095
|
+
else:
|
|
1096
|
+
sup = 2 ** (8 * ext_size)
|
|
1097
|
+
return nervapy.util.is_int(operand) and (
|
|
1098
|
+
-32768 <= operand <= 32767 or sup - 32768 <= operand < sup
|
|
1099
|
+
)
|
|
1100
|
+
|
|
1101
|
+
|
|
1102
|
+
def is_imm32(operand, ext_size=None):
|
|
1103
|
+
import nervapy.util
|
|
1104
|
+
|
|
1105
|
+
if ext_size is None:
|
|
1106
|
+
return nervapy.util.is_int32(operand)
|
|
1107
|
+
else:
|
|
1108
|
+
sup = 2 ** (8 * ext_size)
|
|
1109
|
+
return nervapy.util.is_int(operand) and (
|
|
1110
|
+
-2147483648 <= operand <= 2147483647 or sup - 2147483648 <= operand < sup
|
|
1111
|
+
)
|
|
1112
|
+
|
|
1113
|
+
|
|
1114
|
+
def is_imm64(operand):
|
|
1115
|
+
import nervapy.util
|
|
1116
|
+
|
|
1117
|
+
return nervapy.util.is_int64(operand)
|
|
1118
|
+
|
|
1119
|
+
|
|
1120
|
+
def is_rel8(operand):
|
|
1121
|
+
from nervapy.util import is_sint8
|
|
1122
|
+
|
|
1123
|
+
return isinstance(operand, RIPRelativeOffset) and is_sint8(operand.offset)
|
|
1124
|
+
|
|
1125
|
+
|
|
1126
|
+
def is_rel32(operand):
|
|
1127
|
+
from nervapy.util import is_sint32
|
|
1128
|
+
|
|
1129
|
+
return isinstance(operand, RIPRelativeOffset) and is_sint32(operand.offset)
|
|
1130
|
+
|
|
1131
|
+
|
|
1132
|
+
def is_label(operand):
|
|
1133
|
+
import nervapy.x86_64.pseudo
|
|
1134
|
+
|
|
1135
|
+
return isinstance(operand, nervapy.x86_64.pseudo.Label)
|
|
1136
|
+
|
|
1137
|
+
|
|
1138
|
+
def is_er(operand):
|
|
1139
|
+
return isinstance(operand, RoundingControl)
|
|
1140
|
+
|
|
1141
|
+
|
|
1142
|
+
def is_sae(operand):
|
|
1143
|
+
return isinstance(operand, SuppressAllExceptions)
|
|
1144
|
+
|
|
1145
|
+
|
|
1146
|
+
byte = SizeSpecification(1)
|
|
1147
|
+
word = SizeSpecification(2)
|
|
1148
|
+
dword = SizeSpecification(4)
|
|
1149
|
+
qword = SizeSpecification(8)
|
|
1150
|
+
tword = SizeSpecification(10)
|
|
1151
|
+
oword = SizeSpecification(16)
|
|
1152
|
+
hword = SizeSpecification(32)
|
|
1153
|
+
yword = SizeSpecification(32)
|
|
1154
|
+
zword = SizeSpecification(64)
|
|
1155
|
+
|
|
1156
|
+
|
|
1157
|
+
class RoundingControl:
|
|
1158
|
+
def __init__(self, name, code):
|
|
1159
|
+
self.name = name
|
|
1160
|
+
self.code = code
|
|
1161
|
+
|
|
1162
|
+
def __hash__(self):
|
|
1163
|
+
return hash(self.name)
|
|
1164
|
+
|
|
1165
|
+
def __eq__(self, other):
|
|
1166
|
+
return (
|
|
1167
|
+
isinstance(other, RoundingControl)
|
|
1168
|
+
and other.name == self.name
|
|
1169
|
+
and other.code == self.code
|
|
1170
|
+
)
|
|
1171
|
+
|
|
1172
|
+
def __ne__(self, other):
|
|
1173
|
+
return (
|
|
1174
|
+
not isinstance(other, RoundingControl)
|
|
1175
|
+
or other.name != self.name
|
|
1176
|
+
or other.code != self.code
|
|
1177
|
+
)
|
|
1178
|
+
|
|
1179
|
+
def __str__(self):
|
|
1180
|
+
return "{" + self.name + "}"
|
|
1181
|
+
|
|
1182
|
+
|
|
1183
|
+
class SuppressAllExceptions:
|
|
1184
|
+
def __init__(self, name):
|
|
1185
|
+
self.name = name
|
|
1186
|
+
|
|
1187
|
+
def __hash__(self):
|
|
1188
|
+
return hash(self.name)
|
|
1189
|
+
|
|
1190
|
+
def __eq__(self, other):
|
|
1191
|
+
return isinstance(other, SuppressAllExceptions) and other.name == self.name
|
|
1192
|
+
|
|
1193
|
+
def __ne__(self, other):
|
|
1194
|
+
return not isinstance(other, SuppressAllExceptions) or other.name != self.name
|
|
1195
|
+
|
|
1196
|
+
def __str__(self):
|
|
1197
|
+
return "{" + self.name + "}"
|
|
1198
|
+
|
|
1199
|
+
|
|
1200
|
+
rn_sae = RoundingControl("rn-sae", 0b00)
|
|
1201
|
+
rz_sae = RoundingControl("rz-sae", 0b11)
|
|
1202
|
+
ru_sae = RoundingControl("ru-sae", 0b10)
|
|
1203
|
+
rd_sae = RoundingControl("rd-sae", 0b01)
|
|
1204
|
+
sae = SuppressAllExceptions("sae")
|