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
|
@@ -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()
|