PyNerva 0.0.5__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.

Potentially problematic release.


This version of PyNerva might be problematic. Click here for more details.

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 +2405 -0
  8. nervapy/arm/generic.py +10797 -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.5.dist-info/METADATA +310 -0
  72. pynerva-0.0.5.dist-info/RECORD +74 -0
  73. pynerva-0.0.5.dist-info/WHEEL +4 -0
  74. pynerva-0.0.5.dist-info/licenses/LICENSE.rst +15 -0
@@ -0,0 +1,1225 @@
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
+ from typing import Any, ClassVar, Dict, Optional
6
+
7
+ import six
8
+
9
+
10
+ class Register(object):
11
+ """A base class for all encodable registers (rip is not encodable)"""
12
+
13
+ _mask_size_map = {
14
+ 0x1: 1,
15
+ 0x2: 1,
16
+ 0x3: 2,
17
+ 0x7: 4,
18
+ 0xF: 8,
19
+ 0x10: 8,
20
+ 0x40: 8,
21
+ 0x100: 16,
22
+ 0x300: 32,
23
+ 0x700: 64,
24
+ }
25
+ size: Optional[int] = None
26
+
27
+ def __init__(self, mask, virtual_id=None, physical_id=None):
28
+ super(Register, self).__init__()
29
+ from nervapy.util import is_int
30
+
31
+ assert is_int(mask), "Mask must be an integer"
32
+ assert mask in Register._mask_size_map, "Unknown mask value: %X" % mask
33
+ self.mask = int(mask)
34
+ assert (
35
+ virtual_id is not None or physical_id is not None
36
+ ), "Virtual or physical ID must be specified"
37
+ assert (
38
+ virtual_id is None or is_int(virtual_id) and virtual_id > 0
39
+ ), "Virtual ID must be a positive integer"
40
+ assert (
41
+ physical_id is None or is_int(physical_id) and physical_id >= 0
42
+ ), "Physical ID must be a non-negative integer"
43
+ self.virtual_id = None if virtual_id is None else int(virtual_id)
44
+ self.physical_id = None if physical_id is None else int(physical_id)
45
+
46
+ def __eq__(self, other):
47
+ return (
48
+ isinstance(other, Register)
49
+ and self.mask == other.mask
50
+ and self._internal_id == other._internal_id
51
+ )
52
+
53
+ def __ne__(self, other):
54
+ return (
55
+ not isinstance(other, Register)
56
+ or self.mask != other.mask
57
+ or self._internal_id != other._internal_id
58
+ )
59
+
60
+ def __lt__(self, other):
61
+ return isinstance(other, Register) and (self.mask, -self._internal_id) < (
62
+ other.mask,
63
+ -other._internal_id,
64
+ )
65
+
66
+ def __le__(self, other):
67
+ return isinstance(other, Register) and (self.mask, -self._internal_id) <= (
68
+ other.mask,
69
+ -other._internal_id,
70
+ )
71
+
72
+ def __hash__(self):
73
+ h = hash(self.mask)
74
+ if self.physical_id is not None:
75
+ return hash(self.physical_id) ^ h
76
+ else:
77
+ return hash(self.virtual_id) ^ h
78
+
79
+ def __repr__(self):
80
+ return str(self)
81
+
82
+ @property
83
+ def _internal_id(self):
84
+ if self.is_virtual:
85
+ return -self.virtual_id
86
+ else:
87
+ return self.physical_id
88
+
89
+ @staticmethod
90
+ def _reconstruct(internal_id, mask):
91
+ registers = set()
92
+ if internal_id >= 0:
93
+ # Physical register
94
+ if mask & 0x400 != 0:
95
+ mask &= ~0x700
96
+ registers.add(ZMMRegister(physical_id=internal_id))
97
+ elif mask & 0x200 != 0:
98
+ mask &= ~0x300
99
+ registers.add(YMMRegister(physical_id=internal_id))
100
+ elif mask & 0x100 != 0:
101
+ mask &= ~0x100
102
+ registers.add(XMMRegister(physical_id=internal_id))
103
+ if mask & 0x10 != 0:
104
+ mask &= ~0x10
105
+ registers.add(MMXRegister(physical_id=internal_id))
106
+ if mask & 0x8 != 0:
107
+ mask &= ~0xF
108
+ registers.add(GeneralPurposeRegister64(physical_id=internal_id))
109
+ elif mask & 0x4 != 0:
110
+ mask &= ~0x7
111
+ registers.add(GeneralPurposeRegister32(physical_id=internal_id))
112
+ elif mask & 0x2 != 0:
113
+ mask &= ~0x3
114
+ registers.add(GeneralPurposeRegister16(physical_id=internal_id))
115
+ elif mask & 0x1 != 0:
116
+ mask &= ~0x1
117
+ registers.add(GeneralPurposeRegister8(physical_id=internal_id))
118
+ assert mask == 0, "Unknown register mask component: %X" % mask
119
+ else:
120
+ # Virtual register
121
+ # Physical register
122
+ if mask & 0x400 != 0:
123
+ mask &= ~0x700
124
+ registers.add(ZMMRegister(virtual_id=-internal_id))
125
+ elif mask & 0x200 != 0:
126
+ mask &= ~0x300
127
+ registers.add(YMMRegister(virtual_id=-internal_id))
128
+ elif mask & 0x100 != 0:
129
+ mask &= ~0x100
130
+ registers.add(XMMRegister(virtual_id=-internal_id))
131
+ if mask & 0x10 != 0:
132
+ mask &= ~0x10
133
+ registers.add(MMXRegister(virtual_id=-internal_id))
134
+ if mask & 0x40 != 0:
135
+ mask &= ~0x40
136
+ registers.add(KRegister(virtual_id=-internal_id))
137
+ if mask & 0x8 != 0:
138
+ mask &= ~0xF
139
+ registers.add(GeneralPurposeRegister64(virtual_id=-internal_id))
140
+ elif mask & 0x4 != 0:
141
+ mask &= ~0x7
142
+ registers.add(GeneralPurposeRegister32(virtual_id=-internal_id))
143
+ elif mask & 0x2 != 0:
144
+ mask &= ~0x3
145
+ registers.add(GeneralPurposeRegister16(virtual_id=-internal_id))
146
+ elif mask & 0x1 != 0:
147
+ mask &= ~0x1
148
+ registers.add(GeneralPurposeRegister8(virtual_id=-internal_id))
149
+ assert mask == 0, "Unknown register mask component: %X" % mask
150
+ return registers
151
+
152
+ @staticmethod
153
+ def _reconstruct_multiple(reg_dict):
154
+ reg_set = set()
155
+ for reg_id, reg_mask in six.iteritems(reg_dict):
156
+ reg_set.update(Register._reconstruct(reg_id, reg_mask))
157
+ return reg_set
158
+
159
+ @property
160
+ def kind(self):
161
+ if self.mask & GeneralPurposeRegister64._mask != 0:
162
+ return GeneralPurposeRegister._kind
163
+ elif self.mask & MMXRegister._mask != 0:
164
+ return MMXRegister._kind
165
+ elif self.mask & XMMRegister._mask != 0:
166
+ return XMMRegister._kind
167
+ elif self.mask & KRegister._mask != 0:
168
+ return KRegister._kind
169
+ else:
170
+ assert False, "Unknown register mask: %X" % self.mask
171
+
172
+ @property
173
+ def is_virtual(self):
174
+ """Indicated if a register is virtual, i.e. not bounded to a physical register"""
175
+ return self.physical_id is None
176
+
177
+ @property
178
+ def lcode(self):
179
+ """Returns the bits 0-2 of register encoding"""
180
+ assert (
181
+ self.physical_id is not None
182
+ ), "The method returns encoding detail for a physical register"
183
+ if self.mask == GeneralPurposeRegister8._high_mask:
184
+ assert (
185
+ self.physical_id & ~0x3 == 0
186
+ ), "Only ah, bh, ch, dh can be the high 8-bit registers"
187
+ return 0x4 | self.physical_id
188
+ else:
189
+ return self.physical_id & 0x7
190
+
191
+ @property
192
+ def hcode(self):
193
+ """Returns the bit 3 of register encoding"""
194
+ assert (
195
+ self.physical_id is not None
196
+ ), "The method returns encoding detail for a physical register"
197
+ return (self.physical_id >> 3) & 1
198
+
199
+ @property
200
+ def ecode(self):
201
+ """Returns the bit 4 of register encoding"""
202
+ assert (
203
+ self.physical_id is not None
204
+ ), "The method returns encoding detail for a physical register"
205
+ return (self.physical_id >> 4) & 1
206
+
207
+ @property
208
+ def hlcode(self):
209
+ """Returns the bits 0-3 of register encoding"""
210
+ assert (
211
+ self.physical_id is not None
212
+ ), "The method returns encoding detail for a physical register"
213
+ assert (
214
+ self.mask != GeneralPurposeRegister8._high_mask
215
+ ), "ah/bh/ch/dh registers never use 4-bit encoding"
216
+ return self.physical_id & 0xF
217
+
218
+ @property
219
+ def ehcode(self):
220
+ """Returns the bits 3-4 of register encoding"""
221
+ assert (
222
+ self.physical_id is not None
223
+ ), "The method returns encoding detail for a physical register"
224
+ return (self.physical_id >> 3) & 0b11
225
+
226
+
227
+ class GeneralPurposeRegister(Register):
228
+ """A base class for general-purpose registers"""
229
+
230
+ _go_physical_id_map: ClassVar[Dict[Any, str]] = {
231
+ 0x0: "AX",
232
+ 0x1: "CX",
233
+ 0x2: "DX",
234
+ 0x3: "BX",
235
+ 0x4: "SP",
236
+ 0x5: "BP",
237
+ 0x6: "SI",
238
+ 0x7: "DI",
239
+ 0x8: "R8",
240
+ 0x9: "R9",
241
+ 0xA: "R10",
242
+ 0xB: "R11",
243
+ 0xC: "R12",
244
+ 0xD: "R13",
245
+ 0xE: "R14",
246
+ 0xF: "R15",
247
+ }
248
+ _kind = 1
249
+
250
+ def __init__(self, mask, virtual_id=None, physical_id=None):
251
+ super(GeneralPurposeRegister, self).__init__(mask, virtual_id, physical_id)
252
+
253
+ @property
254
+ def as_low_byte(self):
255
+ return GeneralPurposeRegister8(self.physical_id, self.virtual_id)
256
+
257
+ @property
258
+ def as_word(self):
259
+ return GeneralPurposeRegister16(self.physical_id, self.virtual_id)
260
+
261
+ @property
262
+ def as_dword(self):
263
+ return GeneralPurposeRegister32(self.physical_id, self.virtual_id)
264
+
265
+ @property
266
+ def as_qword(self):
267
+ return GeneralPurposeRegister64(self.physical_id, self.virtual_id)
268
+
269
+ def format(self, assembly_format):
270
+ assert assembly_format in {
271
+ "peachpy",
272
+ "gas",
273
+ "nasm",
274
+ "go",
275
+ }, "Supported assembly formats are 'peachpy', 'gas', 'nasm', 'go'"
276
+
277
+ if assembly_format == "go":
278
+ assert (
279
+ not self.is_virtual
280
+ ), "Go assembler does not support virtual registers"
281
+ return GeneralPurposeRegister._go_physical_id_map[self.physical_id]
282
+ elif assembly_format == "gas":
283
+ return "%" + str(self)
284
+ else:
285
+ return str(self)
286
+
287
+
288
+ class GeneralPurposeRegister64(GeneralPurposeRegister):
289
+ """64-bit general-purpose register"""
290
+
291
+ size = 8
292
+
293
+ _physical_id_map = {
294
+ 0x0: "rax",
295
+ 0x1: "rcx",
296
+ 0x2: "rdx",
297
+ 0x3: "rbx",
298
+ 0x4: "rsp",
299
+ 0x5: "rbp",
300
+ 0x6: "rsi",
301
+ 0x7: "rdi",
302
+ 0x8: "r8",
303
+ 0x9: "r9",
304
+ 0xA: "r10",
305
+ 0xB: "r11",
306
+ 0xC: "r12",
307
+ 0xD: "r13",
308
+ 0xE: "r14",
309
+ 0xF: "r15",
310
+ }
311
+ _mask = 0xF
312
+
313
+ def __init__(self, physical_id=None, virtual_id=None):
314
+ if virtual_id is None and physical_id is None:
315
+ from nervapy.common.function import active_function
316
+
317
+ super(GeneralPurposeRegister64, self).__init__(
318
+ GeneralPurposeRegister64._mask,
319
+ active_function._allocate_general_purpose_register_id(),
320
+ )
321
+ else:
322
+ super(GeneralPurposeRegister64, self).__init__(
323
+ GeneralPurposeRegister64._mask, virtual_id, physical_id
324
+ )
325
+
326
+ def __str__(self):
327
+ if self.is_virtual:
328
+ return "gp64-vreg<%d>" % self.virtual_id
329
+ else:
330
+ return GeneralPurposeRegister64._physical_id_map[self.physical_id]
331
+
332
+ def __add__(self, offset):
333
+ from nervapy.x86_64.operand import MemoryAddress
334
+
335
+ return MemoryAddress(self) + offset
336
+
337
+ def __sub__(self, offset):
338
+ from nervapy.x86_64.operand import MemoryAddress
339
+
340
+ return MemoryAddress(self) - offset
341
+
342
+ def __mul__(self, scale):
343
+ from nervapy.util import is_int
344
+ from nervapy.x86_64.operand import MemoryAddress
345
+
346
+ if not is_int(scale):
347
+ raise TypeError("Register can be scaled only by an integer number")
348
+ if int(scale) not in {1, 2, 4, 8}:
349
+ raise ValueError(
350
+ "Invalid scale value (%d): only scaling by 1, 2, 4, or 8 is supported"
351
+ % scale
352
+ )
353
+ return MemoryAddress(index=self, scale=scale)
354
+
355
+
356
+ rax = GeneralPurposeRegister64(0)
357
+ rcx = GeneralPurposeRegister64(1)
358
+ rdx = GeneralPurposeRegister64(2)
359
+ rbx = GeneralPurposeRegister64(3)
360
+ rsp = GeneralPurposeRegister64(4)
361
+ rbp = GeneralPurposeRegister64(5)
362
+ rsi = GeneralPurposeRegister64(6)
363
+ rdi = GeneralPurposeRegister64(7)
364
+ r8 = GeneralPurposeRegister64(8)
365
+ r9 = GeneralPurposeRegister64(9)
366
+ r10 = GeneralPurposeRegister64(10)
367
+ r11 = GeneralPurposeRegister64(11)
368
+ r12 = GeneralPurposeRegister64(12)
369
+ r13 = GeneralPurposeRegister64(13)
370
+ r14 = GeneralPurposeRegister64(14)
371
+ r15 = GeneralPurposeRegister64(15)
372
+
373
+
374
+ class GeneralPurposeRegister32(GeneralPurposeRegister):
375
+ """32-bit general-purpose register"""
376
+
377
+ size = 4
378
+
379
+ _physical_id_map = {
380
+ 0x0: "eax",
381
+ 0x1: "ecx",
382
+ 0x2: "edx",
383
+ 0x3: "ebx",
384
+ 0x4: "esp",
385
+ 0x5: "ebp",
386
+ 0x6: "esi",
387
+ 0x7: "edi",
388
+ 0x8: "r8d",
389
+ 0x9: "r9d",
390
+ 0xA: "r10d",
391
+ 0xB: "r11d",
392
+ 0xC: "r12d",
393
+ 0xD: "r13d",
394
+ 0xE: "r14d",
395
+ 0xF: "r15d",
396
+ }
397
+ _mask = 0x7
398
+
399
+ def __init__(self, physical_id=None, virtual_id=None):
400
+ if virtual_id is None and physical_id is None:
401
+ from nervapy.common.function import active_function
402
+
403
+ super(GeneralPurposeRegister32, self).__init__(
404
+ GeneralPurposeRegister32._mask,
405
+ active_function._allocate_general_purpose_register_id(),
406
+ )
407
+ else:
408
+ super(GeneralPurposeRegister32, self).__init__(
409
+ GeneralPurposeRegister32._mask, virtual_id, physical_id
410
+ )
411
+
412
+ def __str__(self):
413
+ if self.is_virtual:
414
+ return "gp32-vreg<%d>" % self.virtual_id
415
+ else:
416
+ return GeneralPurposeRegister32._physical_id_map[self.physical_id]
417
+
418
+ def __add__(self, offset):
419
+ from nervapy.x86_64.operand import MemoryAddress
420
+
421
+ return MemoryAddress(self) + offset
422
+
423
+ def __sub__(self, offset):
424
+ from nervapy.x86_64.operand import MemoryAddress
425
+
426
+ return MemoryAddress(self) - offset
427
+
428
+ def __mul__(self, scale):
429
+ from nervapy.util import is_int
430
+ from nervapy.x86_64.operand import MemoryAddress
431
+
432
+ if not is_int(scale):
433
+ raise TypeError("Register can be scaled only by an integer number")
434
+ if int(scale) not in {1, 2, 4, 8}:
435
+ raise ValueError(
436
+ "Invalid scale value (%d): only scaling by 1, 2, 4, or 8 is supported"
437
+ % scale
438
+ )
439
+ return MemoryAddress(index=self, scale=scale)
440
+
441
+
442
+ eax = GeneralPurposeRegister32(0)
443
+ ecx = GeneralPurposeRegister32(1)
444
+ edx = GeneralPurposeRegister32(2)
445
+ ebx = GeneralPurposeRegister32(3)
446
+ esp = GeneralPurposeRegister32(4)
447
+ ebp = GeneralPurposeRegister32(5)
448
+ esi = GeneralPurposeRegister32(6)
449
+ edi = GeneralPurposeRegister32(7)
450
+ r8d = GeneralPurposeRegister32(8)
451
+ r9d = GeneralPurposeRegister32(9)
452
+ r10d = GeneralPurposeRegister32(10)
453
+ r11d = GeneralPurposeRegister32(11)
454
+ r12d = GeneralPurposeRegister32(12)
455
+ r13d = GeneralPurposeRegister32(13)
456
+ r14d = GeneralPurposeRegister32(14)
457
+ r15d = GeneralPurposeRegister32(15)
458
+
459
+
460
+ class GeneralPurposeRegister16(GeneralPurposeRegister):
461
+ """16-bit general-purpose register"""
462
+
463
+ size = 2
464
+
465
+ _physical_id_map = {
466
+ 0x0: "ax",
467
+ 0x1: "cx",
468
+ 0x2: "dx",
469
+ 0x3: "bx",
470
+ 0x4: "sp",
471
+ 0x5: "bp",
472
+ 0x6: "si",
473
+ 0x7: "di",
474
+ 0x8: "r8w",
475
+ 0x9: "r9w",
476
+ 0xA: "r10w",
477
+ 0xB: "r11w",
478
+ 0xC: "r12w",
479
+ 0xD: "r13w",
480
+ 0xE: "r14w",
481
+ 0xF: "r15w",
482
+ }
483
+ _mask = 0x3
484
+
485
+ def __init__(self, physical_id=None, virtual_id=None):
486
+ if virtual_id is None and physical_id is None:
487
+ from nervapy.common.function import active_function
488
+
489
+ super(GeneralPurposeRegister16, self).__init__(
490
+ GeneralPurposeRegister16._mask,
491
+ active_function._allocate_general_purpose_register_id(),
492
+ )
493
+ else:
494
+ super(GeneralPurposeRegister16, self).__init__(
495
+ GeneralPurposeRegister16._mask, virtual_id, physical_id
496
+ )
497
+
498
+ def __str__(self):
499
+ if self.is_virtual:
500
+ return "gp16-vreg<%d>" % self.virtual_id
501
+ else:
502
+ return GeneralPurposeRegister16._physical_id_map[self.physical_id]
503
+
504
+
505
+ ax = GeneralPurposeRegister16(0)
506
+ cx = GeneralPurposeRegister16(1)
507
+ dx = GeneralPurposeRegister16(2)
508
+ bx = GeneralPurposeRegister16(3)
509
+ sp = GeneralPurposeRegister16(4)
510
+ bp = GeneralPurposeRegister16(5)
511
+ si = GeneralPurposeRegister16(6)
512
+ di = GeneralPurposeRegister16(7)
513
+ r8w = GeneralPurposeRegister16(8)
514
+ r9w = GeneralPurposeRegister16(9)
515
+ r10w = GeneralPurposeRegister16(10)
516
+ r11w = GeneralPurposeRegister16(11)
517
+ r12w = GeneralPurposeRegister16(12)
518
+ r13w = GeneralPurposeRegister16(13)
519
+ r14w = GeneralPurposeRegister16(14)
520
+ r15w = GeneralPurposeRegister16(15)
521
+
522
+
523
+ class GeneralPurposeRegister8(GeneralPurposeRegister):
524
+ """8-bit general-purpose register"""
525
+
526
+ size = 1
527
+
528
+ _physical_id_map = {
529
+ (0x0, 0x1): "al",
530
+ (0x1, 0x1): "cl",
531
+ (0x2, 0x1): "dl",
532
+ (0x3, 0x1): "bl",
533
+ (0x0, 0x2): "ah",
534
+ (0x1, 0x2): "ch",
535
+ (0x2, 0x2): "dh",
536
+ (0x3, 0x2): "bh",
537
+ (0x4, 0x1): "spl",
538
+ (0x5, 0x1): "bpl",
539
+ (0x6, 0x1): "sil",
540
+ (0x7, 0x1): "dil",
541
+ (0x8, 0x1): "r8b",
542
+ (0x9, 0x1): "r9b",
543
+ (0xA, 0x1): "r10b",
544
+ (0xB, 0x1): "r11b",
545
+ (0xC, 0x1): "r12b",
546
+ (0xD, 0x1): "r13b",
547
+ (0xE, 0x1): "r14b",
548
+ (0xF, 0x1): "r15b",
549
+ }
550
+ _go_physical_id_map = {
551
+ (0x0, 0x1): "AX",
552
+ (0x1, 0x1): "CX",
553
+ (0x2, 0x1): "DX",
554
+ (0x3, 0x1): "BX",
555
+ (0x0, 0x2): "AH",
556
+ (0x1, 0x2): "CH",
557
+ (0x2, 0x2): "DH",
558
+ (0x3, 0x2): "BH",
559
+ (0x4, 0x1): "SP",
560
+ (0x5, 0x1): "BP",
561
+ (0x6, 0x1): "SI",
562
+ (0x7, 0x1): "DI",
563
+ (0x8, 0x1): "R8",
564
+ (0x9, 0x1): "R9",
565
+ (0xA, 0x1): "R10",
566
+ (0xB, 0x1): "R11",
567
+ (0xC, 0x1): "R12",
568
+ (0xD, 0x1): "R13",
569
+ (0xE, 0x1): "R14",
570
+ (0xF, 0x1): "R15",
571
+ }
572
+ _mask = 0x1
573
+ _high_mask = 0x2
574
+
575
+ def __init__(self, physical_id=None, virtual_id=None, is_high=False):
576
+ mask = (
577
+ GeneralPurposeRegister8._high_mask
578
+ if is_high
579
+ else GeneralPurposeRegister8._mask
580
+ )
581
+ if virtual_id is None and physical_id is None:
582
+ from nervapy.common.function import active_function
583
+
584
+ super(GeneralPurposeRegister8, self).__init__(
585
+ mask, active_function._allocate_general_purpose_register_id()
586
+ )
587
+ else:
588
+ super(GeneralPurposeRegister8, self).__init__(mask, virtual_id, physical_id)
589
+
590
+ def __str__(self):
591
+ if self.is_virtual:
592
+ return "gp8-vreg<%d>" % self.virtual_id
593
+ else:
594
+ return GeneralPurposeRegister8._physical_id_map[
595
+ (self.physical_id, self.mask)
596
+ ]
597
+
598
+ def format(self, assembly_format):
599
+ assert assembly_format in {
600
+ "peachpy",
601
+ "gas",
602
+ "nasm",
603
+ "go",
604
+ }, "Supported assembly formats are 'peachpy', 'gas', 'nasm', 'go'"
605
+
606
+ if assembly_format == "go":
607
+ assert (
608
+ not self.is_virtual
609
+ ), "Go assembler does not support virtual registers"
610
+ return GeneralPurposeRegister8._go_physical_id_map[
611
+ (self.physical_id, self.mask)
612
+ ]
613
+ else:
614
+ return super(GeneralPurposeRegister8, self).format(assembly_format)
615
+
616
+
617
+ al = GeneralPurposeRegister8(0)
618
+ cl = GeneralPurposeRegister8(1)
619
+ dl = GeneralPurposeRegister8(2)
620
+ bl = GeneralPurposeRegister8(3)
621
+ ah = GeneralPurposeRegister8(0, is_high=True)
622
+ ch = GeneralPurposeRegister8(1, is_high=True)
623
+ dh = GeneralPurposeRegister8(2, is_high=True)
624
+ bh = GeneralPurposeRegister8(3, is_high=True)
625
+ spl = GeneralPurposeRegister8(4)
626
+ bpl = GeneralPurposeRegister8(5)
627
+ sil = GeneralPurposeRegister8(6)
628
+ dil = GeneralPurposeRegister8(7)
629
+ r8b = GeneralPurposeRegister8(8)
630
+ r9b = GeneralPurposeRegister8(9)
631
+ r10b = GeneralPurposeRegister8(10)
632
+ r11b = GeneralPurposeRegister8(11)
633
+ r12b = GeneralPurposeRegister8(12)
634
+ r13b = GeneralPurposeRegister8(13)
635
+ r14b = GeneralPurposeRegister8(14)
636
+ r15b = GeneralPurposeRegister8(15)
637
+
638
+
639
+ class MMXRegister(Register):
640
+ """64-bit MMX technology register"""
641
+
642
+ size = 8
643
+
644
+ _physical_id_map = {n: "mm" + str(n) for n in range(8)}
645
+ _go_physical_id_map = {n: "M" + str(n) for n in range(8)}
646
+ _kind = 2
647
+ _mask = 0x10
648
+
649
+ def __init__(self, physical_id=None, virtual_id=None):
650
+ if virtual_id is None and physical_id is None:
651
+ from nervapy.common.function import active_function
652
+
653
+ super(MMXRegister, self).__init__(
654
+ MMXRegister._mask, active_function._allocate_mmx_register_id()
655
+ )
656
+ else:
657
+ super(MMXRegister, self).__init__(
658
+ MMXRegister._mask, virtual_id, physical_id
659
+ )
660
+
661
+ def __str__(self):
662
+ if self.is_virtual:
663
+ return "mm-vreg<%d>" % self.virtual_id
664
+ else:
665
+ return MMXRegister._physical_id_map[self.physical_id]
666
+
667
+ def format(self, assembly_format):
668
+ assert assembly_format in {
669
+ "peachpy",
670
+ "gas",
671
+ "nasm",
672
+ "go",
673
+ }, "Supported assembly formats are 'peachpy', 'gas', 'nasm', 'go'"
674
+
675
+ if assembly_format == "go":
676
+ assert (
677
+ not self.is_virtual
678
+ ), "Go assembler does not support virtual registers"
679
+ return MMXRegister._go_physical_id_map[self.physical_id]
680
+ elif assembly_format == "gas":
681
+ return "%" + str(self)
682
+ else:
683
+ return str(self)
684
+
685
+
686
+ mm0 = MMXRegister(0)
687
+ mm1 = MMXRegister(1)
688
+ mm2 = MMXRegister(2)
689
+ mm3 = MMXRegister(3)
690
+ mm4 = MMXRegister(4)
691
+ mm5 = MMXRegister(5)
692
+ mm6 = MMXRegister(6)
693
+ mm7 = MMXRegister(7)
694
+
695
+
696
+ class XMMRegister(Register):
697
+ """128-bit xmm (SSE) register"""
698
+
699
+ size = 16
700
+
701
+ _physical_id_map = {n: "xmm" + str(n) for n in range(32)}
702
+ _go_physical_id_map = {n: "X" + str(n) for n in range(16)}
703
+ _kind = 3
704
+ _mask = 0x100
705
+
706
+ def __init__(self, physical_id=None, virtual_id=None):
707
+ if virtual_id is None and physical_id is None:
708
+ from nervapy.common.function import active_function
709
+
710
+ super(XMMRegister, self).__init__(
711
+ XMMRegister._mask, active_function._allocate_xmm_register_id()
712
+ )
713
+ else:
714
+ super(XMMRegister, self).__init__(
715
+ XMMRegister._mask, virtual_id, physical_id
716
+ )
717
+
718
+ def __str__(self):
719
+ if self.is_virtual:
720
+ return "xmm-vreg<%d>" % self.virtual_id
721
+ else:
722
+ return XMMRegister._physical_id_map[self.physical_id]
723
+
724
+ def format(self, assembly_format):
725
+ assert assembly_format in {
726
+ "peachpy",
727
+ "gas",
728
+ "nasm",
729
+ "go",
730
+ }, "Supported assembly formats are 'peachpy', 'gas', 'nasm', 'go'"
731
+
732
+ if assembly_format == "go":
733
+ assert (
734
+ not self.is_virtual
735
+ ), "Go assembler does not support virtual registers"
736
+ return XMMRegister._go_physical_id_map[self.physical_id]
737
+ elif assembly_format == "gas":
738
+ return "%" + str(self)
739
+ else:
740
+ return str(self)
741
+
742
+ @property
743
+ def as_xmm(self):
744
+ return XMMRegister(self.physical_id, self.virtual_id)
745
+
746
+ @property
747
+ def as_ymm(self):
748
+ return YMMRegister(self.physical_id, self.virtual_id)
749
+
750
+ @property
751
+ def as_zmm(self):
752
+ return ZMMRegister(self.physical_id, self.virtual_id)
753
+
754
+ @property
755
+ def code(self):
756
+ """Returns 5-bit encoding of the register"""
757
+ assert (
758
+ self.physical_id is not None
759
+ ), "The method returns encoding detail for a physical register"
760
+ return self.physical_id
761
+
762
+ @property
763
+ def kcode(self):
764
+ """Returns encoding of mask register"""
765
+ return 0
766
+
767
+ @property
768
+ def zcode(self):
769
+ """Returns encoding of zeroing/merging flag of mask register"""
770
+ return 0
771
+
772
+ def __call__(self, mask):
773
+ if not isinstance(mask, (KRegister, RegisterMask)):
774
+ raise SyntaxError(
775
+ "xmm(mask) syntax requires mask to be a KRegister or KRegister.z"
776
+ )
777
+ return MaskedRegister(self, mask)
778
+
779
+ def __mul__(self, scale):
780
+ from nervapy.util import is_int
781
+ from nervapy.x86_64.operand import MemoryAddress
782
+
783
+ if not is_int(scale):
784
+ raise TypeError("Register can be scaled only by an integer number")
785
+ if int(scale) not in {1, 2, 4, 8}:
786
+ raise ValueError(
787
+ "Invalid scale value (%d): only scaling by 1, 2, 4, or 8 is supported"
788
+ % scale
789
+ )
790
+ return MemoryAddress(index=self, scale=scale)
791
+
792
+
793
+ xmm0 = XMMRegister(0)
794
+ xmm1 = XMMRegister(1)
795
+ xmm2 = XMMRegister(2)
796
+ xmm3 = XMMRegister(3)
797
+ xmm4 = XMMRegister(4)
798
+ xmm5 = XMMRegister(5)
799
+ xmm6 = XMMRegister(6)
800
+ xmm7 = XMMRegister(7)
801
+ xmm8 = XMMRegister(8)
802
+ xmm9 = XMMRegister(9)
803
+ xmm10 = XMMRegister(10)
804
+ xmm11 = XMMRegister(11)
805
+ xmm12 = XMMRegister(12)
806
+ xmm13 = XMMRegister(13)
807
+ xmm14 = XMMRegister(14)
808
+ xmm15 = XMMRegister(15)
809
+ xmm16 = XMMRegister(16)
810
+ xmm17 = XMMRegister(17)
811
+ xmm18 = XMMRegister(18)
812
+ xmm19 = XMMRegister(19)
813
+ xmm20 = XMMRegister(20)
814
+ xmm21 = XMMRegister(21)
815
+ xmm22 = XMMRegister(22)
816
+ xmm23 = XMMRegister(23)
817
+ xmm24 = XMMRegister(24)
818
+ xmm25 = XMMRegister(25)
819
+ xmm26 = XMMRegister(26)
820
+ xmm27 = XMMRegister(27)
821
+ xmm28 = XMMRegister(28)
822
+ xmm29 = XMMRegister(29)
823
+ xmm30 = XMMRegister(30)
824
+ xmm31 = XMMRegister(31)
825
+
826
+
827
+ class YMMRegister(Register):
828
+ """256-bit ymm (AVX) register"""
829
+
830
+ size = 32
831
+
832
+ _physical_id_map = {n: "ymm" + str(n) for n in range(32)}
833
+ _kind = 3
834
+ _mask = 0x300
835
+
836
+ def __init__(self, physical_id=None, virtual_id=None):
837
+ if virtual_id is None and physical_id is None:
838
+ from nervapy.common.function import active_function
839
+
840
+ super(YMMRegister, self).__init__(
841
+ YMMRegister._mask, active_function._allocate_xmm_register_id()
842
+ )
843
+ else:
844
+ super(YMMRegister, self).__init__(
845
+ YMMRegister._mask, virtual_id, physical_id
846
+ )
847
+
848
+ def __str__(self):
849
+ if self.is_virtual:
850
+ return "ymm-vreg<%d>" % self.virtual_id
851
+ else:
852
+ return YMMRegister._physical_id_map[self.physical_id]
853
+
854
+ def format(self, assembly_format):
855
+ assert assembly_format in {
856
+ "peachpy",
857
+ "gas",
858
+ "nasm",
859
+ "go",
860
+ }, "Supported assembly formats are 'peachpy', 'gas', 'nasm', 'go'"
861
+
862
+ if assembly_format == "go":
863
+ assert (
864
+ not self.is_virtual
865
+ ), "Go assembler does not support virtual registers"
866
+ return XMMRegister._go_physical_id_map[self.physical_id]
867
+ elif assembly_format == "gas":
868
+ return "%" + str(self)
869
+ else:
870
+ return str(self)
871
+
872
+ @property
873
+ def as_xmm(self):
874
+ return XMMRegister(self.physical_id, self.virtual_id)
875
+
876
+ @property
877
+ def as_ymm(self):
878
+ return YMMRegister(self.physical_id, self.virtual_id)
879
+
880
+ @property
881
+ def as_zmm(self):
882
+ return ZMMRegister(self.physical_id, self.virtual_id)
883
+
884
+ @property
885
+ def code(self):
886
+ """Returns 5-bit encoding of the register"""
887
+ assert (
888
+ self.physical_id is not None
889
+ ), "The method returns encoding detail for a physical register"
890
+ return self.physical_id
891
+
892
+ @property
893
+ def kcode(self):
894
+ """Returns encoding of mask register"""
895
+ return 0
896
+
897
+ @property
898
+ def zcode(self):
899
+ """Returns encoding of zeroing/merging flag of mask register"""
900
+ return 0
901
+
902
+ def __call__(self, mask):
903
+ if not isinstance(mask, (KRegister, RegisterMask)):
904
+ raise SyntaxError(
905
+ "ymm(mask) syntax requires mask to be a KRegister or KRegister.z"
906
+ )
907
+ return MaskedRegister(self, mask)
908
+
909
+ def __mul__(self, scale):
910
+ from nervapy.util import is_int
911
+ from nervapy.x86_64.operand import MemoryAddress
912
+
913
+ if not is_int(scale):
914
+ raise TypeError("Register can be scaled only by an integer number")
915
+ if int(scale) not in {1, 2, 4, 8}:
916
+ raise ValueError(
917
+ "Invalid scale value (%d): only scaling by 1, 2, 4, or 8 is supported"
918
+ % scale
919
+ )
920
+ return MemoryAddress(index=self, scale=scale)
921
+
922
+
923
+ ymm0 = YMMRegister(0)
924
+ ymm1 = YMMRegister(1)
925
+ ymm2 = YMMRegister(2)
926
+ ymm3 = YMMRegister(3)
927
+ ymm4 = YMMRegister(4)
928
+ ymm5 = YMMRegister(5)
929
+ ymm6 = YMMRegister(6)
930
+ ymm7 = YMMRegister(7)
931
+ ymm8 = YMMRegister(8)
932
+ ymm9 = YMMRegister(9)
933
+ ymm10 = YMMRegister(10)
934
+ ymm11 = YMMRegister(11)
935
+ ymm12 = YMMRegister(12)
936
+ ymm13 = YMMRegister(13)
937
+ ymm14 = YMMRegister(14)
938
+ ymm15 = YMMRegister(15)
939
+ ymm16 = YMMRegister(16)
940
+ ymm17 = YMMRegister(17)
941
+ ymm18 = YMMRegister(18)
942
+ ymm19 = YMMRegister(19)
943
+ ymm20 = YMMRegister(20)
944
+ ymm21 = YMMRegister(21)
945
+ ymm22 = YMMRegister(22)
946
+ ymm23 = YMMRegister(23)
947
+ ymm24 = YMMRegister(24)
948
+ ymm25 = YMMRegister(25)
949
+ ymm26 = YMMRegister(26)
950
+ ymm27 = YMMRegister(27)
951
+ ymm28 = YMMRegister(28)
952
+ ymm29 = YMMRegister(29)
953
+ ymm30 = YMMRegister(30)
954
+ ymm31 = YMMRegister(31)
955
+
956
+
957
+ class ZMMRegister(Register):
958
+ """512-bit zmm (AVX-512) register"""
959
+
960
+ size = 64
961
+
962
+ _physical_id_map = {n: "zmm" + str(n) for n in range(32)}
963
+ _kind = 3
964
+ _mask = 0x700
965
+
966
+ def __init__(self, physical_id=None, virtual_id=None):
967
+ if virtual_id is None and physical_id is None:
968
+ from nervapy.common.function import active_function
969
+
970
+ super(ZMMRegister, self).__init__(
971
+ ZMMRegister._mask, active_function._allocate_xmm_register_id()
972
+ )
973
+ else:
974
+ super(ZMMRegister, self).__init__(
975
+ ZMMRegister._mask, virtual_id, physical_id
976
+ )
977
+
978
+ def __str__(self):
979
+ if self.is_virtual:
980
+ return "zmm-vreg<%d>" % self.virtual_id
981
+ else:
982
+ return ZMMRegister._physical_id_map[self.physical_id]
983
+
984
+ @property
985
+ def as_xmm(self):
986
+ return XMMRegister(self.physical_id, self.virtual_id)
987
+
988
+ @property
989
+ def as_ymm(self):
990
+ return YMMRegister(self.physical_id, self.virtual_id)
991
+
992
+ @property
993
+ def as_zmm(self):
994
+ return ZMMRegister(self.physical_id, self.virtual_id)
995
+
996
+ @property
997
+ def code(self):
998
+ """Returns 5-bit encoding of the register"""
999
+ assert (
1000
+ self.physical_id is not None
1001
+ ), "The method returns encoding detail for a physical register"
1002
+ return self.physical_id
1003
+
1004
+ @property
1005
+ def kcode(self):
1006
+ """Returns encoding of mask register"""
1007
+ return 0
1008
+
1009
+ @property
1010
+ def zcode(self):
1011
+ """Returns encoding of zeroing/merging flag of mask register"""
1012
+ return 0
1013
+
1014
+ def __call__(self, mask):
1015
+ if not isinstance(mask, (KRegister, RegisterMask)):
1016
+ raise SyntaxError(
1017
+ "zmm(mask) syntax requires mask to be a KRegister or KRegister.z"
1018
+ )
1019
+ return MaskedRegister(self, mask)
1020
+
1021
+ def __mul__(self, scale):
1022
+ from nervapy.util import is_int
1023
+ from nervapy.x86_64.operand import MemoryAddress
1024
+
1025
+ if not is_int(scale):
1026
+ raise TypeError("Register can be scaled only by an integer number")
1027
+ if int(scale) not in {1, 2, 4, 8}:
1028
+ raise ValueError(
1029
+ "Invalid scale value (%d): only scaling by 1, 2, 4, or 8 is supported"
1030
+ % scale
1031
+ )
1032
+ return MemoryAddress(index=self, scale=scale)
1033
+
1034
+
1035
+ zmm0 = ZMMRegister(0)
1036
+ zmm1 = ZMMRegister(1)
1037
+ zmm2 = ZMMRegister(2)
1038
+ zmm3 = ZMMRegister(3)
1039
+ zmm4 = ZMMRegister(4)
1040
+ zmm5 = ZMMRegister(5)
1041
+ zmm6 = ZMMRegister(6)
1042
+ zmm7 = ZMMRegister(7)
1043
+ zmm8 = ZMMRegister(8)
1044
+ zmm9 = ZMMRegister(9)
1045
+ zmm10 = ZMMRegister(10)
1046
+ zmm11 = ZMMRegister(11)
1047
+ zmm12 = ZMMRegister(12)
1048
+ zmm13 = ZMMRegister(13)
1049
+ zmm14 = ZMMRegister(14)
1050
+ zmm15 = ZMMRegister(15)
1051
+ zmm16 = ZMMRegister(16)
1052
+ zmm17 = ZMMRegister(17)
1053
+ zmm18 = ZMMRegister(18)
1054
+ zmm19 = ZMMRegister(19)
1055
+ zmm20 = ZMMRegister(20)
1056
+ zmm21 = ZMMRegister(21)
1057
+ zmm22 = ZMMRegister(22)
1058
+ zmm23 = ZMMRegister(23)
1059
+ zmm24 = ZMMRegister(24)
1060
+ zmm25 = ZMMRegister(25)
1061
+ zmm26 = ZMMRegister(26)
1062
+ zmm27 = ZMMRegister(27)
1063
+ zmm28 = ZMMRegister(28)
1064
+ zmm29 = ZMMRegister(29)
1065
+ zmm30 = ZMMRegister(30)
1066
+ zmm31 = ZMMRegister(31)
1067
+
1068
+
1069
+ class KRegister(Register):
1070
+ """AVX-512 mask register"""
1071
+
1072
+ size = 8
1073
+
1074
+ _physical_id_map = {n: "k" + str(n) for n in range(8)}
1075
+ _kind = 4
1076
+ _mask = 0x40
1077
+
1078
+ def __init__(self, physical_id=None, virtual_id=None):
1079
+ if virtual_id is None and physical_id is None:
1080
+ from nervapy.common.function import active_function
1081
+
1082
+ super(KRegister, self).__init__(
1083
+ KRegister._mask, active_function._allocate_mask_register_id()
1084
+ )
1085
+ else:
1086
+ super(KRegister, self).__init__(KRegister._mask, virtual_id, physical_id)
1087
+
1088
+ def __str__(self):
1089
+ if self.is_virtual:
1090
+ return "k-vreg<%d>" % self.virtual_id
1091
+ else:
1092
+ return KRegister._physical_id_map[self.physical_id]
1093
+
1094
+ @property
1095
+ def z(self):
1096
+ return RegisterMask(self, is_zeroing=True)
1097
+
1098
+ @property
1099
+ def kcode(self):
1100
+ """Returns the register encoding"""
1101
+ assert (
1102
+ self.physical_id is not None
1103
+ ), "The method returns encoding detail for a physical register"
1104
+ return self.physical_id
1105
+
1106
+ @property
1107
+ def zcode(self):
1108
+ """Returns encoding of the merge/zero flags"""
1109
+ return 0
1110
+
1111
+ def __call__(self, mask):
1112
+ if not isinstance(mask, KRegister):
1113
+ raise SyntaxError("k(mask) syntax requires mask to be a KRegister")
1114
+ return MaskedRegister(self, mask)
1115
+
1116
+
1117
+ class RegisterMask:
1118
+ def __init__(self, mask_register, is_zeroing=False):
1119
+ self.mask_register = mask_register
1120
+ self.is_zeroing = is_zeroing
1121
+
1122
+ @property
1123
+ def kcode(self):
1124
+ """Returns encoding of the mask register"""
1125
+ return self.mask_register.kcode
1126
+
1127
+ @property
1128
+ def zcode(self):
1129
+ """Returns encoding of the merge/zero flags"""
1130
+ return int(self.is_zeroing)
1131
+
1132
+
1133
+ k0 = KRegister(0)
1134
+ k1 = KRegister(1)
1135
+ k2 = KRegister(2)
1136
+ k3 = KRegister(3)
1137
+ k4 = KRegister(4)
1138
+ k5 = KRegister(5)
1139
+ k6 = KRegister(6)
1140
+ k7 = KRegister(7)
1141
+
1142
+
1143
+ class MaskedRegister:
1144
+ def __init__(self, register, mask):
1145
+ assert isinstance(register, (XMMRegister, YMMRegister, ZMMRegister, KRegister))
1146
+ assert isinstance(mask, (KRegister, RegisterMask))
1147
+ self.register = register
1148
+ if isinstance(mask, KRegister):
1149
+ self.mask = RegisterMask(mask)
1150
+ else:
1151
+ self.mask = mask
1152
+
1153
+ @property
1154
+ def code(self):
1155
+ """Returns the 5-bit register encoding"""
1156
+ return self.register.code
1157
+
1158
+ @property
1159
+ def lcode(self):
1160
+ """Returns the bits 0-2 of register encoding"""
1161
+ return self.register.lcode
1162
+
1163
+ @property
1164
+ def hcode(self):
1165
+ """Returns the bit 3 of register encoding"""
1166
+ return self.register.hcode
1167
+
1168
+ @property
1169
+ def ecode(self):
1170
+ """Returns the bit 4 of register encoding"""
1171
+ return self.register.ecode
1172
+
1173
+ @property
1174
+ def hlcode(self):
1175
+ """Returns the bits 0-3 of register encoding"""
1176
+ return self.register.hlcode
1177
+
1178
+ @property
1179
+ def ehcode(self):
1180
+ """Returns the bits 3-4 of register encoding"""
1181
+ return self.register.ehcode
1182
+
1183
+ @property
1184
+ def kcode(self):
1185
+ """Returns encoding of mask register"""
1186
+ return self.mask.kcode
1187
+
1188
+ @property
1189
+ def zcode(self):
1190
+ """Returns encoding of zeroing/merging flag of mask register"""
1191
+ return self.mask.zcode
1192
+
1193
+ def __mul__(self, scale):
1194
+ from nervapy.util import is_int
1195
+ from nervapy.x86_64.operand import MemoryAddress
1196
+
1197
+ if not is_int(scale):
1198
+ raise TypeError("Register can be scaled only by an integer number")
1199
+ if int(scale) not in {1, 2, 4, 8}:
1200
+ raise ValueError(
1201
+ "Invalid scale value (%d): only scaling by 1, 2, 4, or 8 is supported"
1202
+ % scale
1203
+ )
1204
+ return MemoryAddress(index=self, scale=scale)
1205
+
1206
+
1207
+ class RIPRegister:
1208
+ def __init__(self):
1209
+ pass
1210
+
1211
+ def __str__(self):
1212
+ return "rip"
1213
+
1214
+ def __add__(self, offset):
1215
+ from nervapy.x86_64.operand import RIPRelativeOffset
1216
+
1217
+ return RIPRelativeOffset(offset)
1218
+
1219
+ def __sub__(self, offset):
1220
+ from nervapy.x86_64.operand import RIPRelativeOffset
1221
+
1222
+ return RIPRelativeOffset(-offset)
1223
+
1224
+
1225
+ rip = RIPRegister()