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.
Files changed (74) hide show
  1. nervapy/__init__.py +50 -0
  2. nervapy/abi.py +91 -0
  3. nervapy/arm/__init__.py +124 -0
  4. nervapy/arm/__main__.py +0 -0
  5. nervapy/arm/abi.py +138 -0
  6. nervapy/arm/formats.py +49 -0
  7. nervapy/arm/function.py +2465 -0
  8. nervapy/arm/generic.py +10796 -0
  9. nervapy/arm/instructions.py +519 -0
  10. nervapy/arm/isa.py +409 -0
  11. nervapy/arm/literal_pool.py +331 -0
  12. nervapy/arm/microarchitecture.py +211 -0
  13. nervapy/arm/pseudo.py +652 -0
  14. nervapy/arm/registers.py +1458 -0
  15. nervapy/arm/vfpneon.py +4092 -0
  16. nervapy/arm.py +13 -0
  17. nervapy/c/__init__.py +1 -0
  18. nervapy/c/types.py +436 -0
  19. nervapy/codegen.py +99 -0
  20. nervapy/common/__init__.py +4 -0
  21. nervapy/common/function.py +5 -0
  22. nervapy/common/regalloc.py +121 -0
  23. nervapy/constant_data.py +282 -0
  24. nervapy/encoder.py +246 -0
  25. nervapy/formats/__init__.py +2 -0
  26. nervapy/formats/elf/__init__.py +4 -0
  27. nervapy/formats/elf/file.py +178 -0
  28. nervapy/formats/elf/image.py +106 -0
  29. nervapy/formats/elf/section.py +422 -0
  30. nervapy/formats/elf/symbol.py +281 -0
  31. nervapy/formats/macho/__init__.py +2 -0
  32. nervapy/formats/macho/file.py +123 -0
  33. nervapy/formats/macho/image.py +143 -0
  34. nervapy/formats/macho/section.py +322 -0
  35. nervapy/formats/macho/symbol.py +158 -0
  36. nervapy/formats/mscoff/__init__.py +8 -0
  37. nervapy/formats/mscoff/image.py +132 -0
  38. nervapy/formats/mscoff/section.py +181 -0
  39. nervapy/formats/mscoff/symbol.py +148 -0
  40. nervapy/function.py +136 -0
  41. nervapy/literal.py +731 -0
  42. nervapy/loader.py +188 -0
  43. nervapy/name.py +159 -0
  44. nervapy/parse.py +52 -0
  45. nervapy/stream.py +58 -0
  46. nervapy/util.py +126 -0
  47. nervapy/writer.py +518 -0
  48. nervapy/x86_64/__init__.py +324 -0
  49. nervapy/x86_64/__main__.py +407 -0
  50. nervapy/x86_64/abi.py +517 -0
  51. nervapy/x86_64/amd.py +6464 -0
  52. nervapy/x86_64/avx.py +102029 -0
  53. nervapy/x86_64/crypto.py +1533 -0
  54. nervapy/x86_64/encoding.py +424 -0
  55. nervapy/x86_64/fma.py +19138 -0
  56. nervapy/x86_64/function.py +2707 -0
  57. nervapy/x86_64/generic.py +23384 -0
  58. nervapy/x86_64/instructions.py +500 -0
  59. nervapy/x86_64/isa.py +476 -0
  60. nervapy/x86_64/lower.py +126 -0
  61. nervapy/x86_64/mask.py +2593 -0
  62. nervapy/x86_64/meta.py +143 -0
  63. nervapy/x86_64/mmxsse.py +17265 -0
  64. nervapy/x86_64/nacl.py +327 -0
  65. nervapy/x86_64/operand.py +1204 -0
  66. nervapy/x86_64/options.py +21 -0
  67. nervapy/x86_64/pseudo.py +686 -0
  68. nervapy/x86_64/registers.py +1225 -0
  69. nervapy/x86_64/types.py +17 -0
  70. nervapy/x86_64/uarch.py +580 -0
  71. pynerva-0.0.7.dist-info/METADATA +310 -0
  72. pynerva-0.0.7.dist-info/RECORD +74 -0
  73. pynerva-0.0.7.dist-info/WHEEL +4 -0
  74. 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")