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
nervapy/arm.py ADDED
@@ -0,0 +1,13 @@
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
+ import inspect
5
+ import string
6
+ import time
7
+
8
+ import nervapy.c
9
+ import nervapy.codegen
10
+ from nervapy import Constant, ConstantBucket, RegisterAllocationError
11
+
12
+ active_function = None
13
+ active_stream = None
nervapy/c/__init__.py ADDED
@@ -0,0 +1 @@
1
+ __author__ = "marat"
nervapy/c/types.py ADDED
@@ -0,0 +1,436 @@
1
+ class Type:
2
+ def __init__(
3
+ self,
4
+ base,
5
+ size=None,
6
+ is_const=False,
7
+ is_floating_point=False,
8
+ is_signed_integer=False,
9
+ is_unsigned_integer=False,
10
+ is_pointer_integer=False,
11
+ is_size_integer=False,
12
+ is_vector=False,
13
+ is_mask=False,
14
+ is_char=False,
15
+ is_wchar=False,
16
+ is_bool=False,
17
+ is_short=False,
18
+ is_int=False,
19
+ is_long=False,
20
+ is_longlong=False,
21
+ header=None,
22
+ ):
23
+ self.size = size
24
+ self.is_const = is_const
25
+ self.is_floating_point = is_floating_point
26
+ self.is_signed_integer = is_signed_integer
27
+ self.is_unsigned_integer = is_unsigned_integer
28
+ self.is_pointer_integer = is_pointer_integer
29
+ self.is_size_integer = is_size_integer
30
+ self.is_vector = is_vector
31
+ self.is_mask = is_mask
32
+ self.is_short = is_short
33
+ self.is_char = is_char
34
+ self.is_wchar = is_wchar
35
+ self.is_bool = is_bool
36
+ self.is_int = is_int
37
+ self.is_long = is_long
38
+ self.is_longlong = is_longlong
39
+ self.header = header
40
+ if base is None or isinstance(base, Type):
41
+ self.base = base
42
+ self.name = None
43
+ self.is_pointer = True
44
+ elif isinstance(base, str):
45
+ self.base = None
46
+ self.name = base
47
+ self.is_pointer = False
48
+ else:
49
+ raise TypeError("%s must be either a type name or a type" % base)
50
+
51
+ def __str__(self):
52
+ if self.is_pointer:
53
+ if self.base is None:
54
+ text = "void*"
55
+ else:
56
+ text = str(self.base) + "*"
57
+ if self.is_const:
58
+ text += " const"
59
+ else:
60
+ text = self.name
61
+ if self.is_const:
62
+ text = "const " + text
63
+ return text
64
+
65
+ def __hash__(self):
66
+ if self.is_pointer:
67
+ h = hash(self.base)
68
+ return (h >> 5) | ((h & 0x07FFFFFF) << 27)
69
+ else:
70
+ h = 0
71
+ if self.is_fixed_size:
72
+ h = hash(self.size)
73
+ if self.is_floating_point:
74
+ h ^= 0x00000003
75
+ if self.is_signed_integer:
76
+ h ^= 0x0000000C
77
+ if self.is_unsigned_integer:
78
+ h ^= 0x00000030
79
+ if self.is_pointer_integer:
80
+ h ^= 0x000000C0
81
+ if self.is_size_integer:
82
+ h ^= 0x00000300
83
+ if self.is_vector:
84
+ h ^= 0x00000C00
85
+ h ^= hash(self.name)
86
+ if self.is_mask:
87
+ h ^= 0x00003000
88
+ if self.is_short:
89
+ h ^= 0x0000C000
90
+ if self.is_char:
91
+ h ^= 0x00030000
92
+ if self.is_wchar:
93
+ h ^= 0x000C0000
94
+ if self.is_bool:
95
+ h ^= 0x00300000
96
+ if self.is_int:
97
+ h ^= 0x00C00000
98
+ if self.is_long:
99
+ h ^= 0x03000000
100
+ if self.is_longlong:
101
+ h ^= 0x0C000000
102
+ return h
103
+
104
+ def __eq__(self, other):
105
+ if not isinstance(other, Type):
106
+ return False
107
+ elif self.is_pointer:
108
+ return other.is_pointer and self.base == other.base
109
+ else:
110
+ if self.name == other.name:
111
+ return True
112
+ else:
113
+ if self.is_vector and other.is_vector:
114
+ return self.name == other.name
115
+ else:
116
+ # If both types have size, check it. If any doesn't have type, ignore size altogether.
117
+ # This is important because the size of ABI-specific types (size_t, etc) is updated after binding
118
+ # to ABI and it is important to ensure that e.g. size_t == size_t after ABI binding too
119
+ if (
120
+ self.size is not None
121
+ and other.size is not None
122
+ and self.size != other.size
123
+ ):
124
+ return False
125
+ else:
126
+ return (
127
+ self.is_floating_point == other.is_floating_point
128
+ and self.is_signed_integer == other.is_signed_integer
129
+ and self.is_unsigned_integer == other.is_unsigned_integer
130
+ and self.is_pointer_integer == other.is_pointer_integer
131
+ and self.is_size_integer == other.is_size_integer
132
+ and self.is_vector == other.is_vector
133
+ and self.is_mask == other.is_mask
134
+ and self.is_short == other.is_short
135
+ and self.is_char == other.is_char
136
+ and self.is_wchar == other.is_wchar
137
+ and self.is_bool == other.is_bool
138
+ and self.is_int == other.is_int
139
+ and self.is_long == other.is_long
140
+ and self.is_longlong == other.is_longlong
141
+ )
142
+
143
+ def __ne__(self, other):
144
+ return not self == other
145
+
146
+ def get_size(self, abi):
147
+ if self.size is None:
148
+ if self.is_pointer or self.is_pointer_integer:
149
+ return abi.pointer_size
150
+ elif self.is_size_integer:
151
+ return abi.index_size
152
+ elif self.is_short:
153
+ return abi.short_size
154
+ elif self.is_int:
155
+ return abi.int_size
156
+ elif self.is_long:
157
+ return abi.long_size
158
+ elif self.is_longlong:
159
+ return abi.longlong_size
160
+ elif self.is_wchar:
161
+ return abi.wchar_size
162
+ elif self.is_bool:
163
+ return abi.bool_size
164
+ else:
165
+ assert False
166
+ else:
167
+ return self.size
168
+
169
+ @property
170
+ def is_fixed_size(self):
171
+ return not (
172
+ self.is_pointer
173
+ or self.is_size_integer
174
+ or self.is_wchar
175
+ or self.is_bool
176
+ or self.is_short
177
+ or self.is_int
178
+ or self.is_long
179
+ or self.is_longlong
180
+ )
181
+
182
+ @property
183
+ def is_integer(self):
184
+ return self.is_unsigned_integer or self.is_signed_integer
185
+
186
+ @property
187
+ def is_codeunit(self):
188
+ return self.is_char or self.is_wchar
189
+
190
+ @property
191
+ def primitive_type(self):
192
+ t = self
193
+ while t.is_pointer:
194
+ t = t.base
195
+ return t
196
+
197
+ @property
198
+ def as_ctypes_type(self):
199
+ import ctypes
200
+
201
+ if self.is_pointer:
202
+ if self.base is None:
203
+ return ctypes.c_void_p
204
+ else:
205
+ return ctypes.POINTER(self.base.as_ctypes_type)
206
+ else:
207
+ types_map = {
208
+ uint8_t: ctypes.c_uint8,
209
+ uint16_t: ctypes.c_uint16,
210
+ uint32_t: ctypes.c_uint32,
211
+ uint64_t: ctypes.c_uint64,
212
+ int8_t: ctypes.c_int8,
213
+ int16_t: ctypes.c_int16,
214
+ int32_t: ctypes.c_int32,
215
+ int64_t: ctypes.c_int64,
216
+ size_t: ctypes.c_size_t,
217
+ # Not exactly the same, but seems to match on all supported platforms
218
+ ptrdiff_t: ctypes.c_ssize_t,
219
+ char: ctypes.c_char,
220
+ signed_char: ctypes.c_byte,
221
+ unsigned_char: ctypes.c_ubyte,
222
+ signed_short: ctypes.c_short,
223
+ unsigned_short: ctypes.c_ushort,
224
+ signed_int: ctypes.c_int,
225
+ unsigned_int: ctypes.c_uint,
226
+ signed_long: ctypes.c_long,
227
+ unsigned_long: ctypes.c_ulong,
228
+ signed_long_long: ctypes.c_longlong,
229
+ unsigned_long_long: ctypes.c_ulonglong,
230
+ float_: ctypes.c_float,
231
+ double_: ctypes.c_double,
232
+ }
233
+ ctype = types_map.get(self)
234
+ if ctype is None:
235
+ raise ValueError("Type %s has no analog in ctypes module" % str(self))
236
+ return ctype
237
+
238
+
239
+ # Fixed-width C types
240
+ uint8_t = Type("uint8_t", size=1, is_unsigned_integer=True, header="stdint.h")
241
+ uint16_t = Type("uint16_t", size=2, is_unsigned_integer=True, header="stdint.h")
242
+ uint32_t = Type("uint32_t", size=4, is_unsigned_integer=True, header="stdint.h")
243
+ uint64_t = Type("uint64_t", size=8, is_unsigned_integer=True, header="stdint.h")
244
+ uintptr_t = Type(
245
+ "uintptr_t", is_unsigned_integer=True, is_pointer_integer=True, header="stdint.h"
246
+ )
247
+ int8_t = Type("int8_t", size=1, is_signed_integer=True, header="stdint.h")
248
+ int16_t = Type("int16_t", size=2, is_signed_integer=True, header="stdint.h")
249
+ int32_t = Type("int32_t", size=4, is_signed_integer=True, header="stdint.h")
250
+ int64_t = Type("int64_t", size=8, is_signed_integer=True, header="stdint.h")
251
+ intptr_t = Type(
252
+ "intptr_t", is_signed_integer=True, is_pointer_integer=True, header="stdint.h"
253
+ )
254
+ size_t = Type(
255
+ "size_t", is_unsigned_integer=True, is_size_integer=True, header="stddef.h"
256
+ )
257
+ ptrdiff_t = Type(
258
+ "ptrdiff_t", is_signed_integer=True, is_size_integer=True, header="stddef.h"
259
+ )
260
+ Float16 = Type("_Float16", is_floating_point=True, size=2)
261
+ Float32 = Type("_Float32", is_floating_point=True, size=4)
262
+ Float64 = Type("_Float64", is_floating_point=True, size=8)
263
+
264
+ const_uint8_t = Type(
265
+ "uint8_t", size=1, is_const=True, is_unsigned_integer=True, header="stdint.h"
266
+ )
267
+ const_uint16_t = Type(
268
+ "uint16_t", size=2, is_const=True, is_unsigned_integer=True, header="stdint.h"
269
+ )
270
+ const_uint32_t = Type(
271
+ "uint32_t", size=4, is_const=True, is_unsigned_integer=True, header="stdint.h"
272
+ )
273
+ const_uint64_t = Type(
274
+ "uint64_t", size=8, is_const=True, is_unsigned_integer=True, header="stdint.h"
275
+ )
276
+ const_uintptr_t = Type(
277
+ "uintptr_t",
278
+ is_const=True,
279
+ is_unsigned_integer=True,
280
+ is_pointer_integer=True,
281
+ header="stdint.h",
282
+ )
283
+ const_int8_t = Type(
284
+ "int8_t", size=1, is_const=True, is_signed_integer=True, header="stdint.h"
285
+ )
286
+ const_int16_t = Type(
287
+ "int16_t", size=2, is_const=True, is_signed_integer=True, header="stdint.h"
288
+ )
289
+ const_int32_t = Type(
290
+ "int32_t", size=4, is_const=True, is_signed_integer=True, header="stdint.h"
291
+ )
292
+ const_int64_t = Type(
293
+ "int64_t", size=8, is_const=True, is_signed_integer=True, header="stdint.h"
294
+ )
295
+ const_intptr_t = Type(
296
+ "intptr_t",
297
+ is_const=True,
298
+ is_signed_integer=True,
299
+ is_pointer_integer=True,
300
+ header="stdint.h",
301
+ )
302
+ const_size_t = Type(
303
+ "size_t",
304
+ is_const=True,
305
+ is_unsigned_integer=True,
306
+ is_size_integer=True,
307
+ header="stddef.h",
308
+ )
309
+ const_ptrdiff_t = Type(
310
+ "ptrdiff_t",
311
+ is_const=True,
312
+ is_signed_integer=True,
313
+ is_size_integer=True,
314
+ header="stddef.h",
315
+ )
316
+ const_Float16 = Type("_Float16", is_const=True, is_floating_point=True, size=2)
317
+ const_Float32 = Type("_Float32", is_const=True, is_floating_point=True, size=4)
318
+ const_Float64 = Type("_Float64", is_const=True, is_floating_point=True, size=8)
319
+
320
+
321
+ # Yeppp! types
322
+ Yep8u = Type("Yep8u", size=1, is_unsigned_integer=True, header="yepTypes.h")
323
+ Yep16u = Type("Yep16u", size=2, is_unsigned_integer=True, header="yepTypes.h")
324
+ Yep32u = Type("Yep32u", size=4, is_unsigned_integer=True, header="yepTypes.h")
325
+ Yep64u = Type("Yep64u", size=8, is_unsigned_integer=True, header="yepTypes.h")
326
+ Yep8s = Type("Yep8s", size=1, is_signed_integer=True, header="yepTypes.h")
327
+ Yep16s = Type("Yep16s", size=2, is_signed_integer=True, header="yepTypes.h")
328
+ Yep32s = Type("Yep32s", size=4, is_signed_integer=True, header="yepTypes.h")
329
+ Yep64s = Type("Yep64s", size=8, is_signed_integer=True, header="yepTypes.h")
330
+ Yep16f = Type("Yep16f", size=2, is_floating_point=True, header="yepTypes.h")
331
+ Yep32f = Type("Yep32f", size=4, is_floating_point=True, header="yepTypes.h")
332
+ Yep64f = Type("Yep64f", size=8, is_floating_point=True, header="yepTypes.h")
333
+ YepSize = Type(
334
+ "YepSize", is_unsigned_integer=True, is_size_integer=True, header="yepTypes.h"
335
+ )
336
+
337
+ const_Yep8u = Type(
338
+ "Yep8u", size=1, is_const=True, is_unsigned_integer=True, header="yepTypes.h"
339
+ )
340
+ const_Yep16u = Type(
341
+ "Yep16u", size=2, is_const=True, is_unsigned_integer=True, header="yepTypes.h"
342
+ )
343
+ const_Yep32u = Type(
344
+ "Yep32u", size=4, is_const=True, is_unsigned_integer=True, header="yepTypes.h"
345
+ )
346
+ const_Yep64u = Type(
347
+ "Yep64u", size=8, is_const=True, is_unsigned_integer=True, header="yepTypes.h"
348
+ )
349
+ const_Yep8s = Type(
350
+ "Yep8s", size=1, is_const=True, is_signed_integer=True, header="yepTypes.h"
351
+ )
352
+ const_Yep16s = Type(
353
+ "Yep16s", size=2, is_const=True, is_signed_integer=True, header="yepTypes.h"
354
+ )
355
+ const_Yep32s = Type(
356
+ "Yep32s", size=4, is_const=True, is_signed_integer=True, header="yepTypes.h"
357
+ )
358
+ const_Yep64s = Type(
359
+ "Yep64s", size=8, is_const=True, is_signed_integer=True, header="yepTypes.h"
360
+ )
361
+ const_Yep16f = Type(
362
+ "Yep16f", size=2, is_const=True, is_floating_point=True, header="yepTypes.h"
363
+ )
364
+ const_Yep32f = Type(
365
+ "Yep32f", size=4, is_const=True, is_floating_point=True, header="yepTypes.h"
366
+ )
367
+ const_Yep64f = Type(
368
+ "Yep64f", size=8, is_const=True, is_floating_point=True, header="yepTypes.h"
369
+ )
370
+ const_YepSize = Type(
371
+ "YepSize",
372
+ is_const=True,
373
+ is_unsigned_integer=True,
374
+ is_size_integer=True,
375
+ header="yepTypes.h",
376
+ )
377
+
378
+
379
+ # Basic C types
380
+ char = Type("char", size=1, is_char=True)
381
+ wchar_t = Type("wchar_t", is_wchar=True)
382
+ signed_char = Type("signed char", size=1, is_signed_integer=True)
383
+ unsigned_char = Type("unsigned char", size=1, is_unsigned_integer=True)
384
+ signed_short = Type("short", is_signed_integer=True, is_short=True)
385
+ unsigned_short = Type("unsigned short", is_unsigned_integer=True, is_short=True)
386
+ signed_int = Type("int", is_signed_integer=True, is_int=True)
387
+ unsigned_int = Type("unsigned int", is_unsigned_integer=True, is_int=True)
388
+ signed_long = Type("long", is_signed_integer=True, is_long=True)
389
+ unsigned_long = Type("unsigned long", is_unsigned_integer=True, is_long=True)
390
+ signed_long_long = Type("long long", is_signed_integer=True, is_longlong=True)
391
+ unsigned_long_long = Type(
392
+ "unsigned long long", is_unsigned_integer=True, is_longlong=True
393
+ )
394
+ float_ = Type("float", is_floating_point=True, size=4)
395
+ double_ = Type("double", is_floating_point=True, size=8)
396
+
397
+ const_char = Type("char", size=1, is_const=True, is_char=True)
398
+ const_wchar_t = Type("wchar_t", is_const=True, is_wchar=True)
399
+ const_signed_char = Type("signed char", size=1, is_const=True, is_signed_integer=True)
400
+ const_unsigned_char = Type(
401
+ "unsigned char", size=1, is_const=True, is_unsigned_integer=True
402
+ )
403
+ const_signed_short = Type("short", is_const=True, is_signed_integer=True, is_short=True)
404
+ const_unsigned_short = Type(
405
+ "unsigned short", is_const=True, is_unsigned_integer=True, is_short=True
406
+ )
407
+ const_signed_int = Type("int", is_const=True, is_signed_integer=True, is_int=True)
408
+ const_unsigned_int = Type(
409
+ "unsigned int", is_const=True, is_unsigned_integer=True, is_int=True
410
+ )
411
+ const_signed_long = Type("long", is_const=True, is_signed_integer=True, is_long=True)
412
+ const_unsigned_long = Type(
413
+ "unsigned long", is_const=True, is_unsigned_integer=True, is_long=True
414
+ )
415
+ const_signed_long_long = Type(
416
+ "long long", is_const=True, is_signed_integer=True, is_longlong=True
417
+ )
418
+ const_unsigned_long_long = Type(
419
+ "unsigned long long", is_const=True, is_unsigned_integer=True, is_longlong=True
420
+ )
421
+ const_float_ = Type("float", is_const=True, is_floating_point=True, size=4)
422
+ const_double_ = Type("double", is_const=True, is_floating_point=True, size=8)
423
+
424
+
425
+ def ptr(t=None):
426
+ if t is None or isinstance(t, Type):
427
+ return Type(base=t)
428
+ else:
429
+ raise TypeError("%s must be a type, e.g. uint32_t, size_t, or Yep64f" % type)
430
+
431
+
432
+ def const_ptr(t=None):
433
+ if t is None or isinstance(t, Type):
434
+ return Type(base=t, is_const=True)
435
+ else:
436
+ raise TypeError("%s must be a type, e.g. uint32_t, size_t, or Yep64f" % type)
nervapy/codegen.py ADDED
@@ -0,0 +1,99 @@
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 CodeGenerator(object):
6
+ def __init__(self, use_tabs=True):
7
+ self.indentationLevel = 0
8
+ self.use_tabs = use_tabs
9
+ self.code = []
10
+
11
+ def indent(self):
12
+ self.indentationLevel += 1
13
+ return self
14
+
15
+ def dedent(self):
16
+ self.indentationLevel -= 1
17
+ return self
18
+
19
+ def add_line(self, string="", indent=None):
20
+ if indent == None:
21
+ indent = self.indentationLevel
22
+ elif indent < 0:
23
+ indent += self.indentationLevel
24
+ if string == "":
25
+ self.code.append(string)
26
+ else:
27
+ if self.use_tabs:
28
+ self.code.append("\t" * indent + string)
29
+ else:
30
+ self.code.append(" " * indent + string)
31
+ return self
32
+
33
+ def add_lines(self, lines, indent=None):
34
+ for line in lines:
35
+ self.add_line(line, indent)
36
+
37
+ def add_empty_lines(self, count):
38
+ for i in range(count):
39
+ self.add_line()
40
+ return self
41
+
42
+ def add_c_comment(self, lines, doxygen=False):
43
+ if isinstance(lines, str) and lines.find("\n") != -1:
44
+ lines = lines.split("\n")
45
+ if isinstance(lines, list) and len(lines) > 1:
46
+ if doxygen:
47
+ self.add_line("/**")
48
+ else:
49
+ self.add_line("/*")
50
+ for line in lines:
51
+ self.add_line(" * " + line)
52
+ self.add_line(" */")
53
+ else:
54
+ line = lines[0] if isinstance(lines, list) else str(lines)
55
+ if doxygen:
56
+ self.add_line("/** " + line + "*/")
57
+ else:
58
+ self.add_line("/* " + line + "*/")
59
+
60
+ def add_assembly_comment(self, lines, indent=None):
61
+ for line in lines:
62
+ self.add_line("; " + line, indent)
63
+
64
+ def add_fortran90_comment(self, lines, doxygen=False):
65
+ if isinstance(lines, str) and lines.find("\n") != -1:
66
+ lines = lines.split("\n")
67
+ elif isinstance(lines, str):
68
+ lines = [lines]
69
+ for index, line in enumerate(lines):
70
+ if doxygen:
71
+ if index == 0:
72
+ self.add_line("!> " + line)
73
+ else:
74
+ self.add_line("!! " + line)
75
+ else:
76
+ self.add_line("! " + line)
77
+
78
+ def add_csharp_comment(self, lines, doxygen=False):
79
+ if isinstance(lines, str) and lines.find("\n") != -1:
80
+ lines = lines.split("\n")
81
+ if isinstance(lines, list) and len(lines) > 1:
82
+ if not doxygen:
83
+ self.add_line("/*")
84
+ for line in lines:
85
+ if doxygen:
86
+ self.add_line("/// " + line)
87
+ else:
88
+ self.add_line(" * " + line)
89
+ if not doxygen:
90
+ self.add_line(" */")
91
+ else:
92
+ line = lines[0] if isinstance(lines, list) else str(lines)
93
+ if doxygen:
94
+ self.add_line("/// " + line)
95
+ else:
96
+ self.add_line("// " + line)
97
+
98
+ def get_code(self):
99
+ return "\n".join(self.code)
@@ -0,0 +1,4 @@
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
+ from nervapy.common.regalloc import RegisterAllocator
@@ -0,0 +1,5 @@
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
+ active_function = None
@@ -0,0 +1,121 @@
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
+ import six
5
+
6
+
7
+ class RegisterAllocator:
8
+ def __init__(self):
9
+ # Map from virtual register id to internal id of conflicting registers (both virtual and physical)
10
+ self.conflicting_registers = dict()
11
+ # Map from virtual register id to physical register id
12
+ self.register_allocations = dict()
13
+ # Map from virtual register id to a list of available physical ids for the allocation
14
+ self.allocation_options = dict()
15
+
16
+ def add_conflicts(self, virtual_id, conflict_internal_ids):
17
+ self.conflicting_registers.setdefault(virtual_id, set())
18
+ self.conflicting_registers[virtual_id].update(conflict_internal_ids)
19
+ for conflict_internal_id in conflict_internal_ids:
20
+ if conflict_internal_id < 0:
21
+ conflict_virtual_id = -conflict_internal_id
22
+ self.conflicting_registers.setdefault(conflict_virtual_id, set())
23
+ self.conflicting_registers[conflict_virtual_id].add(-virtual_id)
24
+
25
+ def set_allocation_options(self, abi, register_kind):
26
+ physical_ids = (
27
+ [
28
+ reg.physical_id
29
+ for reg in abi.volatile_registers
30
+ if reg.kind == register_kind
31
+ ]
32
+ + [
33
+ reg.physical_id
34
+ for reg in abi.argument_registers
35
+ if reg.kind == register_kind
36
+ ][::-1]
37
+ + [
38
+ reg.physical_id
39
+ for reg in abi.callee_save_registers
40
+ if reg.kind == register_kind
41
+ ]
42
+ )
43
+ for reg in abi.restricted_registers:
44
+ if reg.kind == register_kind and reg.physical_id in physical_ids:
45
+ physical_ids.remove(reg.physical_id)
46
+ # TODO: account the pre-allocated registers in allocation options
47
+ for virtual_id, conflict_internal_ids in six.iteritems(
48
+ self.conflicting_registers
49
+ ):
50
+ self.allocation_options[virtual_id] = [
51
+ physical_id
52
+ for physical_id in physical_ids
53
+ if physical_id not in conflict_internal_ids
54
+ ]
55
+
56
+ def _bind_register(self, virtual_id, physical_id):
57
+ assert virtual_id > 0
58
+ assert physical_id >= 0
59
+ # TODO: handle situation before allocation options are initialized
60
+ for conflict_internal_id in self.conflicting_registers[virtual_id]:
61
+ if conflict_internal_id < 0:
62
+ conflict_virtual_id = -conflict_internal_id
63
+ try:
64
+ self.allocation_options[conflict_virtual_id].remove(physical_id)
65
+ except ValueError:
66
+ pass
67
+ self.allocation_options[virtual_id] = [physical_id]
68
+ self.register_allocations[virtual_id] = physical_id
69
+
70
+ def try_allocate_register(self, virtual_id, physical_id):
71
+ assert virtual_id > 0
72
+ if physical_id in self.allocation_options[virtual_id]:
73
+ self._bind_register(virtual_id, physical_id)
74
+ return True
75
+ else:
76
+ return False
77
+
78
+ def _allocation_alternatives(self, virtual_id, physical_id):
79
+ return sum(
80
+ 1 for reg in self.allocation_options[virtual_id] if reg != physical_id
81
+ )
82
+
83
+ def _min_conflict_allocation_alternatives(self, virtual_id, physical_id):
84
+ try:
85
+ return min(
86
+ self._allocation_alternatives(-conflict_internal_id, physical_id)
87
+ for conflict_internal_id in self.conflicting_registers[virtual_id]
88
+ if conflict_internal_id < 0
89
+ )
90
+ except ValueError:
91
+ return 0
92
+
93
+ def allocate_registers(self):
94
+ unallocated_registers = [
95
+ reg
96
+ for reg in six.iterkeys(self.allocation_options)
97
+ if reg not in self.register_allocations
98
+ ]
99
+
100
+ while unallocated_registers:
101
+ # Choose the virtual register for which there are the least allocation options
102
+ virtual_id = min(
103
+ unallocated_registers, key=lambda reg: len(self.allocation_options[reg])
104
+ )
105
+ if not self.allocation_options[virtual_id]:
106
+ raise Exception(
107
+ "No physical registers for virtual register %d" % virtual_id
108
+ )
109
+ if self.conflicting_registers[virtual_id]:
110
+ # Choose the physical register for which there are most alternatives
111
+ physical_id = max(
112
+ self.allocation_options[virtual_id],
113
+ key=lambda reg: self._min_conflict_allocation_alternatives(
114
+ virtual_id, reg
115
+ ),
116
+ )
117
+ else:
118
+ # Choose the first available physical register
119
+ physical_id = self.allocation_options[virtual_id].pop()
120
+ self._bind_register(virtual_id, physical_id)
121
+ unallocated_registers.remove(virtual_id)