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
nervapy/literal.py ADDED
@@ -0,0 +1,731 @@
1
+ import six
2
+
3
+ from nervapy.c.types import (Type, double_, float_, int8_t, int16_t, int32_t,
4
+ int64_t, uint8_t, uint16_t, uint32_t, uint64_t)
5
+ from nervapy.name import Name
6
+ from nervapy.parse import parse_assigned_variable_name
7
+
8
+
9
+ class Constant:
10
+ _supported_sizes = [1, 2, 4, 8, 16, 32, 64]
11
+ _supported_types = [
12
+ uint8_t,
13
+ uint16_t,
14
+ uint32_t,
15
+ uint64_t,
16
+ int8_t,
17
+ int16_t,
18
+ int32_t,
19
+ int64_t,
20
+ float_,
21
+ double_,
22
+ ]
23
+
24
+ def __init__(self, size, repeats, data, element_ctype, name):
25
+ assert isinstance(size, six.integer_types), "Constant size must be an integer"
26
+ assert (
27
+ size in Constant._supported_sizes
28
+ ), "Unsupported size %s: the only supported sizes are %s" % (
29
+ str(size),
30
+ ", ".join(map(str, sorted(Constant._supported_sizes))),
31
+ )
32
+ assert isinstance(
33
+ repeats, six.integer_types
34
+ ), "The number of constant repeats must be an integer"
35
+ assert (
36
+ size % repeats == 0
37
+ ), "The number of constant repeats must divide constant size without remainder"
38
+ assert isinstance(
39
+ element_ctype, Type
40
+ ), "Element type must be an instance of nervapy.c.Type"
41
+ assert (
42
+ element_ctype in Constant._supported_types
43
+ ), "The only supported types are %s" % ", ".join(Constant._supported_types)
44
+ assert isinstance(name, Name)
45
+
46
+ self.size = size
47
+ self.repeats = repeats
48
+ self.element_ctype = element_ctype
49
+ self.data = data
50
+
51
+ self.name = (name,)
52
+
53
+ self.label = None
54
+ self.prefix = None
55
+
56
+ def __str__(self):
57
+ format_spec = "%%0%dX" % (self.size / self.repeats * 2)
58
+ return "<" + ", ".join(format_spec % data for data in self.data) + ">"
59
+
60
+ def __hash__(self):
61
+ return hash(self.data) ^ hash(self.size) ^ hash(self.repeats)
62
+
63
+ def __eq__(self, other):
64
+ return (
65
+ isinstance(other, Constant)
66
+ and self.data == other.data
67
+ and self.element_ctype == other.element_ctype
68
+ )
69
+
70
+ def encode(self, encoder):
71
+ from nervapy.encoder import Encoder
72
+
73
+ assert isinstance(encoder, Encoder)
74
+ encode_function = {
75
+ 1: encoder.uint8,
76
+ 2: encoder.uint16,
77
+ 4: encoder.uint32,
78
+ 8: encoder.uint64,
79
+ }[self.size / self.repeats]
80
+ return bytearray().join([encode_function(data) for data in self.data])
81
+
82
+ @property
83
+ def alignment(self):
84
+ if self.size == 10:
85
+ return 16
86
+ else:
87
+ return self.size
88
+
89
+ @property
90
+ def as_hex(self):
91
+ from nervapy.encoder import Encoder, Endianness
92
+
93
+ bytestring = self.encode(Encoder(Endianness.Little))
94
+ return "".join("%02X" % byte for byte in bytestring)
95
+
96
+ def format(self, assembly_format):
97
+ if assembly_format == "go":
98
+ return "const0x" + self.as_hex + "(SB)"
99
+ else:
100
+ return str(self)
101
+
102
+ @staticmethod
103
+ def _uint64xN(name, n, *args):
104
+ from nervapy.util import is_int, is_int64
105
+
106
+ assert is_int(n)
107
+ args = [arg for arg in args if arg is not None]
108
+ if len(args) == 0:
109
+ raise ValueError("At least one constant value must be specified")
110
+ if len(args) != 1 and len(args) != n:
111
+ raise ValueError("Either 1 or %d values must be specified" % n)
112
+ for i, number in enumerate(args):
113
+ if not is_int(number):
114
+ raise TypeError("The value %s is not an integer" % str(number))
115
+ if not is_int64(number):
116
+ raise ValueError("The number %d is not a 64-bit integer" % number)
117
+ if number < 0:
118
+ args[i] += 0x10000000000000000
119
+ if len(args) == 1:
120
+ args = [args[0]] * n
121
+ return Constant(8 * n, n, tuple(args), uint64_t, name)
122
+
123
+ @staticmethod
124
+ def _uint32xN(name, n, *args):
125
+ from nervapy.util import is_int, is_int32
126
+
127
+ assert is_int(n)
128
+ args = [arg for arg in args if arg is not None]
129
+ if len(args) == 0:
130
+ raise ValueError("At least one constant value must be specified")
131
+ if len(args) != 1 and len(args) != n:
132
+ raise ValueError("Either 1 or %d values must be specified" % n)
133
+ for i, number in enumerate(args):
134
+ if not is_int(number):
135
+ raise TypeError("The value %s is not an integer" % str(number))
136
+ if not is_int32(number):
137
+ raise ValueError("The number %d is not a 32-bit integer" % number)
138
+ if number < 0:
139
+ args[i] += 0x100000000
140
+ if len(args) == 1:
141
+ args = [args[0]] * n
142
+ return Constant(4 * n, n, tuple(args), uint32_t, name)
143
+
144
+ @staticmethod
145
+ def _uint16xN(name, n, *args):
146
+ from nervapy.util import is_int, is_int32
147
+
148
+ assert is_int(n)
149
+ args = [arg for arg in args if arg is not None]
150
+ if len(args) == 0:
151
+ raise ValueError("At least one constant value must be specified")
152
+ if len(args) != 1 and len(args) != n:
153
+ raise ValueError("Either 1 or %d values must be specified" % n)
154
+ for i, number in enumerate(args):
155
+ if not is_int(number):
156
+ raise TypeError("The value %s is not an integer" % str(number))
157
+ if not is_int32(number):
158
+ raise ValueError("The number %d is not a 16-bit integer" % number)
159
+ if number < 0:
160
+ args[i] += 0x100000000
161
+ if len(args) == 1:
162
+ args = [args[0]] * n
163
+ return Constant(2 * n, n, tuple(args), uint32_t, name)
164
+
165
+ @staticmethod
166
+ def _float64xN(name, n, *args):
167
+ args = [arg for arg in args if arg is not None]
168
+ if len(args) == 0:
169
+ raise ValueError("At least one constant value must be specified")
170
+ if len(args) != 1 and len(args) != n:
171
+ raise ValueError("Either 1 or %d values must be specified" % n)
172
+ args = [Constant._parse_float64(arg) for arg in args]
173
+ if len(args) == 1:
174
+ args = [args[0]] * n
175
+ return Constant(8 * n, n, tuple(args), double_, name)
176
+
177
+ @staticmethod
178
+ def _float32xN(name, n, *args):
179
+ args = [arg for arg in args if arg is not None]
180
+ if len(args) == 0:
181
+ raise ValueError("At least one constant value must be specified")
182
+ if len(args) != 1 and len(args) != n:
183
+ raise ValueError("Either 1 or %d values must be specified" % n)
184
+ args = [Constant._parse_float32(arg) for arg in args]
185
+ if len(args) == 1:
186
+ args = [args[0]] * n
187
+ return Constant(4 * n, n, tuple(args), double_, name)
188
+
189
+ @staticmethod
190
+ def uint64(number, name=None):
191
+ if name is not None:
192
+ Name.check_name(name)
193
+ name = Name(name=name)
194
+ else:
195
+ import inspect
196
+
197
+ name = Name(
198
+ prename=parse_assigned_variable_name(inspect.stack(), "Constant.uint64")
199
+ )
200
+
201
+ return Constant._uint64xN(name, 1, number)
202
+
203
+ @staticmethod
204
+ def uint64x2(number1, number2=None, name=None):
205
+ if name is not None:
206
+ Name.check_name(name)
207
+ name = Name(name=name)
208
+ else:
209
+ import inspect
210
+
211
+ name = Name(
212
+ prename=parse_assigned_variable_name(
213
+ inspect.stack(), "Constant.uint64x2"
214
+ )
215
+ )
216
+
217
+ return Constant._uint64xN(name, 2, number1, number2)
218
+
219
+ @staticmethod
220
+ def uint64x4(number1, number2=None, number3=None, number4=None, name=None):
221
+ if name is not None:
222
+ Name.check_name(name)
223
+ name = Name(name=name)
224
+ else:
225
+ import inspect
226
+
227
+ name = Name(
228
+ prename=parse_assigned_variable_name(
229
+ inspect.stack(), "Constant.uint64x4"
230
+ )
231
+ )
232
+
233
+ return Constant._uint64xN(name, 4, number1, number2, number3, number4)
234
+
235
+ @staticmethod
236
+ def uint64x8(
237
+ number1,
238
+ number2=None,
239
+ number3=None,
240
+ number4=None,
241
+ number5=None,
242
+ number6=None,
243
+ number7=None,
244
+ number8=None,
245
+ name=None,
246
+ ):
247
+ if name is not None:
248
+ Name.check_name(name)
249
+ name = Name(name=name)
250
+ else:
251
+ import inspect
252
+
253
+ name = Name(
254
+ prename=parse_assigned_variable_name(
255
+ inspect.stack(), "Constant.uint64x8"
256
+ )
257
+ )
258
+
259
+ return Constant._uint64xN(
260
+ name,
261
+ 8,
262
+ number1,
263
+ number2,
264
+ number3,
265
+ number4,
266
+ number5,
267
+ number6,
268
+ number7,
269
+ number8,
270
+ )
271
+
272
+ @staticmethod
273
+ def uint32(number, name=None):
274
+ if name is not None:
275
+ Name.check_name(name)
276
+ name = Name(name=name)
277
+ else:
278
+ import inspect
279
+
280
+ name = Name(
281
+ prename=parse_assigned_variable_name(inspect.stack(), "Constant.uint32")
282
+ )
283
+
284
+ return Constant._uint32xN(name, 1, number)
285
+
286
+ @staticmethod
287
+ def uint32x2(number1, number2=None, name=None):
288
+ if name is not None:
289
+ Name.check_name(name)
290
+ name = Name(name=name)
291
+ else:
292
+ import inspect
293
+
294
+ name = Name(
295
+ prename=parse_assigned_variable_name(
296
+ inspect.stack(), "Constant.uint32x2"
297
+ )
298
+ )
299
+
300
+ return Constant._uint32xN(name, 2, number1, number2)
301
+
302
+ @staticmethod
303
+ def uint32x4(number1, number2=None, number3=None, number4=None, name=None):
304
+ if name is not None:
305
+ Name.check_name(name)
306
+ name = Name(name=name)
307
+ else:
308
+ import inspect
309
+
310
+ name = Name(
311
+ prename=parse_assigned_variable_name(
312
+ inspect.stack(), "Constant.uint32x4"
313
+ )
314
+ )
315
+
316
+ return Constant._uint32xN(name, 4, number1, number2, number3, number4)
317
+
318
+ @staticmethod
319
+ def uint32x8(
320
+ number1,
321
+ number2=None,
322
+ number3=None,
323
+ number4=None,
324
+ number5=None,
325
+ number6=None,
326
+ number7=None,
327
+ number8=None,
328
+ name=None,
329
+ ):
330
+ if name is not None:
331
+ Name.check_name(name)
332
+ name = Name(name=name)
333
+ else:
334
+ import inspect
335
+
336
+ name = Name(
337
+ prename=parse_assigned_variable_name(
338
+ inspect.stack(), "Constant.uint32x8"
339
+ )
340
+ )
341
+
342
+ return Constant._uint32xN(
343
+ name,
344
+ 8,
345
+ number1,
346
+ number2,
347
+ number3,
348
+ number4,
349
+ number5,
350
+ number6,
351
+ number7,
352
+ number8,
353
+ )
354
+
355
+ @staticmethod
356
+ def uint32x16(
357
+ number1,
358
+ number2=None,
359
+ number3=None,
360
+ number4=None,
361
+ number5=None,
362
+ number6=None,
363
+ number7=None,
364
+ number8=None,
365
+ number9=None,
366
+ number10=None,
367
+ number11=None,
368
+ number12=None,
369
+ number13=None,
370
+ number14=None,
371
+ number15=None,
372
+ number16=None,
373
+ name=None,
374
+ ):
375
+ if name is not None:
376
+ Name.check_name(name)
377
+ name = Name(name=name)
378
+ else:
379
+ import inspect
380
+
381
+ name = Name(
382
+ prename=parse_assigned_variable_name(
383
+ inspect.stack(), "Constant.uint32x16"
384
+ )
385
+ )
386
+
387
+ return Constant._uint32xN(
388
+ name,
389
+ 16,
390
+ number1,
391
+ number2,
392
+ number3,
393
+ number4,
394
+ number5,
395
+ number6,
396
+ number7,
397
+ number8,
398
+ number9,
399
+ number10,
400
+ number11,
401
+ number12,
402
+ number13,
403
+ number14,
404
+ number15,
405
+ number16,
406
+ )
407
+
408
+ @staticmethod
409
+ def uint16x8(
410
+ number1,
411
+ number2=None,
412
+ number3=None,
413
+ number4=None,
414
+ number5=None,
415
+ number6=None,
416
+ number7=None,
417
+ number8=None,
418
+ name=None,
419
+ ):
420
+ if name is not None:
421
+ Name.check_name(name)
422
+ name = Name(name=name)
423
+ else:
424
+ import inspect
425
+
426
+ name = Name(
427
+ prename=parse_assigned_variable_name(
428
+ inspect.stack(), "Constant.uint16x8"
429
+ )
430
+ )
431
+
432
+ return Constant._uint16xN(
433
+ name,
434
+ 8,
435
+ number1,
436
+ number2,
437
+ number3,
438
+ number4,
439
+ number5,
440
+ number6,
441
+ number7,
442
+ number8,
443
+ )
444
+
445
+ @staticmethod
446
+ def uint16x16(
447
+ number1,
448
+ number2=None,
449
+ number3=None,
450
+ number4=None,
451
+ number5=None,
452
+ number6=None,
453
+ number7=None,
454
+ number8=None,
455
+ number9=None,
456
+ number10=None,
457
+ number11=None,
458
+ number12=None,
459
+ number13=None,
460
+ number14=None,
461
+ number15=None,
462
+ number16=None,
463
+ name=None,
464
+ ):
465
+ if name is not None:
466
+ Name.check_name(name)
467
+ name = Name(name=name)
468
+ else:
469
+ import inspect
470
+
471
+ name = Name(
472
+ prename=parse_assigned_variable_name(
473
+ inspect.stack(), "Constant.uint16x16"
474
+ )
475
+ )
476
+
477
+ return Constant._uint16xN(
478
+ name,
479
+ 16,
480
+ number1,
481
+ number2,
482
+ number3,
483
+ number4,
484
+ number5,
485
+ number6,
486
+ number7,
487
+ number8,
488
+ number9,
489
+ number10,
490
+ number11,
491
+ number12,
492
+ number13,
493
+ number14,
494
+ number15,
495
+ number16,
496
+ )
497
+
498
+ @staticmethod
499
+ def float64(number, name=None):
500
+ if name is not None:
501
+ Name.check_name(name)
502
+ name = Name(name=name)
503
+ else:
504
+ import inspect
505
+
506
+ name = Name(
507
+ prename=parse_assigned_variable_name(
508
+ inspect.stack(), "Constant.float64"
509
+ )
510
+ )
511
+
512
+ return Constant._float64xN(name, 1, number)
513
+
514
+ @staticmethod
515
+ def float64x2(number1, number2=None, name=None):
516
+ if name is not None:
517
+ Name.check_name(name)
518
+ name = Name(name=name)
519
+ else:
520
+ import inspect
521
+
522
+ name = Name(
523
+ prename=parse_assigned_variable_name(
524
+ inspect.stack(), "Constant.float64x2"
525
+ )
526
+ )
527
+
528
+ return Constant._float64xN(name, 2, number1, number2)
529
+
530
+ @staticmethod
531
+ def float64x4(number1, number2=None, number3=None, number4=None, name=None):
532
+ if name is not None:
533
+ Name.check_name(name)
534
+ name = Name(name=name)
535
+ else:
536
+ import inspect
537
+
538
+ name = Name(
539
+ prename=parse_assigned_variable_name(
540
+ inspect.stack(), "Constant.float64x4"
541
+ )
542
+ )
543
+
544
+ return Constant._float64xN(name, 4, number1, number2, number3, number4)
545
+
546
+ @staticmethod
547
+ def float32(number, name=None):
548
+ if name is not None:
549
+ Name.check_name(name)
550
+ name = Name(name=name)
551
+ else:
552
+ import inspect
553
+
554
+ name = Name(
555
+ prename=parse_assigned_variable_name(
556
+ inspect.stack(), "Constant.float32"
557
+ )
558
+ )
559
+
560
+ return Constant._float32xN(name, 1, number)
561
+
562
+ @staticmethod
563
+ def float32x2(number1, number2=None, name=None):
564
+ if name is not None:
565
+ Name.check_name(name)
566
+ name = Name(name=name)
567
+ else:
568
+ import inspect
569
+
570
+ name = Name(
571
+ prename=parse_assigned_variable_name(
572
+ inspect.stack(), "Constant.float32x2"
573
+ )
574
+ )
575
+
576
+ return Constant._float32xN(name, 2, number1, number2)
577
+
578
+ @staticmethod
579
+ def float32x4(number1, number2=None, number3=None, number4=None, name=None):
580
+ if name is not None:
581
+ Name.check_name(name)
582
+ name = Name(name=name)
583
+ else:
584
+ import inspect
585
+
586
+ name = Name(
587
+ prename=parse_assigned_variable_name(
588
+ inspect.stack(), "Constant.float32x4"
589
+ )
590
+ )
591
+
592
+ return Constant._float32xN(name, 4, number1, number2, number3, number4)
593
+
594
+ @staticmethod
595
+ def float32x8(
596
+ number1,
597
+ number2=None,
598
+ number3=None,
599
+ number4=None,
600
+ number5=None,
601
+ number6=None,
602
+ number7=None,
603
+ number8=None,
604
+ name=None,
605
+ ):
606
+ if name is not None:
607
+ Name.check_name(name)
608
+ name = Name(name=name)
609
+ else:
610
+ import inspect
611
+
612
+ name = Name(
613
+ prename=parse_assigned_variable_name(
614
+ inspect.stack(), "Constant.float32x8"
615
+ )
616
+ )
617
+
618
+ return Constant._float32xN(
619
+ name,
620
+ 8,
621
+ number1,
622
+ number2,
623
+ number3,
624
+ number4,
625
+ number5,
626
+ number6,
627
+ number7,
628
+ number8,
629
+ )
630
+
631
+ @staticmethod
632
+ def _convert_to_float32(number):
633
+ import array
634
+
635
+ float_array = array.array("f", [number])
636
+ return float_array[0]
637
+
638
+ @staticmethod
639
+ def _parse_float32(number):
640
+ if isinstance(number, float):
641
+ number = float.hex(Constant._convert_to_float32(number))
642
+ elif isinstance(number, str):
643
+ # Validity check
644
+ try:
645
+ number = float.hex(Constant._convert_to_float32(float.fromhex(number)))
646
+ except ValueError:
647
+ raise ValueError(
648
+ "The string %s is not a hexadecimal floating-point number" % number
649
+ )
650
+ else:
651
+ raise TypeError("Unsupported type of constant number %s" % str(number))
652
+ if number == "inf" or number == "+inf":
653
+ return 0x7F800000
654
+ elif number == "-inf":
655
+ return 0xFF800000
656
+ elif number == "nan":
657
+ return 0x7FC00000
658
+ is_negative = number.startswith("-")
659
+ point_position = number.index(".")
660
+ exp_position = number.rindex("p")
661
+ number_prefix = number[int(is_negative) : point_position]
662
+ assert number_prefix == "0x0" or number_prefix == "0x1"
663
+ mantissa = number[point_position + 1 : exp_position]
664
+ if number_prefix == "0x0" and int(mantissa) == 0:
665
+ # Zero
666
+ return int(is_negative) << 31
667
+ else:
668
+ exponent = number[exp_position + 1 :]
669
+ mantissa_bits = len(mantissa) * 4
670
+ if mantissa_bits == 23:
671
+ mantissa = int(mantissa, 16)
672
+ elif mantissa_bits < 23:
673
+ mantissa = int(mantissa, 16) << (23 - mantissa_bits)
674
+ else:
675
+ mantissa = int(mantissa, 16) >> (mantissa_bits - 23)
676
+ exponent = int(exponent)
677
+ if exponent <= -127:
678
+ # Denormals
679
+ mantissa = (mantissa + (1 << 23)) >> -(exponent + 126)
680
+ exponent = -127
681
+ return mantissa + (int(exponent + 127) << 23) + (int(is_negative) << 31)
682
+
683
+ @staticmethod
684
+ def _parse_float64(number):
685
+ if isinstance(number, float):
686
+ number = float.hex(number)
687
+ elif isinstance(number, str):
688
+ # Validity check
689
+ try:
690
+ number = float.hex(float.fromhex(number))
691
+ except ValueError:
692
+ raise ValueError(
693
+ "The string %s is not a hexadecimal floating-point number" % number
694
+ )
695
+ else:
696
+ raise TypeError("Unsupported type of constant number %s" % str(number))
697
+ if number == "inf" or number == "+inf":
698
+ return 0x7FF0000000000000
699
+ if number == "-inf":
700
+ return 0xFFF0000000000000
701
+ if number == "nan":
702
+ return 0x7FF8000000000000
703
+ is_negative = number.startswith("-")
704
+ point_position = number.index(".")
705
+ exp_position = number.rindex("p")
706
+ number_prefix = number[int(is_negative) : point_position]
707
+ assert number_prefix == "0x0" or number_prefix == "0x1"
708
+ mantissa = number[point_position + 1 : exp_position]
709
+ if number_prefix == "0x0":
710
+ # Zero
711
+ assert int(mantissa) == 0
712
+ return int(is_negative) << 63
713
+ else:
714
+ exponent = number[exp_position + 1 :]
715
+ mantissa_bits = len(mantissa) * 4
716
+ if mantissa_bits == 52:
717
+ mantissa = int(mantissa, 16)
718
+ elif mantissa_bits < 52:
719
+ mantissa = int(mantissa, 16) << (52 - mantissa_bits)
720
+ else:
721
+ mantissa = int(mantissa, 16) >> (mantissa_bits - 52)
722
+ exponent = int(exponent)
723
+ if exponent <= -1023:
724
+ # Denormals
725
+ mantissa = (mantissa + (1 << 52)) >> -(exponent + 1022)
726
+ exponent = -1023
727
+ elif exponent > 1023:
728
+ # Infinity
729
+ mantissa = 0
730
+ exponent = 1023
731
+ return mantissa + (int(exponent + 1023) << 52) + (int(is_negative) << 63)