PyNerva 0.0.6__tar.gz → 0.0.8__tar.gz
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.
- {pynerva-0.0.6 → pynerva-0.0.8}/.gitea/workflows/test.yml +1 -1
- {pynerva-0.0.6 → pynerva-0.0.8}/.github/workflows/test.yml +2 -2
- {pynerva-0.0.6 → pynerva-0.0.8}/PKG-INFO +3 -3
- {pynerva-0.0.6 → pynerva-0.0.8}/examples/arm_rust_integration.py +17 -63
- pynerva-0.0.8/examples/kernels.rs +51 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/nervapy/arm/__init__.py +1 -1
- {pynerva-0.0.6 → pynerva-0.0.8}/nervapy/arm/function.py +61 -1
- {pynerva-0.0.6 → pynerva-0.0.8}/nervapy/arm/generic.py +41 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/pyproject.toml +3 -3
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_armv8m.py +59 -3
- pynerva-0.0.8/tests/arm/test_uxth.py +43 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/uv.lock +20 -133
- pynerva-0.0.6/.python-version +0 -1
- pynerva-0.0.6/AND_W_EOR_W_IMPLEMENTATION.md +0 -99
- pynerva-0.0.6/ANSWER_ARMCC_IMPORT.md +0 -288
- pynerva-0.0.6/ANSWER_ARMV7M_BRANCH_INSTRUCTIONS.md +0 -179
- pynerva-0.0.6/ANSWER_CONSTANT_DATA.md +0 -259
- pynerva-0.0.6/ANSWER_LDR_CONSTANT.md +0 -263
- pynerva-0.0.6/ANSWER_LDR_LITERAL.md +0 -333
- pynerva-0.0.6/ANSWER_LDR_SHIFTED_REGISTER.md +0 -106
- pynerva-0.0.6/ANSWER_MOV_W_0x11111111.md +0 -87
- pynerva-0.0.6/ARMV7M_STACK_ALIGNMENT.md +0 -222
- pynerva-0.0.6/BARREL_SHIFTER_AND_LSL.md +0 -107
- pynerva-0.0.6/BARREL_SHIFTER_GUIDE.md +0 -99
- pynerva-0.0.6/BARREL_SHIFTER_TEST_FIX.md +0 -80
- pynerva-0.0.6/COMPLETED_LDR_LITERAL.md +0 -154
- pynerva-0.0.6/CONSTANT_DATA_GUIDE.md +0 -493
- pynerva-0.0.6/CONSTANT_DATA_SUMMARY.md +0 -148
- pynerva-0.0.6/CORTEX_M33_FPU_FIX.md +0 -75
- pynerva-0.0.6/CORTEX_M33_FPU_OPTIONAL.md +0 -132
- pynerva-0.0.6/C_INLINE_ASM_FEATURE.md +0 -157
- pynerva-0.0.6/C_INLINE_ASM_IMPLEMENTATION.md +0 -267
- pynerva-0.0.6/C_INLINE_ASM_TESTS.md +0 -118
- pynerva-0.0.6/HELIUM_MVE_IMPLEMENTATION_PLAN.md +0 -341
- pynerva-0.0.6/HELIUM_MVE_QUICKREF.md +0 -121
- pynerva-0.0.6/HELIUM_MVE_Q_REGISTERS.md +0 -180
- pynerva-0.0.6/HELIUM_MVE_Q_REGISTERS_SUMMARY.md +0 -70
- pynerva-0.0.6/HELIUM_MVE_STATUS.md +0 -190
- pynerva-0.0.6/HELIUM_PHASE1_COMPLETE.md +0 -142
- pynerva-0.0.6/HELIUM_PHASE1_QUICKREF.md +0 -75
- pynerva-0.0.6/HELIUM_Q_REGISTERS_COMPLETE.md +0 -110
- pynerva-0.0.6/IMPLEMENTATION_SUMMARY.md +0 -168
- pynerva-0.0.6/IMPLEMENTATION_SUMMARY_LDR_LITERAL.md +0 -191
- pynerva-0.0.6/LDR_LITERAL_GUIDE.md +0 -410
- pynerva-0.0.6/LDR_LITERAL_INTEGRATION.md +0 -228
- pynerva-0.0.6/LDR_LITERAL_LABEL_IMPLEMENTATION.md +0 -72
- pynerva-0.0.6/LDR_LITERAL_LABEL_SUPPORT.md +0 -122
- pynerva-0.0.6/LDR_LITERAL_QUICKREF.md +0 -153
- pynerva-0.0.6/LITERAL_CLASS_FIX.md +0 -73
- pynerva-0.0.6/LIVE_REGISTERS_GUIDE.md +0 -246
- pynerva-0.0.6/LIVE_REGISTERS_QUICKREF.md +0 -100
- pynerva-0.0.6/LONG_MULTIPLY_IMPLEMENTATION.md +0 -343
- pynerva-0.0.6/LONG_MULTIPLY_SUMMARY.md +0 -206
- pynerva-0.0.6/MOV_W_32BIT_IMMEDIATE.md +0 -87
- pynerva-0.0.6/MOV_W_32BIT_SUPPORT.md +0 -101
- pynerva-0.0.6/MOV_W_COMPLETE_SUMMARY.md +0 -169
- pynerva-0.0.6/MOV_W_IMPLEMENTATION.md +0 -125
- pynerva-0.0.6/MOV_W_INDEX.md +0 -66
- pynerva-0.0.6/MULTIPLY_INSTRUCTIONS_SUMMARY.md +0 -295
- pynerva-0.0.6/MULTIPLY_INSTRUCTIONS_TESTS.md +0 -236
- pynerva-0.0.6/NERVAPY_DATA_SECTION_GUIDE.md +0 -802
- pynerva-0.0.6/PHASE1_SUMMARY.md +0 -104
- pynerva-0.0.6/PRESERVE8_FEATURE.md +0 -84
- pynerva-0.0.6/PRESERVE8_IMPLEMENTATION_SUMMARY.md +0 -119
- pynerva-0.0.6/PRINT_LIVE_REGISTERS_CORRECT_FIX.md +0 -117
- pynerva-0.0.6/PRINT_LIVE_REGISTERS_FIX.md +0 -57
- pynerva-0.0.6/PRINT_LIVE_REGISTERS_SUMMARY.md +0 -48
- pynerva-0.0.6/PRINT_LIVE_REGISTERS_WITH_NAMES.md +0 -90
- pynerva-0.0.6/QUICKREF_AND_W_EOR_W.md +0 -93
- pynerva-0.0.6/QUICKREF_MOV_W.md +0 -46
- pynerva-0.0.6/REGISTER_ALLOCATION_BUG_FIX.md +0 -68
- pynerva-0.0.6/REGISTER_ALLOCATION_BUG_FIX_SUMMARY.md +0 -60
- pynerva-0.0.6/REGISTER_ALLOCATION_ERROR_IMPROVED.md +0 -89
- pynerva-0.0.6/REGISTER_ALLOCATION_ERROR_MESSAGES.md +0 -98
- pynerva-0.0.6/REGISTER_ALLOCATION_LINE_NUMBERS.md +0 -62
- pynerva-0.0.6/REGISTER_COUNT_FIX.md +0 -83
- pynerva-0.0.6/REGISTER_NAMES_IN_ERROR_MESSAGES.md +0 -84
- pynerva-0.0.6/SUMMARY_M33_FPU_FIX.md +0 -72
- pynerva-0.0.6/SUMMARY_MOV_W_FEATURE.md +0 -91
- pynerva-0.0.6/bandit-report.json +0 -7102
- pynerva-0.0.6/build/lib/nervapy/arm/__init__.py +0 -114
- pynerva-0.0.6/build/lib/nervapy/arm/function.py +0 -1990
- pynerva-0.0.6/build/lib/nervapy/arm/generic.py +0 -9347
- pynerva-0.0.6/build/lib/nervapy/arm/instructions.py +0 -499
- pynerva-0.0.6/build/lib/nervapy/arm/microarchitecture.py +0 -213
- pynerva-0.0.6/build/lib/nervapy/arm/registers.py +0 -1360
- pynerva-0.0.6/check_t4_live_example.py +0 -116
- pynerva-0.0.6/demo_and_w_eor_w.py +0 -56
- pynerva-0.0.6/demo_ldr_patterns.py +0 -169
- pynerva-0.0.6/demo_live_registers.py +0 -110
- pynerva-0.0.6/epcc_radix16.py +0 -178
- pynerva-0.0.6/example_print_live_registers.py +0 -75
- pynerva-0.0.6/examples/arm_dsp_multiply_additional.py +0 -203
- pynerva-0.0.6/examples/arm_long_multiply_example.py +0 -289
- pynerva-0.0.6/examples/arm_multiply_instructions.py +0 -274
- pynerva-0.0.6/examples/arm_stack_alignment_example.py +0 -199
- pynerva-0.0.6/examples/arm_umull_example.py +0 -132
- pynerva-0.0.6/examples/armcc_preserve8_example.py +0 -163
- pynerva-0.0.6/examples/c_inline_asm_x86_64_example.py +0 -176
- pynerva-0.0.6/examples/constant_data_example.py +0 -94
- pynerva-0.0.6/examples/helium_q_registers.py +0 -72
- pynerva-0.0.6/examples/ldr_literal_example.py +0 -175
- pynerva-0.0.6/examples/ldr_literal_labels.py +0 -53
- pynerva-0.0.6/examples/ldr_literal_parameter.py +0 -175
- pynerva-0.0.6/main.py +0 -6
- pynerva-0.0.6/nervapy/__init__.py +0 -50
- pynerva-0.0.6/nervapy/abi.py +0 -91
- pynerva-0.0.6/nervapy/arm/__main__.py +0 -0
- pynerva-0.0.6/nervapy/arm/abi.py +0 -138
- pynerva-0.0.6/nervapy/arm/formats.py +0 -49
- pynerva-0.0.6/nervapy/arm/isa.py +0 -409
- pynerva-0.0.6/nervapy/arm/pseudo.py +0 -652
- pynerva-0.0.6/nervapy/arm/vfpneon.py +0 -4092
- pynerva-0.0.6/nervapy/arm.py +0 -13
- pynerva-0.0.6/nervapy/c/__init__.py +0 -1
- pynerva-0.0.6/nervapy/c/types.py +0 -436
- pynerva-0.0.6/nervapy/codegen.py +0 -99
- pynerva-0.0.6/nervapy/common/__init__.py +0 -4
- pynerva-0.0.6/nervapy/common/function.py +0 -5
- pynerva-0.0.6/nervapy/common/regalloc.py +0 -121
- pynerva-0.0.6/nervapy/encoder.py +0 -246
- pynerva-0.0.6/nervapy/formats/__init__.py +0 -2
- pynerva-0.0.6/nervapy/formats/elf/__init__.py +0 -4
- pynerva-0.0.6/nervapy/formats/elf/file.py +0 -178
- pynerva-0.0.6/nervapy/formats/elf/image.py +0 -106
- pynerva-0.0.6/nervapy/formats/elf/section.py +0 -422
- pynerva-0.0.6/nervapy/formats/elf/symbol.py +0 -281
- pynerva-0.0.6/nervapy/formats/macho/__init__.py +0 -2
- pynerva-0.0.6/nervapy/formats/macho/file.py +0 -123
- pynerva-0.0.6/nervapy/formats/macho/image.py +0 -143
- pynerva-0.0.6/nervapy/formats/macho/section.py +0 -322
- pynerva-0.0.6/nervapy/formats/macho/symbol.py +0 -158
- pynerva-0.0.6/nervapy/formats/mscoff/__init__.py +0 -8
- pynerva-0.0.6/nervapy/formats/mscoff/image.py +0 -132
- pynerva-0.0.6/nervapy/formats/mscoff/section.py +0 -181
- pynerva-0.0.6/nervapy/formats/mscoff/symbol.py +0 -148
- pynerva-0.0.6/nervapy/function.py +0 -136
- pynerva-0.0.6/nervapy/literal.py +0 -731
- pynerva-0.0.6/nervapy/loader.py +0 -188
- pynerva-0.0.6/nervapy/name.py +0 -159
- pynerva-0.0.6/nervapy/parse.py +0 -52
- pynerva-0.0.6/nervapy/stream.py +0 -58
- pynerva-0.0.6/nervapy/util.py +0 -126
- pynerva-0.0.6/nervapy/writer.py +0 -518
- pynerva-0.0.6/nervapy/x86_64/__init__.py +0 -324
- pynerva-0.0.6/nervapy/x86_64/__main__.py +0 -407
- pynerva-0.0.6/nervapy/x86_64/abi.py +0 -517
- pynerva-0.0.6/nervapy/x86_64/amd.py +0 -6464
- pynerva-0.0.6/nervapy/x86_64/avx.py +0 -102029
- pynerva-0.0.6/nervapy/x86_64/crypto.py +0 -1533
- pynerva-0.0.6/nervapy/x86_64/encoding.py +0 -424
- pynerva-0.0.6/nervapy/x86_64/fma.py +0 -19138
- pynerva-0.0.6/nervapy/x86_64/function.py +0 -2707
- pynerva-0.0.6/nervapy/x86_64/generic.py +0 -23384
- pynerva-0.0.6/nervapy/x86_64/instructions.py +0 -500
- pynerva-0.0.6/nervapy/x86_64/isa.py +0 -476
- pynerva-0.0.6/nervapy/x86_64/lower.py +0 -126
- pynerva-0.0.6/nervapy/x86_64/mask.py +0 -2593
- pynerva-0.0.6/nervapy/x86_64/meta.py +0 -143
- pynerva-0.0.6/nervapy/x86_64/mmxsse.py +0 -17265
- pynerva-0.0.6/nervapy/x86_64/nacl.py +0 -327
- pynerva-0.0.6/nervapy/x86_64/operand.py +0 -1204
- pynerva-0.0.6/nervapy/x86_64/options.py +0 -21
- pynerva-0.0.6/nervapy/x86_64/pseudo.py +0 -686
- pynerva-0.0.6/nervapy/x86_64/registers.py +0 -1225
- pynerva-0.0.6/nervapy/x86_64/types.py +0 -17
- pynerva-0.0.6/nervapy/x86_64/uarch.py +0 -580
- {pynerva-0.0.6 → pynerva-0.0.8}/.gitea/WORKFLOWS.md +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/.gitea/workflows/code-quality.yml +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/.gitea/workflows/release.yml +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/.github/WORKFLOWS.md +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/.github/workflows/code-quality.yml +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/.github/workflows/publish.yml +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/.github/workflows/release.yml +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/.gitignore +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/.travis.yml +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/LICENSE.rst +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/NervaPy.egg-info/PKG-INFO +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/NervaPy.egg-info/SOURCES.txt +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/NervaPy.egg-info/dependency_links.txt +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/NervaPy.egg-info/requires.txt +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/NervaPy.egg-info/top_level.txt +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/README.md +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/README.rst +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/STRD_IMPLEMENTATION.md +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/appveyor.yml +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/codegen/__init__.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/codegen/code.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/codegen/x86_64.json +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/codegen/x86_64.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/codegen/x86_64_nacl_test.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/codegen/x86_64_test_encoding.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/docs/ARM_BRANCH_INSTRUCTIONS.md +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/docs/ARM_IMPORT_EXTERNAL_FUNCTIONS.md +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/docs/ARM_SHIFTED_REGISTER_ADDRESSING.md +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/docs/ARMv7M_SUPPORT.md +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/docs/armv7m_register_strategies.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/examples/arm_branch_instructions.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/examples/arm_cortex_m_example.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/examples/arm_import_external_functions.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/examples/arm_ldr_shifted_register.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/examples/final_high_register_demo.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/examples/final_implementation_summary.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/examples/go-generate/dot_product.go +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/examples/go-generate/dot_product.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/examples/go-generate/dot_product_test.go +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/examples/go-generate/main.go +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/examples/make/Makefile +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/examples/make/matmul-opt.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/examples/make/matmul-ref.c +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/examples/make/test.c +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/examples/nmake/Makefile +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/examples/nmake/test.cpp +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/examples/nmake/transpose4x4-opt.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/examples/nmake/transpose4x4-ref.cpp +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/examples/test_high_register_strategies.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/examples/test_register_constraints.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/examples/test_simple_strategies.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/logo/college-of-computing.gif +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/logo/hpcgarage.png +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/logo/peachpy.png +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/__init__.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/abi.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/arm/__main__.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/arm/abi.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/arm/formats.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/nervapy/arm/instructions.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/arm/isa.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/nervapy/arm/literal_pool.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/nervapy/arm/microarchitecture.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/arm/pseudo.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/nervapy/arm/registers.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/arm/vfpneon.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/arm.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/c/__init__.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/c/types.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/codegen.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/common/__init__.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/common/function.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/common/regalloc.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/nervapy/constant_data.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/encoder.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/__init__.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/elf/__init__.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/elf/file.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/elf/image.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/elf/section.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/elf/symbol.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/macho/__init__.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/macho/file.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/macho/image.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/macho/section.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/macho/symbol.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/mscoff/__init__.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/mscoff/image.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/mscoff/section.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/mscoff/symbol.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/function.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/literal.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/loader.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/name.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/parse.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/stream.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/util.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/writer.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/__init__.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/__main__.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/abi.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/amd.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/avx.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/crypto.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/encoding.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/fma.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/function.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/generic.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/instructions.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/isa.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/lower.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/mask.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/meta.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/mmxsse.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/nacl.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/operand.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/options.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/pseudo.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/registers.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/types.py +0 -0
- {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/uarch.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/pytest.ini +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/requirements.txt +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/sphinx/conf.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/sphinx/index.rst +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/sphinx/nervapy.rst +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/__init__.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_and_w_eor_w.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_arm.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_armv7m.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_armv7m_registers.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_barrel_shifter.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_cortex_m33_fpu.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_dead_register_allocation.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_helium_phase1.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_live_registers.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_mov_w_32bit.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_movw_32bit.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_multiply_instructions.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_preserve8.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_register_count.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_register_overflow.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_stack_alignment.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/requirements.txt +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/test_elf.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/test_literal.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/__init__.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/encoding/__init__.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/encoding/test_amd.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/encoding/test_avx.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/encoding/test_crypto.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/encoding/test_fma.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/encoding/test_generic.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/encoding/test_imm.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/encoding/test_mask.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/encoding/test_mmxsse.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/test_analysis.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/test_function.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/test_golang.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/test_labels.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/test_load.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/test_register_allocation.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/test_register_constraints.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/test_relocation.py +0 -0
- {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/test_return.py +0 -0
|
@@ -27,7 +27,7 @@ jobs:
|
|
|
27
27
|
fail-fast: false
|
|
28
28
|
matrix:
|
|
29
29
|
os: [ ubuntu-latest-small ]
|
|
30
|
-
python-version: [ "3.
|
|
30
|
+
python-version: [ "3.10", "3.11", "3.12", "3.13", "3.14" ]
|
|
31
31
|
exclude:
|
|
32
32
|
# Exclude some combinations to reduce CI load if needed
|
|
33
33
|
- os: windows-latest
|
|
@@ -27,7 +27,7 @@ jobs:
|
|
|
27
27
|
fail-fast: false
|
|
28
28
|
matrix:
|
|
29
29
|
os: [ubuntu-latest]
|
|
30
|
-
python-version: ['3.
|
|
30
|
+
python-version: ['3.10', '3.11', '3.12', '3.13', '3.14']
|
|
31
31
|
exclude:
|
|
32
32
|
# Exclude some combinations to reduce CI load if needed
|
|
33
33
|
- os: windows-latest
|
|
@@ -162,4 +162,4 @@ jobs:
|
|
|
162
162
|
except Exception as e:
|
|
163
163
|
print(f'✗ {module}: {e}')
|
|
164
164
|
sys.exit(1)
|
|
165
|
-
"
|
|
165
|
+
"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyNerva
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.8
|
|
4
4
|
Summary: Framework for exploring advanced program synthesis and transformation techniques
|
|
5
5
|
Project-URL: Homepage, https://github.com/kriskwiatkowski/NervaPy.git
|
|
6
6
|
Author-email: Kris Kwiatkowski <kris@amongbytes.com>
|
|
@@ -27,9 +27,9 @@ Classifier: Topic :: Software Development :: Assemblers
|
|
|
27
27
|
Classifier: Topic :: Software Development :: Code Generators
|
|
28
28
|
Classifier: Topic :: Software Development :: Compilers
|
|
29
29
|
Classifier: Topic :: Software Development :: Libraries
|
|
30
|
-
Requires-Python: >=3.
|
|
30
|
+
Requires-Python: >=3.10
|
|
31
31
|
Requires-Dist: click>=8.1.8
|
|
32
|
-
Requires-Dist: requests>=2.
|
|
32
|
+
Requires-Dist: requests>=2.34.2
|
|
33
33
|
Description-Content-Type: text/x-rst
|
|
34
34
|
|
|
35
35
|
.. image:: https://github.com/kriskwiatkowski/NervaPy/blob/master/logo/nervapy.png
|
|
@@ -7,39 +7,20 @@ Rust Integration Example
|
|
|
7
7
|
Demonstrates how to generate ARM assembly kernels for use in Rust projects,
|
|
8
8
|
targeting Cortex-M33 (ARMv8-M.main).
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
// lib.rs
|
|
26
|
-
unsafe extern "C" {
|
|
27
|
-
fn copy_words(src: *const u32, dst: *mut u32, n: usize);
|
|
28
|
-
fn accumulate(data: *const u32, n: usize) -> u32;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
Option B - Embedded directly in a .rs file (no build.rs needed):
|
|
32
|
-
|
|
33
|
-
// kernels.rs (generated by this script)
|
|
34
|
-
use core::arch::global_asm;
|
|
35
|
-
core::arch::global_asm!(r#" ... "#);
|
|
36
|
-
|
|
37
|
-
// lib.rs
|
|
38
|
-
mod kernels;
|
|
39
|
-
unsafe extern "C" {
|
|
40
|
-
fn copy_words(src: *const u32, dst: *mut u32, n: usize);
|
|
41
|
-
fn accumulate(data: *const u32, n: usize) -> u32;
|
|
42
|
-
}
|
|
10
|
+
The method is embedded directly in a .rs file with typed externs (no build.rs needed):
|
|
11
|
+
|
|
12
|
+
// kernels.rs (generated by this script)
|
|
13
|
+
core::arch::global_asm!(r#" ... "#);
|
|
14
|
+
unsafe extern "C" {
|
|
15
|
+
pub fn copy_words(src: *const u32, dst: *mut u32, n: usize);
|
|
16
|
+
}
|
|
17
|
+
core::arch::global_asm!(r#" ... "#);
|
|
18
|
+
unsafe extern "C" {
|
|
19
|
+
pub fn accumulate(data: *const u32, n: usize) -> u32;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// lib.rs
|
|
23
|
+
mod kernels;
|
|
43
24
|
"""
|
|
44
25
|
|
|
45
26
|
import os
|
|
@@ -51,7 +32,6 @@ from nervapy.arm.microarchitecture import Microarchitecture
|
|
|
51
32
|
|
|
52
33
|
TARGET = Microarchitecture.CortexM33
|
|
53
34
|
|
|
54
|
-
|
|
55
35
|
def generate_copy_words():
|
|
56
36
|
"""Copy n words from src to dst - equivalent to memcpy for aligned u32 arrays."""
|
|
57
37
|
src_arg = Argument(ptr(const_uint32_t))
|
|
@@ -103,22 +83,12 @@ def generate_accumulate():
|
|
|
103
83
|
|
|
104
84
|
return f
|
|
105
85
|
|
|
106
|
-
|
|
107
|
-
def write_s_file(functions, path):
|
|
108
|
-
"""Write all functions to a single .s file (Option A)."""
|
|
109
|
-
with open(path, "w") as fp:
|
|
110
|
-
for f in functions:
|
|
111
|
-
fp.write(f.assembly)
|
|
112
|
-
print("Wrote: {}".format(path))
|
|
113
|
-
|
|
114
|
-
|
|
115
86
|
def write_global_asm_file(functions, path):
|
|
116
|
-
"""Write all functions as a Rust global_asm!()
|
|
87
|
+
"""Write all functions as a Rust file with global_asm!() and typed externs (Option B)."""
|
|
117
88
|
with open(path, "w") as fp:
|
|
118
89
|
fp.write("// Auto-generated by NervaPy - do not edit manually.\n")
|
|
119
|
-
fp.write("use core::arch::global_asm;\n\n")
|
|
120
90
|
for f in functions:
|
|
121
|
-
fp.write(f.
|
|
91
|
+
fp.write(f.rust_module)
|
|
122
92
|
fp.write("\n")
|
|
123
93
|
print("Wrote: {}".format(path))
|
|
124
94
|
|
|
@@ -128,20 +98,4 @@ if __name__ == "__main__":
|
|
|
128
98
|
accum_fn = generate_accumulate()
|
|
129
99
|
functions = [copy_fn, accum_fn]
|
|
130
100
|
|
|
131
|
-
|
|
132
|
-
os.makedirs(out_dir, exist_ok=True)
|
|
133
|
-
|
|
134
|
-
# Option A: separate .s file
|
|
135
|
-
write_s_file(functions, os.path.join(out_dir, "kernels.s"))
|
|
136
|
-
|
|
137
|
-
# Option B: global_asm!() Rust file
|
|
138
|
-
write_global_asm_file(functions, os.path.join(out_dir, "kernels.rs"))
|
|
139
|
-
|
|
140
|
-
print()
|
|
141
|
-
print("--- kernels.s (Option A) ---")
|
|
142
|
-
for f in functions:
|
|
143
|
-
print(f.assembly)
|
|
144
|
-
|
|
145
|
-
print("--- kernels.rs (Option B) ---")
|
|
146
|
-
for f in functions:
|
|
147
|
-
print(f.global_asm)
|
|
101
|
+
write_global_asm_file(functions, os.path.join(os.path.dirname(__file__), "kernels.rs"))
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// Auto-generated by NervaPy - do not edit manually.
|
|
2
|
+
core::arch::global_asm!(r#"
|
|
3
|
+
.syntax unified
|
|
4
|
+
.arch armv8-m.main
|
|
5
|
+
|
|
6
|
+
.text
|
|
7
|
+
|
|
8
|
+
.global copy_words
|
|
9
|
+
.type copy_words, %function
|
|
10
|
+
copy_words:
|
|
11
|
+
Lcopy_words.ENTRY:
|
|
12
|
+
Lcopy_words.loop_begin:
|
|
13
|
+
LDR r12, [r0], #4
|
|
14
|
+
STR r12, [r1], #4
|
|
15
|
+
SUBS r2, r2, #1
|
|
16
|
+
BNE Lcopy_words.loop_begin
|
|
17
|
+
Lcopy_words.loop_end:
|
|
18
|
+
BX lr
|
|
19
|
+
|
|
20
|
+
"#);
|
|
21
|
+
|
|
22
|
+
unsafe extern "C" {
|
|
23
|
+
pub fn copy_words(src: *const u32, dst: *mut u32, n: usize);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
core::arch::global_asm!(r#"
|
|
27
|
+
.syntax unified
|
|
28
|
+
.arch armv8-m.main
|
|
29
|
+
|
|
30
|
+
.text
|
|
31
|
+
|
|
32
|
+
.global accumulate
|
|
33
|
+
.type accumulate, %function
|
|
34
|
+
accumulate:
|
|
35
|
+
Laccumulate.ENTRY:
|
|
36
|
+
MOV r12, #0
|
|
37
|
+
Laccumulate.loop_begin:
|
|
38
|
+
LDR r3, [r0], #4
|
|
39
|
+
ADD r12, r12, r3
|
|
40
|
+
SUBS r1, r1, #1
|
|
41
|
+
BNE Laccumulate.loop_begin
|
|
42
|
+
Laccumulate.loop_end:
|
|
43
|
+
MOV r0, r12
|
|
44
|
+
BX lr
|
|
45
|
+
|
|
46
|
+
"#);
|
|
47
|
+
|
|
48
|
+
unsafe extern "C" {
|
|
49
|
+
pub fn accumulate(data: *const u32, n: usize) -> u32;
|
|
50
|
+
}
|
|
51
|
+
|
|
@@ -93,7 +93,7 @@ from nervapy.arm.generic import (ADC, ADCCC, ADCCS, ADCEQ, ADCGE, ADCGT, ADCHI,
|
|
|
93
93
|
TSTCS, TSTEQ, TSTGE, TSTGT, TSTHI, TSTHS,
|
|
94
94
|
TSTLE, TSTLO, TSTLS, TSTLT, TSTMI, TSTNE,
|
|
95
95
|
TSTPL, TSTVC, TSTVS, TT, TTA, TTAT, TTT,
|
|
96
|
-
UMAAL, UMAALGE, UMLAL, UMULL, B)
|
|
96
|
+
UMAAL, UMAALGE, UMLAL, UMULL, UXTH, B)
|
|
97
97
|
from nervapy.arm.literal_pool import LDR_LITERAL, LDRL
|
|
98
98
|
from nervapy.arm.microarchitecture import Microarchitecture
|
|
99
99
|
from nervapy.arm.pseudo import (ALIGN, ASSUME, IMPORT, INIT, LABEL, LOAD,
|
|
@@ -338,7 +338,67 @@ class Function(object):
|
|
|
338
338
|
unsafe extern "C" { fn my_func(a: u32) -> u32; }
|
|
339
339
|
"""
|
|
340
340
|
gas = self._generate_gas_assembly()
|
|
341
|
-
return 'core::arch::global_asm!(r#"\n{asm}"#);\n'.format(
|
|
341
|
+
return 'core::arch::global_asm!(r#"\n{asm}"#);\n'.format(
|
|
342
|
+
asm=self._escape_rust_asm_template(gas)
|
|
343
|
+
)
|
|
344
|
+
|
|
345
|
+
@staticmethod
|
|
346
|
+
def _escape_rust_asm_template(asm):
|
|
347
|
+
return asm.replace("{", "{{").replace("}", "}}")
|
|
348
|
+
|
|
349
|
+
def _rust_ffi_type(self, c_type):
|
|
350
|
+
if c_type.is_pointer:
|
|
351
|
+
pointee = c_type.base
|
|
352
|
+
if pointee is None:
|
|
353
|
+
pointee_type = "core::ffi::c_void"
|
|
354
|
+
is_const_pointee = c_type.is_const
|
|
355
|
+
else:
|
|
356
|
+
pointee_type = self._rust_ffi_type(pointee)
|
|
357
|
+
is_const_pointee = pointee.is_const
|
|
358
|
+
return "{0} {1}".format(
|
|
359
|
+
"*const" if is_const_pointee else "*mut", pointee_type
|
|
360
|
+
)
|
|
361
|
+
|
|
362
|
+
if c_type.is_size_integer:
|
|
363
|
+
return "usize" if c_type.is_unsigned_integer else "isize"
|
|
364
|
+
if c_type.is_pointer_integer:
|
|
365
|
+
return "usize" if c_type.is_unsigned_integer else "isize"
|
|
366
|
+
if c_type.is_bool:
|
|
367
|
+
return "bool"
|
|
368
|
+
if c_type.is_char:
|
|
369
|
+
return "core::ffi::c_char"
|
|
370
|
+
if c_type.is_wchar:
|
|
371
|
+
wchar_size = c_type.get_size(self.abi)
|
|
372
|
+
return {2: "u16", 4: "u32"}[wchar_size]
|
|
373
|
+
if c_type.is_floating_point:
|
|
374
|
+
return {2: "u16", 4: "f32", 8: "f64"}[c_type.get_size(self.abi)]
|
|
375
|
+
if c_type.is_signed_integer:
|
|
376
|
+
return {1: "i8", 2: "i16", 4: "i32", 8: "i64"}[c_type.get_size(self.abi)]
|
|
377
|
+
if c_type.is_unsigned_integer:
|
|
378
|
+
return {1: "u8", 2: "u16", 4: "u32", 8: "u64"}[c_type.get_size(self.abi)]
|
|
379
|
+
|
|
380
|
+
raise ValueError("Unsupported Rust FFI type for {0}".format(c_type))
|
|
381
|
+
|
|
382
|
+
@property
|
|
383
|
+
def rust_extern_declaration(self):
|
|
384
|
+
args = ", ".join(
|
|
385
|
+
"{0}: {1}".format(argument.name, self._rust_ffi_type(argument.c_type))
|
|
386
|
+
for argument in self.arguments
|
|
387
|
+
)
|
|
388
|
+
signature = "pub fn {0}({1})".format(self.name, args)
|
|
389
|
+
if self.return_type is not None:
|
|
390
|
+
signature += " -> {0}".format(self._rust_ffi_type(self.return_type))
|
|
391
|
+
return signature + ";"
|
|
392
|
+
|
|
393
|
+
@property
|
|
394
|
+
def rust_extern(self):
|
|
395
|
+
return "unsafe extern \"C\" {{\n {0}\n}}\n".format(
|
|
396
|
+
self.rust_extern_declaration
|
|
397
|
+
)
|
|
398
|
+
|
|
399
|
+
@property
|
|
400
|
+
def rust_module(self):
|
|
401
|
+
return self.global_asm + "\n" + self.rust_extern
|
|
342
402
|
|
|
343
403
|
def _generate_gas_assembly(self):
|
|
344
404
|
"""Generate assembly code in GNU Assembler (GAS) format."""
|
|
@@ -9509,6 +9509,47 @@ class BitFieldInstruction(Instruction):
|
|
|
9509
9509
|
def get_output_registers_list(self):
|
|
9510
9510
|
return self.operands[0].get_registers_list()
|
|
9511
9511
|
|
|
9512
|
+
|
|
9513
|
+
class UnsignedExtendHalfwordInstruction(Instruction):
|
|
9514
|
+
"""UXTH - zero-extend the low halfword of a register."""
|
|
9515
|
+
|
|
9516
|
+
def __init__(self, destination, source, origin=None):
|
|
9517
|
+
from nervapy.arm.function import active_function
|
|
9518
|
+
from nervapy.arm.isa import Extension
|
|
9519
|
+
|
|
9520
|
+
if not (
|
|
9521
|
+
destination.is_general_purpose_register()
|
|
9522
|
+
and source.is_general_purpose_register()
|
|
9523
|
+
):
|
|
9524
|
+
raise ValueError(
|
|
9525
|
+
"UXTH destination and source operands must be general-purpose registers"
|
|
9526
|
+
)
|
|
9527
|
+
if active_function and Extension.V6 not in active_function.target.extensions:
|
|
9528
|
+
raise ValueError("UXTH is not supported on the current target")
|
|
9529
|
+
super(UnsignedExtendHalfwordInstruction, self).__init__(
|
|
9530
|
+
"UXTH", [destination, source], origin=origin
|
|
9531
|
+
)
|
|
9532
|
+
|
|
9533
|
+
def get_input_registers_list(self):
|
|
9534
|
+
return self.operands[1].get_registers_list()
|
|
9535
|
+
|
|
9536
|
+
def get_output_registers_list(self):
|
|
9537
|
+
return self.operands[0].get_registers_list()
|
|
9538
|
+
|
|
9539
|
+
|
|
9540
|
+
def UXTH(destination, source):
|
|
9541
|
+
"""UXTH - zero-extend bits 0-15 of *source* into *destination*."""
|
|
9542
|
+
origin = (
|
|
9543
|
+
inspect.stack() if nervapy.arm.function.active_function.collect_origin else None
|
|
9544
|
+
)
|
|
9545
|
+
instruction = UnsignedExtendHalfwordInstruction(
|
|
9546
|
+
Operand(destination), Operand(source), origin=origin
|
|
9547
|
+
)
|
|
9548
|
+
if nervapy.stream.active_stream is not None:
|
|
9549
|
+
nervapy.stream.active_stream.add_instruction(instruction)
|
|
9550
|
+
return instruction
|
|
9551
|
+
|
|
9552
|
+
|
|
9512
9553
|
def BFI(destination, source, lsb, width):
|
|
9513
9554
|
"""BFI - Bit Field Insert (Thumb-2 / ARMv7-M, ARMv8-M.main).
|
|
9514
9555
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "PyNerva"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.8"
|
|
4
4
|
description = "Framework for exploring advanced program synthesis and transformation techniques"
|
|
5
5
|
authors = [{ name = "Kris Kwiatkowski", email = "kris@amongbytes.com" }]
|
|
6
6
|
keywords = [
|
|
@@ -15,7 +15,7 @@ keywords = [
|
|
|
15
15
|
"code transformation",
|
|
16
16
|
]
|
|
17
17
|
readme = "README.rst"
|
|
18
|
-
requires-python = ">=3.
|
|
18
|
+
requires-python = ">=3.10"
|
|
19
19
|
classifiers = [
|
|
20
20
|
"Development Status :: 3 - Alpha",
|
|
21
21
|
"Intended Audience :: Developers",
|
|
@@ -39,7 +39,7 @@ classifiers = [
|
|
|
39
39
|
"Topic :: Software Development :: Compilers",
|
|
40
40
|
"Topic :: Software Development :: Libraries",
|
|
41
41
|
]
|
|
42
|
-
dependencies = ["click>=8.1.8", "requests>=2.
|
|
42
|
+
dependencies = ["click>=8.1.8", "requests>=2.34.2"]
|
|
43
43
|
|
|
44
44
|
[project.urls]
|
|
45
45
|
Homepage = "https://github.com/kriskwiatkowski/NervaPy.git"
|
|
@@ -446,6 +446,25 @@ class TestRustOutput(unittest.TestCase):
|
|
|
446
446
|
RETURN()
|
|
447
447
|
return f
|
|
448
448
|
|
|
449
|
+
def _make_accumulate(self, target):
|
|
450
|
+
data_arg = Argument(ptr(const_uint32_t))
|
|
451
|
+
n_arg = Argument(size_t)
|
|
452
|
+
with Function('accumulate', (data_arg, n_arg), uint32_t,
|
|
453
|
+
target=target, abi=arm_gnueabihf,
|
|
454
|
+
report_generation=False) as f:
|
|
455
|
+
(data, n) = LOAD.ARGUMENTS()
|
|
456
|
+
acc = GeneralPurposeRegister()
|
|
457
|
+
MOV(acc, 0)
|
|
458
|
+
with Loop() as loop:
|
|
459
|
+
word = GeneralPurposeRegister()
|
|
460
|
+
LDR(word, [data], 4)
|
|
461
|
+
ADD(acc, acc, word)
|
|
462
|
+
SUBS(n, n, 1)
|
|
463
|
+
BNE(loop.begin)
|
|
464
|
+
MOV(r0, acc)
|
|
465
|
+
RETURN()
|
|
466
|
+
return f
|
|
467
|
+
|
|
449
468
|
def test_global_asm_macro_wrapping(self):
|
|
450
469
|
"""global_asm property wraps GAS output in core::arch::global_asm!(r#"..."#)."""
|
|
451
470
|
f = self._make_copy_words(Microarchitecture.CortexM33)
|
|
@@ -456,12 +475,49 @@ class TestRustOutput(unittest.TestCase):
|
|
|
456
475
|
self.assertIn('copy_words:', out)
|
|
457
476
|
self.assertIn('.arch armv8-m.main', out)
|
|
458
477
|
|
|
459
|
-
def
|
|
460
|
-
"""global_asm content is
|
|
478
|
+
def test_global_asm_matches_escaped_gas_assembly(self):
|
|
479
|
+
"""global_asm content is Rust-escaped GAS assembly."""
|
|
461
480
|
f = self._make_copy_words(Microarchitecture.CortexM33)
|
|
462
481
|
gas = f.assembly
|
|
463
482
|
global_asm = f.global_asm
|
|
464
|
-
self.assertIn(gas, global_asm)
|
|
483
|
+
self.assertIn(gas.replace('{', '{{').replace('}', '}}'), global_asm)
|
|
484
|
+
|
|
485
|
+
def test_global_asm_escapes_register_lists(self):
|
|
486
|
+
"""global_asm escapes braces so register lists are valid Rust asm templates."""
|
|
487
|
+
from nervapy.arm.registers import lr, r4, r5
|
|
488
|
+
with Function('push_pop', (), None,
|
|
489
|
+
target=Microarchitecture.CortexM33, abi=arm_gnueabihf,
|
|
490
|
+
report_generation=False) as f:
|
|
491
|
+
PUSH((r4, r5))
|
|
492
|
+
POP((r4, r5))
|
|
493
|
+
BX(lr)
|
|
494
|
+
|
|
495
|
+
out = f.global_asm
|
|
496
|
+
self.assertIn('{{r4, r5}}', out)
|
|
497
|
+
|
|
498
|
+
def test_rust_extern_declaration_for_arguments(self):
|
|
499
|
+
"""rust_extern_declaration maps pointer and size arguments to Rust FFI types."""
|
|
500
|
+
f = self._make_copy_words(Microarchitecture.CortexM33)
|
|
501
|
+
self.assertEqual(
|
|
502
|
+
f.rust_extern_declaration,
|
|
503
|
+
'pub fn copy_words(src: *const u32, dst: *mut u32, len: usize);'
|
|
504
|
+
)
|
|
505
|
+
|
|
506
|
+
def test_rust_extern_declaration_for_return_value(self):
|
|
507
|
+
"""rust_extern_declaration includes the Rust return type."""
|
|
508
|
+
f = self._make_accumulate(Microarchitecture.CortexM33)
|
|
509
|
+
self.assertEqual(
|
|
510
|
+
f.rust_extern_declaration,
|
|
511
|
+
'pub fn accumulate(data: *const u32, n: usize) -> u32;'
|
|
512
|
+
)
|
|
513
|
+
|
|
514
|
+
def test_rust_module_combines_asm_and_extern(self):
|
|
515
|
+
"""rust_module emits both the assembly body and the typed extern declaration."""
|
|
516
|
+
f = self._make_accumulate(Microarchitecture.CortexM33)
|
|
517
|
+
out = f.rust_module
|
|
518
|
+
self.assertIn('core::arch::global_asm!(r#"', out)
|
|
519
|
+
self.assertIn('unsafe extern "C" {', out)
|
|
520
|
+
self.assertIn('pub fn accumulate(data: *const u32, n: usize) -> u32;', out)
|
|
465
521
|
|
|
466
522
|
def test_gas_output_usable_as_s_file(self):
|
|
467
523
|
"""GAS output has directives required for a Rust .s file."""
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
|
|
3
|
+
from nervapy import *
|
|
4
|
+
from nervapy.arm import *
|
|
5
|
+
from nervapy.arm.abi import arm_gnueabihf
|
|
6
|
+
from nervapy.arm.microarchitecture import Microarchitecture
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TestUXTH(unittest.TestCase):
|
|
10
|
+
def test_emits_zero_extend_halfword(self):
|
|
11
|
+
with Function(
|
|
12
|
+
"zero_extend_halfword",
|
|
13
|
+
(),
|
|
14
|
+
target=Microarchitecture.ARM11,
|
|
15
|
+
abi=arm_gnueabihf,
|
|
16
|
+
report_generation=False,
|
|
17
|
+
) as function:
|
|
18
|
+
UXTH(r0, r1)
|
|
19
|
+
RETURN()
|
|
20
|
+
|
|
21
|
+
self.assertIn("UXTH r0, r1", function.assembly)
|
|
22
|
+
|
|
23
|
+
def test_requires_armv6(self):
|
|
24
|
+
with self.assertRaisesRegex(ValueError, "not supported"):
|
|
25
|
+
with Function(
|
|
26
|
+
"unsupported_uxth",
|
|
27
|
+
(),
|
|
28
|
+
target=Microarchitecture.ARM9,
|
|
29
|
+
abi=arm_gnueabihf,
|
|
30
|
+
report_generation=False,
|
|
31
|
+
):
|
|
32
|
+
UXTH(r0, r1)
|
|
33
|
+
|
|
34
|
+
def test_rejects_non_register_operands(self):
|
|
35
|
+
with self.assertRaisesRegex(ValueError, "general-purpose registers"):
|
|
36
|
+
with Function(
|
|
37
|
+
"invalid_uxth",
|
|
38
|
+
(),
|
|
39
|
+
target=Microarchitecture.ARM11,
|
|
40
|
+
abi=arm_gnueabihf,
|
|
41
|
+
report_generation=False,
|
|
42
|
+
):
|
|
43
|
+
UXTH(r0, 1)
|