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.
Files changed (332) hide show
  1. {pynerva-0.0.6 → pynerva-0.0.8}/.gitea/workflows/test.yml +1 -1
  2. {pynerva-0.0.6 → pynerva-0.0.8}/.github/workflows/test.yml +2 -2
  3. {pynerva-0.0.6 → pynerva-0.0.8}/PKG-INFO +3 -3
  4. {pynerva-0.0.6 → pynerva-0.0.8}/examples/arm_rust_integration.py +17 -63
  5. pynerva-0.0.8/examples/kernels.rs +51 -0
  6. {pynerva-0.0.6 → pynerva-0.0.8}/nervapy/arm/__init__.py +1 -1
  7. {pynerva-0.0.6 → pynerva-0.0.8}/nervapy/arm/function.py +61 -1
  8. {pynerva-0.0.6 → pynerva-0.0.8}/nervapy/arm/generic.py +41 -0
  9. {pynerva-0.0.6 → pynerva-0.0.8}/pyproject.toml +3 -3
  10. {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_armv8m.py +59 -3
  11. pynerva-0.0.8/tests/arm/test_uxth.py +43 -0
  12. {pynerva-0.0.6 → pynerva-0.0.8}/uv.lock +20 -133
  13. pynerva-0.0.6/.python-version +0 -1
  14. pynerva-0.0.6/AND_W_EOR_W_IMPLEMENTATION.md +0 -99
  15. pynerva-0.0.6/ANSWER_ARMCC_IMPORT.md +0 -288
  16. pynerva-0.0.6/ANSWER_ARMV7M_BRANCH_INSTRUCTIONS.md +0 -179
  17. pynerva-0.0.6/ANSWER_CONSTANT_DATA.md +0 -259
  18. pynerva-0.0.6/ANSWER_LDR_CONSTANT.md +0 -263
  19. pynerva-0.0.6/ANSWER_LDR_LITERAL.md +0 -333
  20. pynerva-0.0.6/ANSWER_LDR_SHIFTED_REGISTER.md +0 -106
  21. pynerva-0.0.6/ANSWER_MOV_W_0x11111111.md +0 -87
  22. pynerva-0.0.6/ARMV7M_STACK_ALIGNMENT.md +0 -222
  23. pynerva-0.0.6/BARREL_SHIFTER_AND_LSL.md +0 -107
  24. pynerva-0.0.6/BARREL_SHIFTER_GUIDE.md +0 -99
  25. pynerva-0.0.6/BARREL_SHIFTER_TEST_FIX.md +0 -80
  26. pynerva-0.0.6/COMPLETED_LDR_LITERAL.md +0 -154
  27. pynerva-0.0.6/CONSTANT_DATA_GUIDE.md +0 -493
  28. pynerva-0.0.6/CONSTANT_DATA_SUMMARY.md +0 -148
  29. pynerva-0.0.6/CORTEX_M33_FPU_FIX.md +0 -75
  30. pynerva-0.0.6/CORTEX_M33_FPU_OPTIONAL.md +0 -132
  31. pynerva-0.0.6/C_INLINE_ASM_FEATURE.md +0 -157
  32. pynerva-0.0.6/C_INLINE_ASM_IMPLEMENTATION.md +0 -267
  33. pynerva-0.0.6/C_INLINE_ASM_TESTS.md +0 -118
  34. pynerva-0.0.6/HELIUM_MVE_IMPLEMENTATION_PLAN.md +0 -341
  35. pynerva-0.0.6/HELIUM_MVE_QUICKREF.md +0 -121
  36. pynerva-0.0.6/HELIUM_MVE_Q_REGISTERS.md +0 -180
  37. pynerva-0.0.6/HELIUM_MVE_Q_REGISTERS_SUMMARY.md +0 -70
  38. pynerva-0.0.6/HELIUM_MVE_STATUS.md +0 -190
  39. pynerva-0.0.6/HELIUM_PHASE1_COMPLETE.md +0 -142
  40. pynerva-0.0.6/HELIUM_PHASE1_QUICKREF.md +0 -75
  41. pynerva-0.0.6/HELIUM_Q_REGISTERS_COMPLETE.md +0 -110
  42. pynerva-0.0.6/IMPLEMENTATION_SUMMARY.md +0 -168
  43. pynerva-0.0.6/IMPLEMENTATION_SUMMARY_LDR_LITERAL.md +0 -191
  44. pynerva-0.0.6/LDR_LITERAL_GUIDE.md +0 -410
  45. pynerva-0.0.6/LDR_LITERAL_INTEGRATION.md +0 -228
  46. pynerva-0.0.6/LDR_LITERAL_LABEL_IMPLEMENTATION.md +0 -72
  47. pynerva-0.0.6/LDR_LITERAL_LABEL_SUPPORT.md +0 -122
  48. pynerva-0.0.6/LDR_LITERAL_QUICKREF.md +0 -153
  49. pynerva-0.0.6/LITERAL_CLASS_FIX.md +0 -73
  50. pynerva-0.0.6/LIVE_REGISTERS_GUIDE.md +0 -246
  51. pynerva-0.0.6/LIVE_REGISTERS_QUICKREF.md +0 -100
  52. pynerva-0.0.6/LONG_MULTIPLY_IMPLEMENTATION.md +0 -343
  53. pynerva-0.0.6/LONG_MULTIPLY_SUMMARY.md +0 -206
  54. pynerva-0.0.6/MOV_W_32BIT_IMMEDIATE.md +0 -87
  55. pynerva-0.0.6/MOV_W_32BIT_SUPPORT.md +0 -101
  56. pynerva-0.0.6/MOV_W_COMPLETE_SUMMARY.md +0 -169
  57. pynerva-0.0.6/MOV_W_IMPLEMENTATION.md +0 -125
  58. pynerva-0.0.6/MOV_W_INDEX.md +0 -66
  59. pynerva-0.0.6/MULTIPLY_INSTRUCTIONS_SUMMARY.md +0 -295
  60. pynerva-0.0.6/MULTIPLY_INSTRUCTIONS_TESTS.md +0 -236
  61. pynerva-0.0.6/NERVAPY_DATA_SECTION_GUIDE.md +0 -802
  62. pynerva-0.0.6/PHASE1_SUMMARY.md +0 -104
  63. pynerva-0.0.6/PRESERVE8_FEATURE.md +0 -84
  64. pynerva-0.0.6/PRESERVE8_IMPLEMENTATION_SUMMARY.md +0 -119
  65. pynerva-0.0.6/PRINT_LIVE_REGISTERS_CORRECT_FIX.md +0 -117
  66. pynerva-0.0.6/PRINT_LIVE_REGISTERS_FIX.md +0 -57
  67. pynerva-0.0.6/PRINT_LIVE_REGISTERS_SUMMARY.md +0 -48
  68. pynerva-0.0.6/PRINT_LIVE_REGISTERS_WITH_NAMES.md +0 -90
  69. pynerva-0.0.6/QUICKREF_AND_W_EOR_W.md +0 -93
  70. pynerva-0.0.6/QUICKREF_MOV_W.md +0 -46
  71. pynerva-0.0.6/REGISTER_ALLOCATION_BUG_FIX.md +0 -68
  72. pynerva-0.0.6/REGISTER_ALLOCATION_BUG_FIX_SUMMARY.md +0 -60
  73. pynerva-0.0.6/REGISTER_ALLOCATION_ERROR_IMPROVED.md +0 -89
  74. pynerva-0.0.6/REGISTER_ALLOCATION_ERROR_MESSAGES.md +0 -98
  75. pynerva-0.0.6/REGISTER_ALLOCATION_LINE_NUMBERS.md +0 -62
  76. pynerva-0.0.6/REGISTER_COUNT_FIX.md +0 -83
  77. pynerva-0.0.6/REGISTER_NAMES_IN_ERROR_MESSAGES.md +0 -84
  78. pynerva-0.0.6/SUMMARY_M33_FPU_FIX.md +0 -72
  79. pynerva-0.0.6/SUMMARY_MOV_W_FEATURE.md +0 -91
  80. pynerva-0.0.6/bandit-report.json +0 -7102
  81. pynerva-0.0.6/build/lib/nervapy/arm/__init__.py +0 -114
  82. pynerva-0.0.6/build/lib/nervapy/arm/function.py +0 -1990
  83. pynerva-0.0.6/build/lib/nervapy/arm/generic.py +0 -9347
  84. pynerva-0.0.6/build/lib/nervapy/arm/instructions.py +0 -499
  85. pynerva-0.0.6/build/lib/nervapy/arm/microarchitecture.py +0 -213
  86. pynerva-0.0.6/build/lib/nervapy/arm/registers.py +0 -1360
  87. pynerva-0.0.6/check_t4_live_example.py +0 -116
  88. pynerva-0.0.6/demo_and_w_eor_w.py +0 -56
  89. pynerva-0.0.6/demo_ldr_patterns.py +0 -169
  90. pynerva-0.0.6/demo_live_registers.py +0 -110
  91. pynerva-0.0.6/epcc_radix16.py +0 -178
  92. pynerva-0.0.6/example_print_live_registers.py +0 -75
  93. pynerva-0.0.6/examples/arm_dsp_multiply_additional.py +0 -203
  94. pynerva-0.0.6/examples/arm_long_multiply_example.py +0 -289
  95. pynerva-0.0.6/examples/arm_multiply_instructions.py +0 -274
  96. pynerva-0.0.6/examples/arm_stack_alignment_example.py +0 -199
  97. pynerva-0.0.6/examples/arm_umull_example.py +0 -132
  98. pynerva-0.0.6/examples/armcc_preserve8_example.py +0 -163
  99. pynerva-0.0.6/examples/c_inline_asm_x86_64_example.py +0 -176
  100. pynerva-0.0.6/examples/constant_data_example.py +0 -94
  101. pynerva-0.0.6/examples/helium_q_registers.py +0 -72
  102. pynerva-0.0.6/examples/ldr_literal_example.py +0 -175
  103. pynerva-0.0.6/examples/ldr_literal_labels.py +0 -53
  104. pynerva-0.0.6/examples/ldr_literal_parameter.py +0 -175
  105. pynerva-0.0.6/main.py +0 -6
  106. pynerva-0.0.6/nervapy/__init__.py +0 -50
  107. pynerva-0.0.6/nervapy/abi.py +0 -91
  108. pynerva-0.0.6/nervapy/arm/__main__.py +0 -0
  109. pynerva-0.0.6/nervapy/arm/abi.py +0 -138
  110. pynerva-0.0.6/nervapy/arm/formats.py +0 -49
  111. pynerva-0.0.6/nervapy/arm/isa.py +0 -409
  112. pynerva-0.0.6/nervapy/arm/pseudo.py +0 -652
  113. pynerva-0.0.6/nervapy/arm/vfpneon.py +0 -4092
  114. pynerva-0.0.6/nervapy/arm.py +0 -13
  115. pynerva-0.0.6/nervapy/c/__init__.py +0 -1
  116. pynerva-0.0.6/nervapy/c/types.py +0 -436
  117. pynerva-0.0.6/nervapy/codegen.py +0 -99
  118. pynerva-0.0.6/nervapy/common/__init__.py +0 -4
  119. pynerva-0.0.6/nervapy/common/function.py +0 -5
  120. pynerva-0.0.6/nervapy/common/regalloc.py +0 -121
  121. pynerva-0.0.6/nervapy/encoder.py +0 -246
  122. pynerva-0.0.6/nervapy/formats/__init__.py +0 -2
  123. pynerva-0.0.6/nervapy/formats/elf/__init__.py +0 -4
  124. pynerva-0.0.6/nervapy/formats/elf/file.py +0 -178
  125. pynerva-0.0.6/nervapy/formats/elf/image.py +0 -106
  126. pynerva-0.0.6/nervapy/formats/elf/section.py +0 -422
  127. pynerva-0.0.6/nervapy/formats/elf/symbol.py +0 -281
  128. pynerva-0.0.6/nervapy/formats/macho/__init__.py +0 -2
  129. pynerva-0.0.6/nervapy/formats/macho/file.py +0 -123
  130. pynerva-0.0.6/nervapy/formats/macho/image.py +0 -143
  131. pynerva-0.0.6/nervapy/formats/macho/section.py +0 -322
  132. pynerva-0.0.6/nervapy/formats/macho/symbol.py +0 -158
  133. pynerva-0.0.6/nervapy/formats/mscoff/__init__.py +0 -8
  134. pynerva-0.0.6/nervapy/formats/mscoff/image.py +0 -132
  135. pynerva-0.0.6/nervapy/formats/mscoff/section.py +0 -181
  136. pynerva-0.0.6/nervapy/formats/mscoff/symbol.py +0 -148
  137. pynerva-0.0.6/nervapy/function.py +0 -136
  138. pynerva-0.0.6/nervapy/literal.py +0 -731
  139. pynerva-0.0.6/nervapy/loader.py +0 -188
  140. pynerva-0.0.6/nervapy/name.py +0 -159
  141. pynerva-0.0.6/nervapy/parse.py +0 -52
  142. pynerva-0.0.6/nervapy/stream.py +0 -58
  143. pynerva-0.0.6/nervapy/util.py +0 -126
  144. pynerva-0.0.6/nervapy/writer.py +0 -518
  145. pynerva-0.0.6/nervapy/x86_64/__init__.py +0 -324
  146. pynerva-0.0.6/nervapy/x86_64/__main__.py +0 -407
  147. pynerva-0.0.6/nervapy/x86_64/abi.py +0 -517
  148. pynerva-0.0.6/nervapy/x86_64/amd.py +0 -6464
  149. pynerva-0.0.6/nervapy/x86_64/avx.py +0 -102029
  150. pynerva-0.0.6/nervapy/x86_64/crypto.py +0 -1533
  151. pynerva-0.0.6/nervapy/x86_64/encoding.py +0 -424
  152. pynerva-0.0.6/nervapy/x86_64/fma.py +0 -19138
  153. pynerva-0.0.6/nervapy/x86_64/function.py +0 -2707
  154. pynerva-0.0.6/nervapy/x86_64/generic.py +0 -23384
  155. pynerva-0.0.6/nervapy/x86_64/instructions.py +0 -500
  156. pynerva-0.0.6/nervapy/x86_64/isa.py +0 -476
  157. pynerva-0.0.6/nervapy/x86_64/lower.py +0 -126
  158. pynerva-0.0.6/nervapy/x86_64/mask.py +0 -2593
  159. pynerva-0.0.6/nervapy/x86_64/meta.py +0 -143
  160. pynerva-0.0.6/nervapy/x86_64/mmxsse.py +0 -17265
  161. pynerva-0.0.6/nervapy/x86_64/nacl.py +0 -327
  162. pynerva-0.0.6/nervapy/x86_64/operand.py +0 -1204
  163. pynerva-0.0.6/nervapy/x86_64/options.py +0 -21
  164. pynerva-0.0.6/nervapy/x86_64/pseudo.py +0 -686
  165. pynerva-0.0.6/nervapy/x86_64/registers.py +0 -1225
  166. pynerva-0.0.6/nervapy/x86_64/types.py +0 -17
  167. pynerva-0.0.6/nervapy/x86_64/uarch.py +0 -580
  168. {pynerva-0.0.6 → pynerva-0.0.8}/.gitea/WORKFLOWS.md +0 -0
  169. {pynerva-0.0.6 → pynerva-0.0.8}/.gitea/workflows/code-quality.yml +0 -0
  170. {pynerva-0.0.6 → pynerva-0.0.8}/.gitea/workflows/release.yml +0 -0
  171. {pynerva-0.0.6 → pynerva-0.0.8}/.github/WORKFLOWS.md +0 -0
  172. {pynerva-0.0.6 → pynerva-0.0.8}/.github/workflows/code-quality.yml +0 -0
  173. {pynerva-0.0.6 → pynerva-0.0.8}/.github/workflows/publish.yml +0 -0
  174. {pynerva-0.0.6 → pynerva-0.0.8}/.github/workflows/release.yml +0 -0
  175. {pynerva-0.0.6 → pynerva-0.0.8}/.gitignore +0 -0
  176. {pynerva-0.0.6 → pynerva-0.0.8}/.travis.yml +0 -0
  177. {pynerva-0.0.6 → pynerva-0.0.8}/LICENSE.rst +0 -0
  178. {pynerva-0.0.6 → pynerva-0.0.8}/NervaPy.egg-info/PKG-INFO +0 -0
  179. {pynerva-0.0.6 → pynerva-0.0.8}/NervaPy.egg-info/SOURCES.txt +0 -0
  180. {pynerva-0.0.6 → pynerva-0.0.8}/NervaPy.egg-info/dependency_links.txt +0 -0
  181. {pynerva-0.0.6 → pynerva-0.0.8}/NervaPy.egg-info/requires.txt +0 -0
  182. {pynerva-0.0.6 → pynerva-0.0.8}/NervaPy.egg-info/top_level.txt +0 -0
  183. {pynerva-0.0.6 → pynerva-0.0.8}/README.md +0 -0
  184. {pynerva-0.0.6 → pynerva-0.0.8}/README.rst +0 -0
  185. {pynerva-0.0.6 → pynerva-0.0.8}/STRD_IMPLEMENTATION.md +0 -0
  186. {pynerva-0.0.6 → pynerva-0.0.8}/appveyor.yml +0 -0
  187. {pynerva-0.0.6 → pynerva-0.0.8}/codegen/__init__.py +0 -0
  188. {pynerva-0.0.6 → pynerva-0.0.8}/codegen/code.py +0 -0
  189. {pynerva-0.0.6 → pynerva-0.0.8}/codegen/x86_64.json +0 -0
  190. {pynerva-0.0.6 → pynerva-0.0.8}/codegen/x86_64.py +0 -0
  191. {pynerva-0.0.6 → pynerva-0.0.8}/codegen/x86_64_nacl_test.py +0 -0
  192. {pynerva-0.0.6 → pynerva-0.0.8}/codegen/x86_64_test_encoding.py +0 -0
  193. {pynerva-0.0.6 → pynerva-0.0.8}/docs/ARM_BRANCH_INSTRUCTIONS.md +0 -0
  194. {pynerva-0.0.6 → pynerva-0.0.8}/docs/ARM_IMPORT_EXTERNAL_FUNCTIONS.md +0 -0
  195. {pynerva-0.0.6 → pynerva-0.0.8}/docs/ARM_SHIFTED_REGISTER_ADDRESSING.md +0 -0
  196. {pynerva-0.0.6 → pynerva-0.0.8}/docs/ARMv7M_SUPPORT.md +0 -0
  197. {pynerva-0.0.6 → pynerva-0.0.8}/docs/armv7m_register_strategies.py +0 -0
  198. {pynerva-0.0.6 → pynerva-0.0.8}/examples/arm_branch_instructions.py +0 -0
  199. {pynerva-0.0.6 → pynerva-0.0.8}/examples/arm_cortex_m_example.py +0 -0
  200. {pynerva-0.0.6 → pynerva-0.0.8}/examples/arm_import_external_functions.py +0 -0
  201. {pynerva-0.0.6 → pynerva-0.0.8}/examples/arm_ldr_shifted_register.py +0 -0
  202. {pynerva-0.0.6 → pynerva-0.0.8}/examples/final_high_register_demo.py +0 -0
  203. {pynerva-0.0.6 → pynerva-0.0.8}/examples/final_implementation_summary.py +0 -0
  204. {pynerva-0.0.6 → pynerva-0.0.8}/examples/go-generate/dot_product.go +0 -0
  205. {pynerva-0.0.6 → pynerva-0.0.8}/examples/go-generate/dot_product.py +0 -0
  206. {pynerva-0.0.6 → pynerva-0.0.8}/examples/go-generate/dot_product_test.go +0 -0
  207. {pynerva-0.0.6 → pynerva-0.0.8}/examples/go-generate/main.go +0 -0
  208. {pynerva-0.0.6 → pynerva-0.0.8}/examples/make/Makefile +0 -0
  209. {pynerva-0.0.6 → pynerva-0.0.8}/examples/make/matmul-opt.py +0 -0
  210. {pynerva-0.0.6 → pynerva-0.0.8}/examples/make/matmul-ref.c +0 -0
  211. {pynerva-0.0.6 → pynerva-0.0.8}/examples/make/test.c +0 -0
  212. {pynerva-0.0.6 → pynerva-0.0.8}/examples/nmake/Makefile +0 -0
  213. {pynerva-0.0.6 → pynerva-0.0.8}/examples/nmake/test.cpp +0 -0
  214. {pynerva-0.0.6 → pynerva-0.0.8}/examples/nmake/transpose4x4-opt.py +0 -0
  215. {pynerva-0.0.6 → pynerva-0.0.8}/examples/nmake/transpose4x4-ref.cpp +0 -0
  216. {pynerva-0.0.6 → pynerva-0.0.8}/examples/test_high_register_strategies.py +0 -0
  217. {pynerva-0.0.6 → pynerva-0.0.8}/examples/test_register_constraints.py +0 -0
  218. {pynerva-0.0.6 → pynerva-0.0.8}/examples/test_simple_strategies.py +0 -0
  219. {pynerva-0.0.6 → pynerva-0.0.8}/logo/college-of-computing.gif +0 -0
  220. {pynerva-0.0.6 → pynerva-0.0.8}/logo/hpcgarage.png +0 -0
  221. {pynerva-0.0.6 → pynerva-0.0.8}/logo/peachpy.png +0 -0
  222. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/__init__.py +0 -0
  223. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/abi.py +0 -0
  224. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/arm/__main__.py +0 -0
  225. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/arm/abi.py +0 -0
  226. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/arm/formats.py +0 -0
  227. {pynerva-0.0.6 → pynerva-0.0.8}/nervapy/arm/instructions.py +0 -0
  228. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/arm/isa.py +0 -0
  229. {pynerva-0.0.6 → pynerva-0.0.8}/nervapy/arm/literal_pool.py +0 -0
  230. {pynerva-0.0.6 → pynerva-0.0.8}/nervapy/arm/microarchitecture.py +0 -0
  231. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/arm/pseudo.py +0 -0
  232. {pynerva-0.0.6 → pynerva-0.0.8}/nervapy/arm/registers.py +0 -0
  233. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/arm/vfpneon.py +0 -0
  234. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/arm.py +0 -0
  235. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/c/__init__.py +0 -0
  236. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/c/types.py +0 -0
  237. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/codegen.py +0 -0
  238. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/common/__init__.py +0 -0
  239. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/common/function.py +0 -0
  240. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/common/regalloc.py +0 -0
  241. {pynerva-0.0.6 → pynerva-0.0.8}/nervapy/constant_data.py +0 -0
  242. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/encoder.py +0 -0
  243. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/__init__.py +0 -0
  244. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/elf/__init__.py +0 -0
  245. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/elf/file.py +0 -0
  246. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/elf/image.py +0 -0
  247. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/elf/section.py +0 -0
  248. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/elf/symbol.py +0 -0
  249. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/macho/__init__.py +0 -0
  250. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/macho/file.py +0 -0
  251. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/macho/image.py +0 -0
  252. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/macho/section.py +0 -0
  253. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/macho/symbol.py +0 -0
  254. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/mscoff/__init__.py +0 -0
  255. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/mscoff/image.py +0 -0
  256. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/mscoff/section.py +0 -0
  257. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/formats/mscoff/symbol.py +0 -0
  258. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/function.py +0 -0
  259. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/literal.py +0 -0
  260. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/loader.py +0 -0
  261. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/name.py +0 -0
  262. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/parse.py +0 -0
  263. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/stream.py +0 -0
  264. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/util.py +0 -0
  265. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/writer.py +0 -0
  266. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/__init__.py +0 -0
  267. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/__main__.py +0 -0
  268. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/abi.py +0 -0
  269. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/amd.py +0 -0
  270. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/avx.py +0 -0
  271. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/crypto.py +0 -0
  272. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/encoding.py +0 -0
  273. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/fma.py +0 -0
  274. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/function.py +0 -0
  275. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/generic.py +0 -0
  276. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/instructions.py +0 -0
  277. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/isa.py +0 -0
  278. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/lower.py +0 -0
  279. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/mask.py +0 -0
  280. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/meta.py +0 -0
  281. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/mmxsse.py +0 -0
  282. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/nacl.py +0 -0
  283. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/operand.py +0 -0
  284. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/options.py +0 -0
  285. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/pseudo.py +0 -0
  286. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/registers.py +0 -0
  287. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/types.py +0 -0
  288. {pynerva-0.0.6/build/lib → pynerva-0.0.8}/nervapy/x86_64/uarch.py +0 -0
  289. {pynerva-0.0.6 → pynerva-0.0.8}/pytest.ini +0 -0
  290. {pynerva-0.0.6 → pynerva-0.0.8}/requirements.txt +0 -0
  291. {pynerva-0.0.6 → pynerva-0.0.8}/sphinx/conf.py +0 -0
  292. {pynerva-0.0.6 → pynerva-0.0.8}/sphinx/index.rst +0 -0
  293. {pynerva-0.0.6 → pynerva-0.0.8}/sphinx/nervapy.rst +0 -0
  294. {pynerva-0.0.6 → pynerva-0.0.8}/tests/__init__.py +0 -0
  295. {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_and_w_eor_w.py +0 -0
  296. {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_arm.py +0 -0
  297. {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_armv7m.py +0 -0
  298. {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_armv7m_registers.py +0 -0
  299. {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_barrel_shifter.py +0 -0
  300. {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_cortex_m33_fpu.py +0 -0
  301. {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_dead_register_allocation.py +0 -0
  302. {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_helium_phase1.py +0 -0
  303. {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_live_registers.py +0 -0
  304. {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_mov_w_32bit.py +0 -0
  305. {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_movw_32bit.py +0 -0
  306. {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_multiply_instructions.py +0 -0
  307. {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_preserve8.py +0 -0
  308. {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_register_count.py +0 -0
  309. {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_register_overflow.py +0 -0
  310. {pynerva-0.0.6 → pynerva-0.0.8}/tests/arm/test_stack_alignment.py +0 -0
  311. {pynerva-0.0.6 → pynerva-0.0.8}/tests/requirements.txt +0 -0
  312. {pynerva-0.0.6 → pynerva-0.0.8}/tests/test_elf.py +0 -0
  313. {pynerva-0.0.6 → pynerva-0.0.8}/tests/test_literal.py +0 -0
  314. {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/__init__.py +0 -0
  315. {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/encoding/__init__.py +0 -0
  316. {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/encoding/test_amd.py +0 -0
  317. {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/encoding/test_avx.py +0 -0
  318. {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/encoding/test_crypto.py +0 -0
  319. {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/encoding/test_fma.py +0 -0
  320. {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/encoding/test_generic.py +0 -0
  321. {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/encoding/test_imm.py +0 -0
  322. {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/encoding/test_mask.py +0 -0
  323. {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/encoding/test_mmxsse.py +0 -0
  324. {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/test_analysis.py +0 -0
  325. {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/test_function.py +0 -0
  326. {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/test_golang.py +0 -0
  327. {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/test_labels.py +0 -0
  328. {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/test_load.py +0 -0
  329. {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/test_register_allocation.py +0 -0
  330. {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/test_register_constraints.py +0 -0
  331. {pynerva-0.0.6 → pynerva-0.0.8}/tests/x86_64/test_relocation.py +0 -0
  332. {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.8", "3.9", "3.10", "3.11", "3.12" ]
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.8', '3.9', '3.10', '3.11', '3.12']
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.6
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.8
30
+ Requires-Python: >=3.10
31
31
  Requires-Dist: click>=8.1.8
32
- Requires-Dist: requests>=2.32.4
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
- Two integration methods are shown:
11
-
12
- Option A - Separate .s file compiled via build.rs:
13
-
14
- // build.rs
15
- fn main() {
16
- cc::Build::new()
17
- .file("src/kernels.s")
18
- .compile("kernels");
19
- }
20
-
21
- // Cargo.toml
22
- [build-dependencies]
23
- cc = "1"
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!() file (Option B)."""
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.global_asm)
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
- out_dir = os.path.join(os.path.dirname(__file__), "rust_output")
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(asm=gas)
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.6"
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.8"
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.32.4"]
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 test_global_asm_matches_gas_assembly(self):
460
- """global_asm content is identical to function.assembly."""
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)