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,331 @@
1
+ """
2
+ Literal Pool Support for ARM Assembly
3
+
4
+ This module implements literal pool functionality for the LDR =label pseudo-instruction.
5
+ It manages constant literals that can be loaded into registers using PC-relative addressing.
6
+
7
+ Usage:
8
+ from nervapy.arm.literal_pool import Literal
9
+ from nervapy.arm.generic import LDR
10
+
11
+ with Function("my_func", ...) as func:
12
+ # Load constant using literal pool
13
+ LDR(r0, literal=Literal(0x11111111))
14
+
15
+ # Load with custom label
16
+ LDR(r0, literal=Literal(0x11111111, label="MY_CONSTANT"))
17
+
18
+ # Or load from ConstantData label
19
+ magic = ConstantData.uint32(0x11111111, name="MAGIC_NUMBER")
20
+ LDR(r0, literal=magic)
21
+ """
22
+
23
+ import inspect
24
+
25
+ import nervapy.arm.function
26
+ import nervapy.stream
27
+ from nervapy.arm.generic import Operand
28
+ from nervapy.arm.instructions import Instruction
29
+
30
+
31
+ class Literal:
32
+ """
33
+ Wrapper class for literal values with optional custom labels.
34
+
35
+ Use this class to specify a literal value for LDR instruction with an optional label.
36
+ This is useful when you want to control the label name in the generated assembly.
37
+
38
+ Examples:
39
+ # Simple literal (auto-generated label)
40
+ LDR(r0, literal=Literal(0x11111111))
41
+ # Generates: literal_123456789: .word 0x11111111
42
+
43
+ # Literal with custom label
44
+ LDR(r0, literal=Literal(0x11111111, label="MY_CONSTANT"))
45
+ # Generates: MY_CONSTANT: .word 0x11111111
46
+
47
+ # 64-bit literal
48
+ LDR(r0, literal=Literal(0x123456789ABCDEF0))
49
+
50
+ # Direct integer also works (backward compatibility)
51
+ LDR(r1, literal=0x22222222)
52
+ """
53
+
54
+ def __init__(self, value, label=None):
55
+ """
56
+ Args:
57
+ value: The literal value (int or float)
58
+ label: Optional custom label name for the literal
59
+ """
60
+ self.value = value
61
+ self.label = label
62
+
63
+ def get_value(self):
64
+ """Return the literal value"""
65
+ return self.value
66
+
67
+ def get_label(self):
68
+ """Return the custom label, if any"""
69
+ return self.label
70
+
71
+
72
+ class LiteralPoolEntry:
73
+ """Represents a single entry in the literal pool"""
74
+
75
+ def __init__(self, value, label=None, size=32):
76
+ """
77
+ Args:
78
+ value: The literal value (int, float, or ConstantData)
79
+ label: Optional label name for the literal
80
+ size: Size in bits (8, 16, 32, or 64)
81
+ """
82
+ self.value = value
83
+ self.label = label or f"literal_{id(self)}"
84
+ self.size = size
85
+ self._is_constant_data = False
86
+
87
+ # Check if value is a ConstantData object
88
+ try:
89
+ from nervapy.constant_data import ConstantData
90
+ if isinstance(value, ConstantData):
91
+ self._is_constant_data = True
92
+ self.label = value.get_label()
93
+ except ImportError:
94
+ pass
95
+
96
+ def is_constant_data(self):
97
+ """Check if this entry references ConstantData"""
98
+ return self._is_constant_data
99
+
100
+ def get_label(self):
101
+ """Get the label for this literal"""
102
+ return self.label
103
+
104
+ def get_value(self):
105
+ """Get the numeric value"""
106
+ if self._is_constant_data:
107
+ # For ConstantData, return the first value
108
+ if hasattr(self.value, 'data') and len(self.value.data) > 0:
109
+ return self.value.data[0]
110
+ return 0
111
+ return self.value
112
+
113
+ def generate_assembly(self, format='gas'):
114
+ """Generate assembly for this literal entry"""
115
+ if self._is_constant_data:
116
+ # ConstantData generates its own .data section
117
+ return ""
118
+
119
+ if format == 'gas':
120
+ if self.size == 64:
121
+ # 64-bit value
122
+ return f"{self.label}:\n\t.word 0x{self.value & 0xFFFFFFFF:08X}, 0x{(self.value >> 32) & 0xFFFFFFFF:08X}"
123
+ elif self.size == 32:
124
+ return f"{self.label}:\n\t.word 0x{self.value:08X}"
125
+ elif self.size == 16:
126
+ return f"{self.label}:\n\t.hword 0x{self.value:04X}"
127
+ elif self.size == 8:
128
+ return f"{self.label}:\n\t.byte 0x{self.value:02X}"
129
+ elif format == 'armcc':
130
+ if self.size == 64:
131
+ return f"{self.label} DCD 0x{self.value & 0xFFFFFFFF:08X}, 0x{(self.value >> 32) & 0xFFFFFFFF:08X}"
132
+ elif self.size == 32:
133
+ return f"{self.label} DCD 0x{self.value:08X}"
134
+ elif self.size == 16:
135
+ return f"{self.label} DCW 0x{self.value:04X}"
136
+ elif self.size == 8:
137
+ return f"{self.label} DCB 0x{self.value:02X}"
138
+
139
+ return ""
140
+
141
+
142
+ class LiteralPool:
143
+ """Manages a pool of literals for a function"""
144
+
145
+ def __init__(self):
146
+ self.entries = []
147
+ self._value_map = {} # Map values to entries for deduplication
148
+
149
+ def add_literal(self, value, label=None, size=32):
150
+ """
151
+ Add a literal to the pool
152
+
153
+ Args:
154
+ value: The literal value
155
+ label: Optional label name
156
+ size: Size in bits
157
+
158
+ Returns:
159
+ LiteralPoolEntry: The pool entry
160
+ """
161
+ # Check if we already have this value (deduplication)
162
+ if label is None and not self._is_constant_data(value):
163
+ key = (value, size)
164
+ if key in self._value_map:
165
+ return self._value_map[key]
166
+
167
+ entry = LiteralPoolEntry(value, label, size)
168
+ self.entries.append(entry)
169
+
170
+ if label is None and not entry.is_constant_data():
171
+ self._value_map[(value, size)] = entry
172
+
173
+ return entry
174
+
175
+ def _is_constant_data(self, value):
176
+ """Check if value is ConstantData"""
177
+ try:
178
+ from nervapy.constant_data import ConstantData
179
+ return isinstance(value, ConstantData)
180
+ except ImportError:
181
+ return False
182
+
183
+ def generate_assembly(self, format='gas'):
184
+ """Generate assembly for the entire literal pool"""
185
+ if not self.entries:
186
+ return ""
187
+
188
+ lines = []
189
+
190
+ if format == 'gas':
191
+ lines.append("\t.align 4")
192
+ for entry in self.entries:
193
+ if not entry.is_constant_data():
194
+ asm = entry.generate_assembly(format='gas')
195
+ if asm:
196
+ lines.append(asm)
197
+ elif format == 'armcc':
198
+ lines.append(" ALIGN 4")
199
+ for entry in self.entries:
200
+ if not entry.is_constant_data():
201
+ asm = entry.generate_assembly(format='armcc')
202
+ if asm:
203
+ lines.append(asm)
204
+
205
+ return "\n".join(lines) if lines else ""
206
+
207
+
208
+ class LiteralLoadInstruction(Instruction):
209
+ """
210
+ LDR pseudo-instruction for loading literals: LDR rd, =value
211
+
212
+ This generates either:
213
+ 1. A literal pool entry + PC-relative LDR
214
+ 2. An optimized MOV/MVN if the value is encodable
215
+ 3. A reference to a ConstantData label
216
+ """
217
+
218
+ def __init__(self, register, value, label=None, origin=None):
219
+ """
220
+ Args:
221
+ register: Destination register
222
+ value: Literal value (int, float, ConstantData, or Literal object)
223
+ label: Optional custom label name for the literal
224
+ """
225
+ self.literal_register = Operand(register)
226
+
227
+ # Extract value and label from Literal object if provided
228
+ actual_value = value
229
+ actual_label = label
230
+
231
+ if isinstance(value, Literal):
232
+ actual_value = value.get_value()
233
+ if label is None: # Only use Literal's label if not explicitly provided
234
+ actual_label = value.get_label()
235
+
236
+ self.literal_value = actual_value
237
+ self.pool_entry = None
238
+
239
+ # Check if it's a ConstantData object
240
+ self._is_constant_data = False
241
+ try:
242
+ from nervapy.constant_data import ConstantData
243
+ if isinstance(actual_value, ConstantData):
244
+ self._is_constant_data = True
245
+ except ImportError:
246
+ pass
247
+
248
+ # Add to literal pool if function is active
249
+ if nervapy.arm.function.active_function is not None:
250
+ if not hasattr(nervapy.arm.function.active_function, 'literal_pool'):
251
+ nervapy.arm.function.active_function.literal_pool = LiteralPool()
252
+
253
+ size = 32
254
+ if isinstance(actual_value, int):
255
+ if actual_value > 0xFFFFFFFF:
256
+ size = 64
257
+
258
+ self.pool_entry = nervapy.arm.function.active_function.literal_pool.add_literal(
259
+ actual_value, label=actual_label, size=size
260
+ )
261
+
262
+ # Create instruction representation
263
+ super(LiteralLoadInstruction, self).__init__(
264
+ "LDR", [self.literal_register], origin=origin
265
+ )
266
+
267
+ def __str__(self):
268
+ """Generate the assembly string"""
269
+ if self.pool_entry:
270
+ label = self.pool_entry.get_label()
271
+ return f"LDR {self.literal_register}, ={label}"
272
+ else:
273
+ # Fallback if no pool entry
274
+ return f"LDR {self.literal_register}, =0x{self.literal_value:X}"
275
+
276
+ def get_output_registers_list(self):
277
+ """Return list of registers modified by this instruction"""
278
+ return [self.literal_register.get_registers_list()[0]]
279
+
280
+ def get_input_registers_list(self):
281
+ """Return list of registers used by this instruction"""
282
+ return []
283
+
284
+
285
+ def LDR_LITERAL(register, value, label=None):
286
+ """
287
+ Load a literal value into a register using the literal pool.
288
+
289
+ This implements the ARM pseudo-instruction: LDR rd, =value
290
+
291
+ Args:
292
+ register: Destination general-purpose register
293
+ value: Literal value to load (int, float, or ConstantData)
294
+ label: Optional custom label name for the literal
295
+
296
+ Returns:
297
+ LiteralLoadInstruction: The instruction object
298
+
299
+ Examples:
300
+ # Load a 32-bit constant
301
+ LDR_LITERAL(r0, 0x11111111)
302
+
303
+ # Load with custom label
304
+ LDR_LITERAL(r0, 0x11111111, label="my_constant")
305
+
306
+ # Load from ConstantData
307
+ magic = ConstantData.uint32(0x12345678, name="MAGIC")
308
+ LDR_LITERAL(r1, magic)
309
+
310
+ # Load a large value
311
+ LDR_LITERAL(r2, 0xDEADBEEF)
312
+
313
+ Note:
314
+ The assembler will automatically:
315
+ - Create a literal pool entry
316
+ - Generate PC-relative LDR instruction
317
+ - Place the literal in .text or .rodata section
318
+
319
+ For ConstantData objects, it references the .data section label.
320
+ """
321
+ origin = (
322
+ inspect.stack() if nervapy.arm.function.active_function.collect_origin else None
323
+ )
324
+ instruction = LiteralLoadInstruction(register, value, label=label, origin=origin)
325
+ if nervapy.stream.active_stream is not None:
326
+ nervapy.stream.active_stream.add_instruction(instruction)
327
+ return instruction
328
+
329
+
330
+ # Alias for convenience
331
+ LDRL = LDR_LITERAL
@@ -0,0 +1,211 @@
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 typing import Optional
5
+
6
+ from nervapy.arm.isa import Extension, Extensions
7
+
8
+
9
+ class Microarchitecture:
10
+ def __init__(self, name, extensions):
11
+ self.name = name
12
+ self.extensions = Extensions(
13
+ *[
14
+ prerequisite
15
+ for extension in extensions
16
+ for prerequisite in extension.prerequisites
17
+ ]
18
+ )
19
+
20
+ def is_supported(self, extension):
21
+ return extension in self.extensions
22
+
23
+ @property
24
+ def id(self):
25
+ return self.name.replace(" ", "")
26
+
27
+ def __add__(self, extension):
28
+ return Microarchitecture(self.name, self.extensions + extension)
29
+
30
+ def __sub__(self, extension):
31
+ return Microarchitecture(self.name, self.extensions - extension)
32
+
33
+ def __str__(self):
34
+ return self.name
35
+
36
+ Default: Optional["Microarchitecture"] = None
37
+ XScale: Optional["Microarchitecture"] = None
38
+ ARM9: Optional["Microarchitecture"] = None
39
+ ARM11: Optional["Microarchitecture"] = None
40
+ CortexA5: Optional["Microarchitecture"] = None
41
+ CortexA7: Optional["Microarchitecture"] = None
42
+ CortexA8: Optional["Microarchitecture"] = None
43
+ CortexA9: Optional["Microarchitecture"] = None
44
+ CortexA12: Optional["Microarchitecture"] = None
45
+ CortexA15: Optional["Microarchitecture"] = None
46
+ CortexM0: Optional["Microarchitecture"] = None
47
+ CortexM0Plus: Optional["Microarchitecture"] = None
48
+ CortexM1: Optional["Microarchitecture"] = None
49
+ CortexM3: Optional["Microarchitecture"] = None
50
+ CortexM4: Optional["Microarchitecture"] = None
51
+ CortexM7: Optional["Microarchitecture"] = None
52
+ CortexM23: Optional["Microarchitecture"] = None
53
+ CortexM33: Optional["Microarchitecture"] = None
54
+ CortexM35P: Optional["Microarchitecture"] = None
55
+ CortexM55: Optional["Microarchitecture"] = None
56
+ CortexM85: Optional["Microarchitecture"] = None
57
+ Scorpion: Optional["Microarchitecture"] = None
58
+ Krait: Optional["Microarchitecture"] = None
59
+ PJ4: Optional["Microarchitecture"] = None
60
+
61
+
62
+ Microarchitecture.Default = Microarchitecture("Default", Extension.All)
63
+ Microarchitecture.XScale = Microarchitecture(
64
+ "XScale", [Extension.V5E, Extension.Thumb, Extension.XScale, Extension.WMMX2]
65
+ )
66
+ Microarchitecture.ARM9 = Microarchitecture("ARM9", [Extension.V5E, Extension.Thumb])
67
+ Microarchitecture.ARM11 = Microarchitecture(
68
+ "ARM11", [Extension.V6K, Extension.Thumb, Extension.VFP2, Extension.VFPVectorMode]
69
+ )
70
+ Microarchitecture.CortexA5 = Microarchitecture(
71
+ "Cortex A5",
72
+ [
73
+ Extension.V7MP,
74
+ Extension.Thumb2,
75
+ Extension.VFP4,
76
+ Extension.VFPd32,
77
+ Extension.NEON2,
78
+ ],
79
+ )
80
+ Microarchitecture.CortexA7 = Microarchitecture(
81
+ "Cortex A7",
82
+ [
83
+ Extension.V7MP,
84
+ Extension.Thumb2,
85
+ Extension.Div,
86
+ Extension.VFP4,
87
+ Extension.VFPd32,
88
+ Extension.NEON2,
89
+ ],
90
+ )
91
+ Microarchitecture.CortexA8 = Microarchitecture(
92
+ "Cortex A8",
93
+ [Extension.V7, Extension.Thumb2, Extension.VFP3, Extension.VFPd32, Extension.NEON],
94
+ )
95
+ Microarchitecture.CortexA9 = Microarchitecture(
96
+ "Cortex A9", [Extension.V7MP, Extension.Thumb2, Extension.VFP3, Extension.VFPHP]
97
+ )
98
+ Microarchitecture.CortexA12 = Microarchitecture(
99
+ "Cortex A12",
100
+ [
101
+ Extension.V7MP,
102
+ Extension.Thumb2,
103
+ Extension.Div,
104
+ Extension.VFP4,
105
+ Extension.VFPd32,
106
+ Extension.NEON2,
107
+ ],
108
+ )
109
+ Microarchitecture.CortexA15 = Microarchitecture(
110
+ "Cortex A15",
111
+ [
112
+ Extension.V7MP,
113
+ Extension.Thumb2,
114
+ Extension.Div,
115
+ Extension.VFP4,
116
+ Extension.VFPd32,
117
+ Extension.NEON2,
118
+ ],
119
+ )
120
+ Microarchitecture.Scorpion = Microarchitecture(
121
+ "Scorpion",
122
+ [
123
+ Extension.V7MP,
124
+ Extension.Thumb2,
125
+ Extension.VFP3,
126
+ Extension.VFPd32,
127
+ Extension.VFPHP,
128
+ Extension.NEON,
129
+ Extension.NEONHP,
130
+ ],
131
+ )
132
+ Microarchitecture.Krait = Microarchitecture(
133
+ "Krait",
134
+ [
135
+ Extension.V7MP,
136
+ Extension.Thumb2,
137
+ Extension.Div,
138
+ Extension.VFP4,
139
+ Extension.VFPd32,
140
+ Extension.NEON2,
141
+ ],
142
+ )
143
+ Microarchitecture.PJ4 = Microarchitecture(
144
+ "PJ4", [Extension.V7, Extension.Thumb2, Extension.VFP3, Extension.WMMX2]
145
+ )
146
+
147
+ # Cortex-M series microarchitectures
148
+ Microarchitecture.CortexM0 = Microarchitecture(
149
+ "Cortex M0", [Extension.V6, Extension.Thumb2]
150
+ )
151
+ Microarchitecture.CortexM0Plus = Microarchitecture(
152
+ "Cortex M0+", [Extension.V6, Extension.Thumb2]
153
+ )
154
+ Microarchitecture.CortexM1 = Microarchitecture(
155
+ "Cortex M1", [Extension.V6, Extension.Thumb2]
156
+ )
157
+ Microarchitecture.CortexM3 = Microarchitecture(
158
+ "Cortex M3", [Extension.V7M, Extension.Thumb2]
159
+ )
160
+ Microarchitecture.CortexM4 = Microarchitecture(
161
+ "Cortex M4", [Extension.V7M, Extension.Thumb2, Extension.DSP, Extension.VFP4]
162
+ )
163
+ Microarchitecture.CortexM7 = Microarchitecture(
164
+ "Cortex M7",
165
+ [Extension.V7M, Extension.Thumb2, Extension.DSP, Extension.VFP4, Extension.VFPd32],
166
+ )
167
+
168
+ # ARMv8-M Cortex-M series microarchitectures
169
+ Microarchitecture.CortexM23 = Microarchitecture(
170
+ "Cortex M23", [Extension.V8MBase, Extension.Thumb, Extension.TrustZone]
171
+ )
172
+ Microarchitecture.CortexM33 = Microarchitecture(
173
+ "Cortex M33",
174
+ [
175
+ Extension.V8MMain,
176
+ Extension.Thumb2,
177
+ Extension.DSP,
178
+ Extension.TrustZone,
179
+ ],
180
+ )
181
+ Microarchitecture.CortexM35P = Microarchitecture(
182
+ "Cortex M35P",
183
+ [
184
+ Extension.V8MMain,
185
+ Extension.Thumb2,
186
+ Extension.DSP,
187
+ Extension.TrustZone,
188
+ ],
189
+ )
190
+ Microarchitecture.CortexM55 = Microarchitecture(
191
+ "Cortex M55",
192
+ [
193
+ Extension.V8_1MMain,
194
+ Extension.Thumb2,
195
+ Extension.DSP,
196
+ Extension.VFP4,
197
+ Extension.TrustZone,
198
+ Extension.MVE,
199
+ ],
200
+ )
201
+ Microarchitecture.CortexM85 = Microarchitecture(
202
+ "Cortex M85",
203
+ [
204
+ Extension.V8_1MMain,
205
+ Extension.Thumb2,
206
+ Extension.DSP,
207
+ Extension.VFP4,
208
+ Extension.TrustZone,
209
+ Extension.MVE,
210
+ ],
211
+ )