PyNerva 0.0.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nervapy/__init__.py +50 -0
- nervapy/abi.py +91 -0
- nervapy/arm/__init__.py +124 -0
- nervapy/arm/__main__.py +0 -0
- nervapy/arm/abi.py +138 -0
- nervapy/arm/formats.py +49 -0
- nervapy/arm/function.py +2465 -0
- nervapy/arm/generic.py +10796 -0
- nervapy/arm/instructions.py +519 -0
- nervapy/arm/isa.py +409 -0
- nervapy/arm/literal_pool.py +331 -0
- nervapy/arm/microarchitecture.py +211 -0
- nervapy/arm/pseudo.py +652 -0
- nervapy/arm/registers.py +1458 -0
- nervapy/arm/vfpneon.py +4092 -0
- nervapy/arm.py +13 -0
- nervapy/c/__init__.py +1 -0
- nervapy/c/types.py +436 -0
- nervapy/codegen.py +99 -0
- nervapy/common/__init__.py +4 -0
- nervapy/common/function.py +5 -0
- nervapy/common/regalloc.py +121 -0
- nervapy/constant_data.py +282 -0
- nervapy/encoder.py +246 -0
- nervapy/formats/__init__.py +2 -0
- nervapy/formats/elf/__init__.py +4 -0
- nervapy/formats/elf/file.py +178 -0
- nervapy/formats/elf/image.py +106 -0
- nervapy/formats/elf/section.py +422 -0
- nervapy/formats/elf/symbol.py +281 -0
- nervapy/formats/macho/__init__.py +2 -0
- nervapy/formats/macho/file.py +123 -0
- nervapy/formats/macho/image.py +143 -0
- nervapy/formats/macho/section.py +322 -0
- nervapy/formats/macho/symbol.py +158 -0
- nervapy/formats/mscoff/__init__.py +8 -0
- nervapy/formats/mscoff/image.py +132 -0
- nervapy/formats/mscoff/section.py +181 -0
- nervapy/formats/mscoff/symbol.py +148 -0
- nervapy/function.py +136 -0
- nervapy/literal.py +731 -0
- nervapy/loader.py +188 -0
- nervapy/name.py +159 -0
- nervapy/parse.py +52 -0
- nervapy/stream.py +58 -0
- nervapy/util.py +126 -0
- nervapy/writer.py +518 -0
- nervapy/x86_64/__init__.py +324 -0
- nervapy/x86_64/__main__.py +407 -0
- nervapy/x86_64/abi.py +517 -0
- nervapy/x86_64/amd.py +6464 -0
- nervapy/x86_64/avx.py +102029 -0
- nervapy/x86_64/crypto.py +1533 -0
- nervapy/x86_64/encoding.py +424 -0
- nervapy/x86_64/fma.py +19138 -0
- nervapy/x86_64/function.py +2707 -0
- nervapy/x86_64/generic.py +23384 -0
- nervapy/x86_64/instructions.py +500 -0
- nervapy/x86_64/isa.py +476 -0
- nervapy/x86_64/lower.py +126 -0
- nervapy/x86_64/mask.py +2593 -0
- nervapy/x86_64/meta.py +143 -0
- nervapy/x86_64/mmxsse.py +17265 -0
- nervapy/x86_64/nacl.py +327 -0
- nervapy/x86_64/operand.py +1204 -0
- nervapy/x86_64/options.py +21 -0
- nervapy/x86_64/pseudo.py +686 -0
- nervapy/x86_64/registers.py +1225 -0
- nervapy/x86_64/types.py +17 -0
- nervapy/x86_64/uarch.py +580 -0
- pynerva-0.0.7.dist-info/METADATA +310 -0
- pynerva-0.0.7.dist-info/RECORD +74 -0
- pynerva-0.0.7.dist-info/WHEEL +4 -0
- pynerva-0.0.7.dist-info/licenses/LICENSE.rst +15 -0
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,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)
|