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,519 @@
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
+ class QuasiInstruction(object):
6
+ def __init__(self, name, origin=None):
7
+ super(QuasiInstruction, self).__init__()
8
+ self.name = name
9
+ self.line_number = origin[1][2] if origin else None
10
+ self.source_file = origin[1][1] if origin else None
11
+ self.source_code = origin[1][4][0].strip() if origin else None
12
+
13
+
14
+ class Instruction(QuasiInstruction):
15
+ def __init__(self, name, operands, isa_extensions=None, origin=None):
16
+ import nervapy.x86_64.isa
17
+
18
+ super(Instruction, self).__init__(name, origin=origin)
19
+ self.operands = operands
20
+ self.isa_extensions = nervapy.x86_64.isa.Extensions(isa_extensions)
21
+ self.available_registers = set()
22
+ self.live_registers = set()
23
+
24
+ def __len__(self):
25
+ return self.size
26
+
27
+ def __str__(self):
28
+ return self.name + " " + ", ".join(map(str, self.operands))
29
+
30
+ def get_registers_list(self):
31
+ return [
32
+ register
33
+ for operand in self.operands
34
+ for register in operand.get_registers_list()
35
+ ]
36
+
37
+ def get_local_variable(self):
38
+ for operand in self.operands:
39
+ if isinstance(operand, Operand) and operand.is_local_variable():
40
+ return operand.variable
41
+
42
+ def get_constant(self):
43
+ for operand in self.operands:
44
+ if isinstance(operand, Operand) and operand.is_constant():
45
+ return operand.constant
46
+
47
+
48
+ class Operand(object):
49
+ RegisterType = 1
50
+ RegisterListType = 2
51
+ RegisterLanesType = 3
52
+ RegisterLanesListType = 4
53
+ ShiftedRegisterType = 5
54
+ AddressRegisterType = 6
55
+ ImmediateType = 7
56
+ MemoryType = 8
57
+ ConstantType = 9
58
+ VariableType = 10
59
+ LabelType = 11
60
+ NoneType = 12
61
+
62
+ def __init__(self, operand):
63
+ super(Operand, self).__init__()
64
+ import copy
65
+
66
+ from nervapy import Constant
67
+ from nervapy.arm.function import LocalVariable
68
+ from nervapy.arm.pseudo import ExternalFunction, Label
69
+ from nervapy.arm.registers import (DRegisterLanes,
70
+ GeneralPurposeRegister,
71
+ GeneralPurposeRegisterWriteback,
72
+ Register,
73
+ ShiftedGeneralPurposeRegister)
74
+ from nervapy.util import is_int
75
+
76
+ if isinstance(operand, GeneralPurposeRegisterWriteback):
77
+ self.type = Operand.AddressRegisterType
78
+ self.register = copy.deepcopy(operand.register)
79
+ elif isinstance(operand, Register):
80
+ self.type = Operand.RegisterType
81
+ self.register = copy.deepcopy(operand)
82
+ elif isinstance(operand, DRegisterLanes):
83
+ self.type = Operand.RegisterLanesType
84
+ self.lanes = copy.deepcopy(operand)
85
+ elif isinstance(operand, ShiftedGeneralPurposeRegister):
86
+ self.type = Operand.ShiftedRegisterType
87
+ self.register = copy.deepcopy(operand)
88
+ elif isinstance(operand, tuple):
89
+ if all(isinstance(element, Register) for element in operand):
90
+ if (
91
+ len(set((register.type, register.size) for register in operand))
92
+ == 1
93
+ ):
94
+ self.type = Operand.RegisterListType
95
+ self.register_list = copy.deepcopy(operand)
96
+ else:
97
+ raise TypeError(
98
+ "Register in the list {0} have different types".format(
99
+ ", ".join(operand)
100
+ )
101
+ )
102
+ elif all(isinstance(element, DRegisterLanes) for element in operand):
103
+ self.type = Operand.RegisterLanesListType
104
+ self.register_list = copy.deepcopy(operand)
105
+ else:
106
+ raise TypeError("Unknown tuple elements {0}".format(operand))
107
+ elif is_int(operand):
108
+ if -9223372036854775808 <= operand <= 18446744073709551615:
109
+ self.type = Operand.ImmediateType
110
+ self.immediate = operand
111
+ else:
112
+ raise ValueError(
113
+ "The immediate operand {0} is not a 64-bit value".format(operand)
114
+ )
115
+ elif isinstance(operand, list):
116
+ if len(operand) == 1 and (
117
+ isinstance(operand[0], GeneralPurposeRegister)
118
+ or isinstance(operand[0], GeneralPurposeRegisterWriteback)
119
+ ):
120
+ self.type = Operand.MemoryType
121
+ self.base = copy.deepcopy(operand[0])
122
+ self.offset = None
123
+ elif (
124
+ len(operand) == 2
125
+ and isinstance(operand[0], GeneralPurposeRegister)
126
+ and (
127
+ isinstance(operand[1], int)
128
+ or isinstance(operand[1], ShiftedGeneralPurposeRegister)
129
+ )
130
+ ):
131
+ self.type = Operand.MemoryType
132
+ self.base = copy.deepcopy(operand[0])
133
+ self.offset = operand[1]
134
+ else:
135
+ raise ValueError(
136
+ "Memory operand must be a list with only one or two elements"
137
+ )
138
+ elif isinstance(operand, Constant):
139
+ self.type = Operand.ConstantType
140
+ self.constant = operand
141
+ self.size = operand.size * operand.repeats
142
+ elif isinstance(operand, LocalVariable):
143
+ self.type = Operand.VariableType
144
+ self.variable = operand
145
+ self.size = operand.size * 8
146
+ elif isinstance(operand, ExternalFunction):
147
+ # Treat external functions as labels
148
+ self.type = Operand.LabelType
149
+ self.label = operand.name
150
+ elif isinstance(operand, str):
151
+ self.type = Operand.LabelType
152
+ self.label = operand
153
+ elif isinstance(operand, Label):
154
+ self.type = Operand.LabelType
155
+ self.label = operand.name
156
+ elif operand is None:
157
+ self.type = Operand.NoneType
158
+ else:
159
+ raise TypeError(
160
+ "The operand {0} is not a valid assembly instruction operand".format(
161
+ operand
162
+ )
163
+ )
164
+
165
+ def __str__(self):
166
+ if self.is_constant():
167
+ if self.constant.prefix is None:
168
+ return "[rel {0}]".format(self.constant.label)
169
+ else:
170
+ return "[rel {1}.{0}]".format(self.constant.label, self.constant.prefix)
171
+ elif self.is_local_variable():
172
+ return str(self.variable)
173
+ elif self.is_memory_address():
174
+ from nervapy.arm.registers import GeneralPurposeRegisterWriteback
175
+
176
+ if self.offset is None:
177
+ if isinstance(self.base, GeneralPurposeRegisterWriteback):
178
+ return "[" + str(self.base.register) + "]!"
179
+ else:
180
+ return "[" + str(self.base) + "]"
181
+ else:
182
+ if isinstance(self.base, GeneralPurposeRegisterWriteback):
183
+ return (
184
+ "[" + str(self.base.register) + ", #" + str(self.offset) + "]!"
185
+ )
186
+ else:
187
+ if isinstance(self.offset, int):
188
+ return "[" + str(self.base) + ", #" + str(self.offset) + "]"
189
+ else:
190
+ return "[" + str(self.base) + ", " + str(self.offset) + "]"
191
+ elif self.is_register() or self.is_shifted_general_purpose_register():
192
+ return str(self.register)
193
+ elif self.is_register_lanes():
194
+ return str(self.register)
195
+ elif self.is_address_register():
196
+ return str(self.register) + "!"
197
+ elif self.is_register_list() or self.is_register_lanes_list():
198
+ return "{" + ", ".join(map(str, self.register_list)) + "}"
199
+ elif self.is_label():
200
+ return self.label
201
+ elif self.is_immediate():
202
+ return "#" + str(self.immediate)
203
+ elif self.is_none():
204
+ return ""
205
+ else:
206
+ raise TypeError("Unsupported operand type")
207
+
208
+ def __eq__(self, other):
209
+ if isinstance(other, Operand) and self.type == other.type:
210
+ if self.is_immediate():
211
+ return self.immediate == other.immediate
212
+ elif self.is_register():
213
+ return self.register == other.register
214
+ elif self.is_memory_address():
215
+ return self.base == other.base and self.offset == other.offset
216
+ elif self.is_label():
217
+ return self.label == other.label
218
+ else:
219
+ return False
220
+ else:
221
+ return False
222
+
223
+ def __ne__(self, other):
224
+ return not self == other
225
+
226
+ def is_none(self):
227
+ return self.type == Operand.NoneType
228
+
229
+ def is_immediate(self):
230
+ return self.type == Operand.ImmediateType
231
+
232
+ def is_immediate5(self):
233
+ return self.is_immediate() and 0 <= self.immediate <= 31
234
+
235
+ def is_modified_immediate12(self):
236
+ def rotate32(x, n):
237
+ return ((x >> n) | (x << (32 - n))) & 0xFFFFFFFF
238
+
239
+ if self.type == Operand.ImmediateType:
240
+ if -2147483648 <= self.immediate <= 4294967295:
241
+ dword = self.immediate & 0xFFFFFFFF
242
+
243
+ # Check byte replication patterns (ARM ARM A5.3.2)
244
+ # Pattern 0b00: 0x000000XY
245
+ if dword <= 0xFF:
246
+ return True
247
+
248
+ # Pattern 0b01: 0x00XY00XY
249
+ if (dword & 0xFF00FF00) == 0 and ((dword >> 16) & 0xFF) == (dword & 0xFF):
250
+ return True
251
+
252
+ # Pattern 0b10: 0xXY00XY00
253
+ if (dword & 0x00FF00FF) == 0 and ((dword >> 24) & 0xFF) == ((dword >> 8) & 0xFF):
254
+ return True
255
+
256
+ # Pattern 0b11: 0xXYXYXYXY
257
+ byte_val = dword & 0xFF
258
+ if dword == (byte_val << 24) | (byte_val << 16) | (byte_val << 8) | byte_val:
259
+ return True
260
+
261
+ # Rotation patterns (original check)
262
+ ndword = (~self.immediate) & 0xFFFFFFFF
263
+ return any(
264
+ [
265
+ (rotate32(dword, n) & 0xFFFFFF00) == 0x00000000
266
+ or (rotate32(ndword, n) & 0xFFFFFF00) == 0x00000000
267
+ for n in range(0, 32, 2)
268
+ ]
269
+ )
270
+ else:
271
+ return False
272
+ else:
273
+ return False
274
+
275
+ def is_neon_modified_immediate8(self):
276
+ return self.type == Operand.ImmediateType and -128 <= self.immediate <= 255
277
+
278
+ def is_neon_modified_immediate16(self):
279
+ if self.type == Operand.ImmediateType and -32768 <= self.immediate <= 65535:
280
+ hword = self.immediate & 0xFFFF
281
+ return (hword & 0xFF00) == 0 or (hword & 0x00FF) == 0
282
+ else:
283
+ return False
284
+
285
+ def is_neon_modified_immediate32(self):
286
+ if (
287
+ self.type == Operand.ImmediateType
288
+ and -2147483648 <= self.immediate <= 4294967295
289
+ ):
290
+ word = self.immediate & 0xFFFFFFFF
291
+ return (
292
+ (word & 0x00FFFFFF) == 0x00000000
293
+ or (word & 0xFF00FFFF) == 0x00000000
294
+ or (word & 0xFFFF00FF) == 0x00000000
295
+ or (word & 0xFFFFFF00) == 0x00000000
296
+ or (word & 0xFF00FFFF) == 0x0000FFFF
297
+ or (word & 0xFFFF00FF) == 0x000000FF
298
+ )
299
+ else:
300
+ return False
301
+
302
+ def is_neon_modified_immediate64(self):
303
+ if (
304
+ self.type == Operand.ImmediateType
305
+ and -2147483648 <= self.immediate <= 4294967295
306
+ ):
307
+ dword = self.immediate & 0xFFFFFFFFFFFFFFFF
308
+ byte = dword & 0xFF
309
+ return all([(dword >> n) & 0xFF == byte for n in range(8, 64, 8)])
310
+ else:
311
+ return False
312
+
313
+ def is_preindexed_memory_address(self):
314
+ from nervapy.arm.registers import GeneralPurposeRegisterWriteback
315
+
316
+ return (
317
+ self.type == Operand.MemoryType
318
+ and self.offset is not None
319
+ and isinstance(self.base, GeneralPurposeRegisterWriteback)
320
+ )
321
+
322
+ def is_memory_address(self, offset_bits=None, allow_writeback=True):
323
+ from nervapy.arm.registers import (GeneralPurposeRegisterWriteback,
324
+ ShiftedGeneralPurposeRegister)
325
+
326
+ if self.type == Operand.MemoryType:
327
+ if not allow_writeback and isinstance(
328
+ self.base, GeneralPurposeRegisterWriteback
329
+ ):
330
+ return False
331
+ else:
332
+ if self.offset is None or offset_bits is None:
333
+ return True
334
+ elif isinstance(self.offset, ShiftedGeneralPurposeRegister):
335
+ return True
336
+ else:
337
+ bound = (1 << offset_bits) - 1
338
+ return -bound <= self.offset <= bound
339
+ else:
340
+ return False
341
+
342
+ def is_writeback_memory_address(self):
343
+ from nervapy.arm.registers import GeneralPurposeRegisterWriteback
344
+
345
+ return self.type == Operand.MemoryType and isinstance(
346
+ self.base, GeneralPurposeRegisterWriteback
347
+ )
348
+
349
+ def is_memory_address_offset8_mod4(self):
350
+ return self.type == Operand.MemoryType and (
351
+ self.offset is None or -1020 <= self.offset <= 1020 and self.offset % 4 == 0
352
+ )
353
+
354
+ def is_offset8(self):
355
+ return self.type == Operand.ImmediateType and -255 <= self.immediate <= 255
356
+
357
+ def is_offset12(self):
358
+ return self.type == Operand.ImmediateType and -4095 <= self.immediate <= 4095
359
+
360
+ def is_label(self):
361
+ return self.type == Operand.LabelType
362
+
363
+ def is_constant(self):
364
+ return self.type == Operand.ConstantType
365
+
366
+ def is_local_variable(self):
367
+ return self.type == Operand.VariableType
368
+
369
+ def is_register(self):
370
+ return self.type == Operand.RegisterType
371
+
372
+ def is_register_lanes(self):
373
+ return self.type == Operand.RegisterLanesType
374
+
375
+ def is_register_list(self):
376
+ return self.is_register() or self.type == Operand.RegisterListType
377
+
378
+ def is_register_lanes_list(self):
379
+ return self.type == Operand.RegisterLanesListType
380
+
381
+ def is_general_purpose_register(self):
382
+ from nervapy.arm.registers import GeneralPurposeRegister
383
+
384
+ return self.type == Operand.RegisterType and isinstance(
385
+ self.register, GeneralPurposeRegister
386
+ )
387
+
388
+ def is_shifted_general_purpose_register(self):
389
+ from nervapy.arm.registers import ShiftedGeneralPurposeRegister
390
+
391
+ return (
392
+ self.is_general_purpose_register()
393
+ or self.type == Operand.ShiftedRegisterType
394
+ and isinstance(self.register, ShiftedGeneralPurposeRegister)
395
+ )
396
+
397
+ def is_general_purpose_register_list(self):
398
+ from nervapy.arm.registers import GeneralPurposeRegister
399
+
400
+ return (
401
+ self.is_general_purpose_register()
402
+ or self.type == Operand.RegisterListType
403
+ and isinstance(self.register_list[0], GeneralPurposeRegister)
404
+ )
405
+
406
+ def is_address_register(self):
407
+ return (
408
+ self.is_general_purpose_register()
409
+ or self.type == Operand.AddressRegisterType
410
+ )
411
+
412
+ def is_wmmx_register(self):
413
+ from nervapy.arm.registers import WMMXRegister
414
+
415
+ return self.type == Operand.RegisterType and isinstance(
416
+ self.register, WMMXRegister
417
+ )
418
+
419
+ def is_s_register(self):
420
+ from nervapy.arm.registers import SRegister
421
+
422
+ return self.type == Operand.RegisterType and isinstance(
423
+ self.register, SRegister
424
+ )
425
+
426
+ def is_s_register_list(self):
427
+ from nervapy.arm.registers import SRegister
428
+
429
+ return (
430
+ self.is_s_register()
431
+ or self.type == Operand.RegisterListType
432
+ and isinstance(self.register_list[0], SRegister)
433
+ )
434
+
435
+ def is_d_register(self):
436
+ from nervapy.arm.registers import DRegister
437
+
438
+ return self.type == Operand.RegisterType and isinstance(
439
+ self.register, DRegister
440
+ )
441
+
442
+ def is_d_register_list(self):
443
+ from nervapy.arm.registers import DRegister
444
+
445
+ return (
446
+ self.is_d_register()
447
+ or self.type == Operand.RegisterListType
448
+ and isinstance(self.register_list[0], DRegister)
449
+ )
450
+
451
+ def is_q_register(self):
452
+ from nervapy.arm.registers import QRegister
453
+
454
+ return self.type == Operand.RegisterType and isinstance(
455
+ self.register, QRegister
456
+ )
457
+
458
+ def is_vldst1_register_list(self):
459
+ from nervapy.arm.registers import DRegister
460
+
461
+ return (
462
+ self.is_d_register()
463
+ or self.type == Operand.RegisterListType
464
+ and isinstance(self.register_list[0], DRegister)
465
+ and len(self.register_list) <= 4
466
+ )
467
+
468
+ def is_vldst1_register_lanes_list(self):
469
+ from nervapy.arm.registers import DRegisterLanes
470
+
471
+ return (
472
+ self.type == Operand.RegisterLanesType
473
+ and isinstance(self.register, DRegisterLanes)
474
+ or self.type == Operand.RegisterLanesListType
475
+ and all(
476
+ isinstance(register, DRegisterLanes) for register in self.register_list
477
+ )
478
+ )
479
+
480
+ def is_general_purpose_memory_address(self):
481
+ return self.type == Operand.MemoryType and -4095 <= self.offset <= 4095
482
+
483
+ def get_registers_list(self):
484
+ from nervapy.arm.registers import (GeneralPurposeRegisterWriteback,
485
+ ShiftedGeneralPurposeRegister, sp)
486
+
487
+ if self.is_address_register() or self.is_register() or self.is_register_lanes():
488
+ return [self.register]
489
+ elif self.is_shifted_general_purpose_register():
490
+ return [self.register.register]
491
+ elif self.is_constant():
492
+ return list()
493
+ elif self.is_local_variable():
494
+ return [sp]
495
+ elif self.is_register_list():
496
+ return list(self.register_list)
497
+ elif self.is_register_lanes_list():
498
+ return [register_lanes.register for register_lanes in self.register_list]
499
+ elif self.is_memory_address():
500
+ if isinstance(self.base, GeneralPurposeRegisterWriteback):
501
+ return [self.base.register]
502
+ else:
503
+ if isinstance(self.offset, ShiftedGeneralPurposeRegister):
504
+ return [self.base, self.offset.register]
505
+ else:
506
+ return [self.base]
507
+ else:
508
+ return list()
509
+
510
+ def get_writeback_registers_list(self):
511
+ if self.is_memory_address():
512
+ from nervapy.arm.registers import GeneralPurposeRegisterWriteback
513
+
514
+ if isinstance(self.base, GeneralPurposeRegisterWriteback):
515
+ return [self.base.register]
516
+ else:
517
+ return [self.base]
518
+ else:
519
+ return list()