cimo 0.0.2__tar.gz → 0.0.3__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 (401) hide show
  1. cimo-0.0.3/LICENSE +21 -0
  2. {cimo-0.0.2 → cimo-0.0.3}/PKG-INFO +5 -3
  3. cimo-0.0.3/README.md +8 -0
  4. {cimo-0.0.2 → cimo-0.0.3}/cimo/__init__.py +1 -1
  5. {cimo-0.0.2 → cimo-0.0.3}/cimo/assembler.py +7 -2
  6. {cimo-0.0.2 → cimo-0.0.3}/cimo/assembler_amd64.py +42 -0
  7. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/amd64/emit.py +179 -5
  8. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/amd64/isel.py +130 -5
  9. cimo-0.0.3/cimo/backend/amd64/qlower.py +152 -0
  10. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/amd64/targ.py +4 -0
  11. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/arm64/emit.py +5 -0
  12. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/defs.py +10 -0
  13. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/ext.py +1 -1
  14. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/gcm.py +68 -28
  15. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/main.py +12 -0
  16. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/parse.py +1 -1
  17. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/rega.py +4 -1
  18. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/thread.py +2 -0
  19. {cimo-0.0.2 → cimo-0.0.3}/cimo/driver.py +20 -3
  20. {cimo-0.0.2 → cimo-0.0.3}/cimo/frontend/decl.py +1 -1
  21. {cimo-0.0.2 → cimo-0.0.3}/cimo/frontend/expr.py +7 -0
  22. {cimo-0.0.2 → cimo-0.0.3}/cimo/frontend/qbe.py +36 -1
  23. cimo-0.0.3/cimo/introspect.py +36 -0
  24. {cimo-0.0.2 → cimo-0.0.3}/cimo/middle/ifconv.py +3 -1
  25. {cimo-0.0.2 → cimo-0.0.3}/cimo/middle/inner.py +17 -5
  26. {cimo-0.0.2 → cimo-0.0.3}/cimo/middle/vectorize.py +228 -7
  27. {cimo-0.0.2 → cimo-0.0.3}/cimo/wasm/pyodide.py +8 -1
  28. {cimo-0.0.2 → cimo-0.0.3}/cimo.egg-info/PKG-INFO +5 -3
  29. {cimo-0.0.2 → cimo-0.0.3}/cimo.egg-info/SOURCES.txt +6 -0
  30. {cimo-0.0.2 → cimo-0.0.3}/pyproject.toml +1 -1
  31. cimo-0.0.3/tests/test_gcm_order.py +37 -0
  32. cimo-0.0.3/tests/test_introspect.py +55 -0
  33. {cimo-0.0.2 → cimo-0.0.3}/tests/test_middle_random.py +32 -2
  34. {cimo-0.0.2 → cimo-0.0.3}/tests/test_regressions.py +15 -0
  35. {cimo-0.0.2 → cimo-0.0.3}/tests/test_runtime.py +1 -1
  36. cimo-0.0.3/tests/test_thread_loops.py +35 -0
  37. {cimo-0.0.2 → cimo-0.0.3}/tests/test_vector.py +50 -6
  38. cimo-0.0.3/tests/test_vectorize.py +459 -0
  39. cimo-0.0.2/README.md +0 -8
  40. cimo-0.0.2/tests/test_vectorize.py +0 -207
  41. {cimo-0.0.2 → cimo-0.0.3}/cimo/__main__.py +0 -0
  42. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/LICENSE +0 -0
  43. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/PORTING.md +0 -0
  44. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/__init__.py +0 -0
  45. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/__main__.py +0 -0
  46. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/abi.py +0 -0
  47. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/alias.py +0 -0
  48. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/amd64/__init__.py +0 -0
  49. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/amd64/regs.py +0 -0
  50. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/amd64/sysv.py +0 -0
  51. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/amd64/winabi.py +0 -0
  52. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/arm64/__init__.py +0 -0
  53. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/arm64/abi.py +0 -0
  54. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/arm64/isel.py +0 -0
  55. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/arm64/pair.py +0 -0
  56. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/arm64/regs.py +0 -0
  57. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/arm64/targ.py +0 -0
  58. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/cfg.py +0 -0
  59. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/copy.py +0 -0
  60. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/cse.py +0 -0
  61. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/emit.py +0 -0
  62. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/fold.py +0 -0
  63. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/gvn.py +0 -0
  64. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/ifopt.py +0 -0
  65. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/inline.py +0 -0
  66. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/live.py +0 -0
  67. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/load.py +0 -0
  68. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/mem.py +0 -0
  69. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/memopt.py +0 -0
  70. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/nowrap.py +0 -0
  71. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/scalar.py +0 -0
  72. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/simpl.py +0 -0
  73. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/simplify.py +0 -0
  74. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/spill.py +0 -0
  75. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/sroa.py +0 -0
  76. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/ssa.py +0 -0
  77. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/util.py +0 -0
  78. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/wasm/__init__.py +0 -0
  79. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/wasm/emit.py +0 -0
  80. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/wasm/obj.py +0 -0
  81. {cimo-0.0.2 → cimo-0.0.3}/cimo/backend/wasm/targ.py +0 -0
  82. {cimo-0.0.2 → cimo-0.0.3}/cimo/cli/__init__.py +0 -0
  83. {cimo-0.0.2 → cimo-0.0.3}/cimo/cli/commands.py +0 -0
  84. {cimo-0.0.2 → cimo-0.0.3}/cimo/cli/completion.py +0 -0
  85. {cimo-0.0.2 → cimo-0.0.3}/cimo/cli/parse.py +0 -0
  86. {cimo-0.0.2 → cimo-0.0.3}/cimo/cli/report.py +0 -0
  87. {cimo-0.0.2 → cimo-0.0.3}/cimo/cli/term.py +0 -0
  88. {cimo-0.0.2 → cimo-0.0.3}/cimo/execution.py +0 -0
  89. {cimo-0.0.2 → cimo-0.0.3}/cimo/frontend/LICENSE +0 -0
  90. {cimo-0.0.2 → cimo-0.0.3}/cimo/frontend/PORTING.md +0 -0
  91. {cimo-0.0.2 → cimo-0.0.3}/cimo/frontend/__init__.py +0 -0
  92. {cimo-0.0.2 → cimo-0.0.3}/cimo/frontend/__main__.py +0 -0
  93. {cimo-0.0.2 → cimo-0.0.3}/cimo/frontend/attr.py +0 -0
  94. {cimo-0.0.2 → cimo-0.0.3}/cimo/frontend/cc.py +0 -0
  95. {cimo-0.0.2 → cimo-0.0.3}/cimo/frontend/diag.py +0 -0
  96. {cimo-0.0.2 → cimo-0.0.3}/cimo/frontend/eval.py +0 -0
  97. {cimo-0.0.2 → cimo-0.0.3}/cimo/frontend/init.py +0 -0
  98. {cimo-0.0.2 → cimo-0.0.3}/cimo/frontend/main.py +0 -0
  99. {cimo-0.0.2 → cimo-0.0.3}/cimo/frontend/map.py +0 -0
  100. {cimo-0.0.2 → cimo-0.0.3}/cimo/frontend/pp.py +0 -0
  101. {cimo-0.0.2 → cimo-0.0.3}/cimo/frontend/prune.py +0 -0
  102. {cimo-0.0.2 → cimo-0.0.3}/cimo/frontend/scan.py +0 -0
  103. {cimo-0.0.2 → cimo-0.0.3}/cimo/frontend/scope.py +0 -0
  104. {cimo-0.0.2 → cimo-0.0.3}/cimo/frontend/stmt.py +0 -0
  105. {cimo-0.0.2 → cimo-0.0.3}/cimo/frontend/targ.py +0 -0
  106. {cimo-0.0.2 → cimo-0.0.3}/cimo/frontend/token.py +0 -0
  107. {cimo-0.0.2 → cimo-0.0.3}/cimo/frontend/tree.py +0 -0
  108. {cimo-0.0.2 → cimo-0.0.3}/cimo/frontend/type.py +0 -0
  109. {cimo-0.0.2 → cimo-0.0.3}/cimo/frontend/utf.py +0 -0
  110. {cimo-0.0.2 → cimo-0.0.3}/cimo/frontend/util.py +0 -0
  111. {cimo-0.0.2 → cimo-0.0.3}/cimo/include/assert.h +0 -0
  112. {cimo-0.0.2 → cimo-0.0.3}/cimo/include/ctype.h +0 -0
  113. {cimo-0.0.2 → cimo-0.0.3}/cimo/include/float.h +0 -0
  114. {cimo-0.0.2 → cimo-0.0.3}/cimo/include/inttypes.h +0 -0
  115. {cimo-0.0.2 → cimo-0.0.3}/cimo/include/iso646.h +0 -0
  116. {cimo-0.0.2 → cimo-0.0.3}/cimo/include/limits.h +0 -0
  117. {cimo-0.0.2 → cimo-0.0.3}/cimo/include/math.h +0 -0
  118. {cimo-0.0.2 → cimo-0.0.3}/cimo/include/stdalign.h +0 -0
  119. {cimo-0.0.2 → cimo-0.0.3}/cimo/include/stdarg.h +0 -0
  120. {cimo-0.0.2 → cimo-0.0.3}/cimo/include/stdbool.h +0 -0
  121. {cimo-0.0.2 → cimo-0.0.3}/cimo/include/stddef.h +0 -0
  122. {cimo-0.0.2 → cimo-0.0.3}/cimo/include/stdint.h +0 -0
  123. {cimo-0.0.2 → cimo-0.0.3}/cimo/include/stdio.h +0 -0
  124. {cimo-0.0.2 → cimo-0.0.3}/cimo/include/stdlib.h +0 -0
  125. {cimo-0.0.2 → cimo-0.0.3}/cimo/include/stdnoreturn.h +0 -0
  126. {cimo-0.0.2 → cimo-0.0.3}/cimo/include/string.h +0 -0
  127. {cimo-0.0.2 → cimo-0.0.3}/cimo/linker.py +0 -0
  128. {cimo-0.0.2 → cimo-0.0.3}/cimo/loader.py +0 -0
  129. {cimo-0.0.2 → cimo-0.0.3}/cimo/middle/__init__.py +0 -0
  130. {cimo-0.0.2 → cimo-0.0.3}/cimo/middle/affine.py +0 -0
  131. {cimo-0.0.2 → cimo-0.0.3}/cimo/middle/ir.py +0 -0
  132. {cimo-0.0.2 → cimo-0.0.3}/cimo/middle/jam.py +0 -0
  133. {cimo-0.0.2 → cimo-0.0.3}/cimo/middle/loops.py +0 -0
  134. {cimo-0.0.2 → cimo-0.0.3}/cimo/middle/memdep.py +0 -0
  135. {cimo-0.0.2 → cimo-0.0.3}/cimo/middle/pipeline.py +0 -0
  136. {cimo-0.0.2 → cimo-0.0.3}/cimo/middle/unswitch.py +0 -0
  137. {cimo-0.0.2 → cimo-0.0.3}/cimo/onefile.py +0 -0
  138. {cimo-0.0.2 → cimo-0.0.3}/cimo/preprocessor.py +0 -0
  139. {cimo-0.0.2 → cimo-0.0.3}/cimo/py.typed +0 -0
  140. {cimo-0.0.2 → cimo-0.0.3}/cimo/resources.py +0 -0
  141. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/COPYRIGHT +0 -0
  142. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/abort.c +0 -0
  143. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/builtins.c +0 -0
  144. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/ctype/ctype.c +0 -0
  145. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/heap.c +0 -0
  146. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/internal/endian.h +0 -0
  147. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/internal/errno.h +0 -0
  148. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/internal/exp2f_data.h +0 -0
  149. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/internal/exp_data.h +0 -0
  150. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/internal/fenv.h +0 -0
  151. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/internal/floatscan.h +0 -0
  152. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/internal/intscan.h +0 -0
  153. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/internal/libm.h +0 -0
  154. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/internal/log2_data.h +0 -0
  155. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/internal/log2f_data.h +0 -0
  156. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/internal/log_data.h +0 -0
  157. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/internal/logf_data.h +0 -0
  158. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/internal/musl.h +0 -0
  159. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/internal/pow_data.h +0 -0
  160. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/internal/powf_data.h +0 -0
  161. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/internal/shgetc.h +0 -0
  162. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/internal/softfma.h +0 -0
  163. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/internal/sqrt_data.h +0 -0
  164. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/internal/stdio_impl.h +0 -0
  165. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/internal/string.h +0 -0
  166. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/__cos.c +0 -0
  167. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/__cosdf.c +0 -0
  168. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/__expo2.c +0 -0
  169. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/__expo2f.c +0 -0
  170. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/__math_divzero.c +0 -0
  171. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/__math_divzerof.c +0 -0
  172. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/__math_invalid.c +0 -0
  173. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/__math_invalidf.c +0 -0
  174. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/__math_oflow.c +0 -0
  175. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/__math_oflowf.c +0 -0
  176. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/__math_uflow.c +0 -0
  177. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/__math_uflowf.c +0 -0
  178. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/__math_xflow.c +0 -0
  179. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/__math_xflowf.c +0 -0
  180. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/__rem_pio2.c +0 -0
  181. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/__rem_pio2_large.c +0 -0
  182. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/__rem_pio2f.c +0 -0
  183. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/__sin.c +0 -0
  184. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/__sindf.c +0 -0
  185. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/__tan.c +0 -0
  186. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/__tandf.c +0 -0
  187. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/acos.c +0 -0
  188. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/acosf.c +0 -0
  189. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/acosh.c +0 -0
  190. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/acoshf.c +0 -0
  191. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/asin.c +0 -0
  192. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/asinf.c +0 -0
  193. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/asinh.c +0 -0
  194. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/asinhf.c +0 -0
  195. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/atan.c +0 -0
  196. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/atan2.c +0 -0
  197. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/atan2f.c +0 -0
  198. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/atanf.c +0 -0
  199. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/atanh.c +0 -0
  200. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/atanhf.c +0 -0
  201. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/cbrt.c +0 -0
  202. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/cbrtf.c +0 -0
  203. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/ceil.c +0 -0
  204. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/ceilf.c +0 -0
  205. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/copysign.c +0 -0
  206. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/copysignf.c +0 -0
  207. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/cos.c +0 -0
  208. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/cosf.c +0 -0
  209. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/cosh.c +0 -0
  210. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/coshf.c +0 -0
  211. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/erf.c +0 -0
  212. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/erff.c +0 -0
  213. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/exp.c +0 -0
  214. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/exp2.c +0 -0
  215. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/exp2f.c +0 -0
  216. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/exp2f_data.c +0 -0
  217. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/exp_data.c +0 -0
  218. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/expf.c +0 -0
  219. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/expm1.c +0 -0
  220. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/expm1f.c +0 -0
  221. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/fabs.c +0 -0
  222. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/fabsf.c +0 -0
  223. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/fdim.c +0 -0
  224. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/fdimf.c +0 -0
  225. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/floor.c +0 -0
  226. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/floorf.c +0 -0
  227. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/fma.c +0 -0
  228. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/fmaf.c +0 -0
  229. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/fmax.c +0 -0
  230. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/fmaxf.c +0 -0
  231. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/fmin.c +0 -0
  232. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/fminf.c +0 -0
  233. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/fmod.c +0 -0
  234. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/fmodf.c +0 -0
  235. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/frexp.c +0 -0
  236. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/frexpf.c +0 -0
  237. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/hypot.c +0 -0
  238. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/hypotf.c +0 -0
  239. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/ilogb.c +0 -0
  240. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/ilogbf.c +0 -0
  241. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/ldexp.c +0 -0
  242. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/ldexpf.c +0 -0
  243. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/lgamma.c +0 -0
  244. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/lgamma_r.c +0 -0
  245. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/lgammaf.c +0 -0
  246. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/lgammaf_r.c +0 -0
  247. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/llrint.c +0 -0
  248. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/llrintf.c +0 -0
  249. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/llround.c +0 -0
  250. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/llroundf.c +0 -0
  251. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/log.c +0 -0
  252. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/log10.c +0 -0
  253. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/log10f.c +0 -0
  254. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/log1p.c +0 -0
  255. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/log1pf.c +0 -0
  256. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/log2.c +0 -0
  257. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/log2_data.c +0 -0
  258. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/log2f.c +0 -0
  259. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/log2f_data.c +0 -0
  260. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/log_data.c +0 -0
  261. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/logb.c +0 -0
  262. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/logbf.c +0 -0
  263. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/logf.c +0 -0
  264. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/logf_data.c +0 -0
  265. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/lrint.c +0 -0
  266. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/lrintf.c +0 -0
  267. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/lround.c +0 -0
  268. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/lroundf.c +0 -0
  269. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/modf.c +0 -0
  270. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/modff.c +0 -0
  271. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/nan.c +0 -0
  272. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/nanf.c +0 -0
  273. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/nearbyint.c +0 -0
  274. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/nearbyintf.c +0 -0
  275. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/nextafter.c +0 -0
  276. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/nextafterf.c +0 -0
  277. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/pow.c +0 -0
  278. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/pow_data.c +0 -0
  279. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/powf.c +0 -0
  280. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/powf_data.c +0 -0
  281. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/remainder.c +0 -0
  282. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/remainderf.c +0 -0
  283. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/remquo.c +0 -0
  284. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/remquof.c +0 -0
  285. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/rint.c +0 -0
  286. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/rintf.c +0 -0
  287. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/round.c +0 -0
  288. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/roundf.c +0 -0
  289. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/scalbln.c +0 -0
  290. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/scalblnf.c +0 -0
  291. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/scalbn.c +0 -0
  292. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/scalbnf.c +0 -0
  293. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/signgam.c +0 -0
  294. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/sin.c +0 -0
  295. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/sinf.c +0 -0
  296. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/sinh.c +0 -0
  297. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/sinhf.c +0 -0
  298. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/sqrt.c +0 -0
  299. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/sqrtf.c +0 -0
  300. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/tan.c +0 -0
  301. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/tanf.c +0 -0
  302. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/tanh.c +0 -0
  303. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/tanhf.c +0 -0
  304. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/tgamma.c +0 -0
  305. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/tgammaf.c +0 -0
  306. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/trunc.c +0 -0
  307. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/math/truncf.c +0 -0
  308. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/stdio/snprintf.c +0 -0
  309. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/stdio/stdout.c +0 -0
  310. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/stdio/vfprintf.c +0 -0
  311. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/stdlib/abs.c +0 -0
  312. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/stdlib/atof.c +0 -0
  313. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/stdlib/atoi.c +0 -0
  314. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/stdlib/atol.c +0 -0
  315. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/stdlib/atoll.c +0 -0
  316. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/stdlib/bsearch.c +0 -0
  317. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/stdlib/div.c +0 -0
  318. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/stdlib/floatscan.c +0 -0
  319. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/stdlib/intscan.c +0 -0
  320. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/stdlib/inttypes.c +0 -0
  321. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/stdlib/labs.c +0 -0
  322. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/stdlib/ldiv.c +0 -0
  323. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/stdlib/llabs.c +0 -0
  324. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/stdlib/lldiv.c +0 -0
  325. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/stdlib/qsort.c +0 -0
  326. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/stdlib/qsort_nr.c +0 -0
  327. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/stdlib/rand.c +0 -0
  328. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/stdlib/strtod.c +0 -0
  329. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/stdlib/strtol.c +0 -0
  330. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/memchr.c +0 -0
  331. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/memcmp.c +0 -0
  332. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/memcpy.c +0 -0
  333. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/memmove.c +0 -0
  334. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/memrchr.c +0 -0
  335. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/memset.c +0 -0
  336. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/stpcpy.c +0 -0
  337. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/stpncpy.c +0 -0
  338. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/strcat.c +0 -0
  339. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/strchr.c +0 -0
  340. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/strchrnul.c +0 -0
  341. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/strcmp.c +0 -0
  342. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/strcoll.c +0 -0
  343. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/strcpy.c +0 -0
  344. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/strcspn.c +0 -0
  345. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/strdup.c +0 -0
  346. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/strerror.c +0 -0
  347. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/strlen.c +0 -0
  348. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/strncat.c +0 -0
  349. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/strncmp.c +0 -0
  350. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/strncpy.c +0 -0
  351. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/strndup.c +0 -0
  352. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/strnlen.c +0 -0
  353. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/strpbrk.c +0 -0
  354. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/strrchr.c +0 -0
  355. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/strspn.c +0 -0
  356. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/strstr.c +0 -0
  357. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/strtok.c +0 -0
  358. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/string/strxfrm.c +0 -0
  359. {cimo-0.0.2 → cimo-0.0.3}/cimo/runtime/symbols.txt +0 -0
  360. {cimo-0.0.2 → cimo-0.0.3}/cimo/wasm/__init__.py +0 -0
  361. {cimo-0.0.2 → cimo-0.0.3}/cimo/wasm/link.py +0 -0
  362. {cimo-0.0.2 → cimo-0.0.3}/cimo/wasm/runtime/fma.c +0 -0
  363. {cimo-0.0.2 → cimo-0.0.3}/cimo.egg-info/dependency_links.txt +0 -0
  364. {cimo-0.0.2 → cimo-0.0.3}/cimo.egg-info/entry_points.txt +0 -0
  365. {cimo-0.0.2 → cimo-0.0.3}/cimo.egg-info/requires.txt +0 -0
  366. {cimo-0.0.2 → cimo-0.0.3}/cimo.egg-info/top_level.txt +0 -0
  367. {cimo-0.0.2 → cimo-0.0.3}/setup.cfg +0 -0
  368. {cimo-0.0.2 → cimo-0.0.3}/tests/test_abi.py +0 -0
  369. {cimo-0.0.2 → cimo-0.0.3}/tests/test_amd64_fixes.py +0 -0
  370. {cimo-0.0.2 → cimo-0.0.3}/tests/test_assembler.py +0 -0
  371. {cimo-0.0.2 → cimo-0.0.3}/tests/test_assembler_amd64.py +0 -0
  372. {cimo-0.0.2 → cimo-0.0.3}/tests/test_backend_edges.py +0 -0
  373. {cimo-0.0.2 → cimo-0.0.3}/tests/test_backend_fold.py +0 -0
  374. {cimo-0.0.2 → cimo-0.0.3}/tests/test_bench_gate.py +0 -0
  375. {cimo-0.0.2 → cimo-0.0.3}/tests/test_cli.py +0 -0
  376. {cimo-0.0.2 → cimo-0.0.3}/tests/test_constraints.py +0 -0
  377. {cimo-0.0.2 → cimo-0.0.3}/tests/test_corpora.py +0 -0
  378. {cimo-0.0.2 → cimo-0.0.3}/tests/test_cse.py +0 -0
  379. {cimo-0.0.2 → cimo-0.0.3}/tests/test_diagnostics.py +0 -0
  380. {cimo-0.0.2 → cimo-0.0.3}/tests/test_execution.py +0 -0
  381. {cimo-0.0.2 → cimo-0.0.3}/tests/test_ext_kernels.py +0 -0
  382. {cimo-0.0.2 → cimo-0.0.3}/tests/test_fma.py +0 -0
  383. {cimo-0.0.2 → cimo-0.0.3}/tests/test_frontend.py +0 -0
  384. {cimo-0.0.2 → cimo-0.0.3}/tests/test_inline.py +0 -0
  385. {cimo-0.0.2 → cimo-0.0.3}/tests/test_isel.py +0 -0
  386. {cimo-0.0.2 → cimo-0.0.3}/tests/test_ldp_layout.py +0 -0
  387. {cimo-0.0.2 → cimo-0.0.3}/tests/test_loader.py +0 -0
  388. {cimo-0.0.2 → cimo-0.0.3}/tests/test_loader_amd64.py +0 -0
  389. {cimo-0.0.2 → cimo-0.0.3}/tests/test_m2.py +0 -0
  390. {cimo-0.0.2 → cimo-0.0.3}/tests/test_macos.py +0 -0
  391. {cimo-0.0.2 → cimo-0.0.3}/tests/test_middle.py +0 -0
  392. {cimo-0.0.2 → cimo-0.0.3}/tests/test_nowrap.py +0 -0
  393. {cimo-0.0.2 → cimo-0.0.3}/tests/test_onefile.py +0 -0
  394. {cimo-0.0.2 → cimo-0.0.3}/tests/test_passes_matter.py +0 -0
  395. {cimo-0.0.2 → cimo-0.0.3}/tests/test_preprocessor.py +0 -0
  396. {cimo-0.0.2 → cimo-0.0.3}/tests/test_semantics.py +0 -0
  397. {cimo-0.0.2 → cimo-0.0.3}/tests/test_simplify.py +0 -0
  398. {cimo-0.0.2 → cimo-0.0.3}/tests/test_site.py +0 -0
  399. {cimo-0.0.2 → cimo-0.0.3}/tests/test_typing.py +0 -0
  400. {cimo-0.0.2 → cimo-0.0.3}/tests/test_wasm.py +0 -0
  401. {cimo-0.0.2 → cimo-0.0.3}/tests/test_windows.py +0 -0
cimo-0.0.3/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Fariz Rahman
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cimo
3
- Version: 0.0.2
3
+ Version: 0.0.3
4
4
  Summary: A C compiler written in pure Python: C kernels in, machine code out.
5
5
  Author: Fariz Rahman
6
6
  License: MIT
@@ -11,17 +11,19 @@ Classifier: Topic :: Software Development :: Compilers
11
11
  Classifier: License :: OSI Approved :: MIT License
12
12
  Requires-Python: >=3.9
13
13
  Description-Content-Type: text/markdown
14
+ License-File: LICENSE
14
15
  Provides-Extra: dev
15
16
  Requires-Dist: pytest; extra == "dev"
16
17
  Requires-Dist: black; extra == "dev"
17
18
  Requires-Dist: isort; extra == "dev"
18
19
  Requires-Dist: numpy; extra == "dev"
19
20
  Requires-Dist: mypy; extra == "dev"
21
+ Dynamic: license-file
20
22
 
21
23
  # cimo
22
24
 
23
- A C compiler written in pure Python: compile freestanding C kernels at runtime and call them on
24
- your numpy arrays, with no compiler, SDK or native dependency on the machine.
25
+ A C compiler written in pure Python: compile C kernels at runtime and call them on your numpy
26
+ arrays, with no compiler, SDK or native dependency on the machine.
25
27
 
26
28
  See the [project README](https://github.com/farizrahman4u/cimo#readme).
27
29
 
cimo-0.0.3/README.md ADDED
@@ -0,0 +1,8 @@
1
+ # cimo
2
+
3
+ A C compiler written in pure Python: compile C kernels at runtime and call them on your numpy
4
+ arrays, with no compiler, SDK or native dependency on the machine.
5
+
6
+ See the [project README](https://github.com/farizrahman4u/cimo#readme).
7
+
8
+ Development install, from this directory: `pip install -e '.[dev]'`
@@ -2,4 +2,4 @@
2
2
 
3
3
  from .driver import compile, load, Module, CompileError, KernelError
4
4
 
5
- __version__ = "0.0.2"
5
+ __version__ = "0.0.3"
@@ -935,7 +935,8 @@ _NEON2 = {'neg': (0x6e20b800, 's'), 'fneg': (0x6ea0f800, 'f'), 'fabs': (0x4ea0f8
935
935
  'mvn': (0x6e205800, '')}
936
936
  _NEONSH = {'shl': 0x4f005400, 'ushr': 0x6f000400, 'sshr': 0x4f000400}
937
937
  _LANES = {'16b': 0, '8h': 1, '4s': 2, '2d': 3}
938
- _VREG = re.compile(r'v(\d+)\.(16b|8h|4s|2d)$')
938
+ _NEONW = {'saddw': 0x0ea01000, 'saddw2': 0x4ea01000, 'uaddw': 0x2ea01000, 'uaddw2': 0x6ea01000} # 2d, 2d, 2s or 4s
939
+ _VREG = re.compile(r'v(\d+)\.(16b|8h|4s|2d|2s)$')
939
940
  _VELEM = re.compile(r'v(\d+)\.([bhsd])\[(\d+)\]$')
940
941
 
941
942
 
@@ -953,10 +954,14 @@ def _v(s):
953
954
  def _neon(mn, ops):
954
955
  """The word of a NEON instruction whose first operand is a vector register."""
955
956
  d, lane = _v(ops[0])
956
- size = _LANES[lane]
957
+ size = _LANES.get(lane, 2)
957
958
  if mn == 'mov':
958
959
  n, _ = _v(ops[1])
959
960
  return 0x4ea01c00 | n << 16 | n << 5 | d
961
+ if mn in _NEONW:
962
+ n, _ = _v(ops[1])
963
+ m, _ = _v(ops[2])
964
+ return _NEONW[mn] | m << 16 | n << 5 | d
960
965
  if mn == 'dup':
961
966
  s = ops[1].strip().lower()
962
967
  e = _VELEM.match(s)
@@ -962,6 +962,36 @@ def _h_round(a, ops, sz, op):
962
962
  imm=(1, None, v, None))
963
963
 
964
964
 
965
+ def _h_sseimm(a, ops, sz, arg):
966
+ """$imm, xmm/mem -> xmm: arg = (mandatory prefix, opcode)."""
967
+ _nops(ops, 3)
968
+ imm, src, dst = ops
969
+ sym, v = _immop(imm, 1)
970
+ if sym is not None:
971
+ raise AssemblerError('expected a constant')
972
+ _enc(a, arg[1], _xmm(dst), _xmm(src, True), 0, mand=arg[0], imm=(1, None, v, None))
973
+
974
+
975
+ def _h_pshift(a, ops, sz, arg):
976
+ """$imm, xmm: arg = (opcode, /digit)."""
977
+ _nops(ops, 2)
978
+ imm, dst = ops
979
+ sym, v = _immop(imm, 1)
980
+ if sym is not None:
981
+ raise AssemblerError('expected a constant')
982
+ _enc(a, bytes([0x0f, arg[0]]), arg[1], _xmm(dst), 0, mand=b'\x66', imm=(1, None, v, None))
983
+
984
+
985
+ def _h_pextrw(a, ops, sz, _):
986
+ _nops(ops, 3)
987
+ imm, src, dst = ops
988
+ sym, v = _immop(imm, 1)
989
+ if sym is not None or src[0] != 'x':
990
+ raise AssemblerError('bad operands')
991
+ _gpr(dst, (4, 8))
992
+ _enc(a, b'\x0f\xc5', dst, src, 0, mand=b'\x66', imm=(1, None, v, None))
993
+
994
+
965
995
  # mnemonic table: name -> (handler, suffix size, argument)
966
996
 
967
997
  _SFX = {'b': 1, 'w': 2, 'l': 4, 'q': 8}
@@ -1054,6 +1084,18 @@ for _n, _p, _op in (('andps', b'', 0x54), ('andpd', b'\x66', 0x54), ('andnps', b
1054
1084
  ('unpcklpd', b'\x66', 0x14), ('cvtps2pd', b'', 0x5a),
1055
1085
  ('cvtpd2ps', b'\x66', 0x5a)):
1056
1086
  _INSNS[_n] = (_h_sse, 0, (_p, bytes([0x0f, _op])))
1087
+ for _n, _op in (('paddb', 0xfc), ('paddw', 0xfd), ('paddd', 0xfe), ('paddq', 0xd4), ('psubb', 0xf8), ('psubw', 0xf9),
1088
+ ('psubd', 0xfa), ('psubq', 0xfb), ('pmullw', 0xd5), ('pmuludq', 0xf4), ('pcmpeqb', 0x74), ('pcmpeqw', 0x75),
1089
+ ('pcmpeqd', 0x76), ('pcmpgtb', 0x64), ('pcmpgtw', 0x65), ('pcmpgtd', 0x66), ('pminub', 0xda), ('pmaxub', 0xde),
1090
+ ('pminsw', 0xea), ('pmaxsw', 0xee), ('pandn', 0xdf), ('punpcklbw', 0x60), ('punpcklwd', 0x61),
1091
+ ('punpckldq', 0x62), ('punpckhdq', 0x6a), ('punpcklqdq', 0x6c)):
1092
+ _INSNS[_n] = (_h_sse, 0, (b'\x66', bytes([0x0f, _op])))
1093
+ for _n, _p, _o in (('pshufd', b'\x66', 0x70), ('pshuflw', b'\xf2', 0x70), ('cmpps', b'', 0xc2), ('cmppd', b'\x66', 0xc2)):
1094
+ _INSNS[_n] = (_h_sseimm, 0, (_p, bytes([0x0f, _o])))
1095
+ for _n, _op, _d in (('psllw', 0x71, 6), ('pslld', 0x72, 6), ('psllq', 0x73, 6), ('psrlw', 0x71, 2), ('psrld', 0x72, 2),
1096
+ ('psrlq', 0x73, 2), ('psraw', 0x71, 4), ('psrad', 0x72, 4)):
1097
+ _INSNS[_n] = (_h_pshift, 0, (_op, _d))
1098
+ _INSNS['pextrw'] = (_h_pextrw, 0, None)
1057
1099
  for _n, _p, _ld, _st in (('movss', b'\xf3', 0x10, 0x11), ('movsd', b'\xf2', 0x10, 0x11),
1058
1100
  ('movups', b'', 0x10, 0x11), ('movupd', b'\x66', 0x10, 0x11),
1059
1101
  ('movaps', b'', 0x28, 0x29), ('movapd', b'\x66', 0x28, 0x29),
@@ -141,6 +141,11 @@ omap = [
141
141
  (Oxcmp, Kd, "ucomisd %D0, %D1"),
142
142
  (Oxcmp, Ki, "cmp%k %0, %1"),
143
143
  (Oxtest, Ki, "test%k %0, %1"),
144
+ (D.Oxaddm, Ki, "add%k %0, %M1"),
145
+ (D.Oxsubm, Ki, "sub%k %0, %M1"),
146
+ (D.Oxandm, Ki, "and%k %0, %M1"),
147
+ (D.Oxorm, Ki, "or%k %0, %M1"),
148
+ (D.Oxxorm, Ki, "xor%k %0, %M1"),
144
149
  ]
145
150
  omap += [(Oflag + c, Ki, "set" + s + " %B=\n\tmovzb%k %B=, %=") for c, s, _ in _CMP]
146
151
  omap += [
@@ -232,6 +237,19 @@ def getarg(c, i):
232
237
  die("invalid arg letter %c", c)
233
238
 
234
239
 
240
+ _FALSEDEP = frozenset((Ofsqrt, Oswtof, Osltof, Oexts, Otruncd))
241
+
242
+
243
+ def _xreg(r):
244
+ return rtype(r) == RTmp and isreg(r) and rval(r) >= XMM0
245
+
246
+
247
+ def _xcopy(to, a, e):
248
+ """cimo: movss and movsd between registers keep the destination's upper bits, so they wait for what last wrote it,
249
+ which behind a division or a square root is most of the loop (nbody_acc on Intel). movaps doesn't, as gcc and clang."""
250
+ e.f.write("\tmovaps %%xmm%d, %%xmm%d\n" % (rval(a) - XMM0, rval(to) - XMM0))
251
+
252
+
235
253
  def emitcopy(r1, r2, k, e):
236
254
  icp = Ins(Ocopy, k, r1, r2)
237
255
  emitins(icp, e)
@@ -369,11 +387,161 @@ def _table(i, e):
369
387
  die("no match for %s(%c)", optab[i.op].name, "wlsd"[i.cls])
370
388
 
371
389
 
390
+ _QX15 = "%xmm15"
391
+ # (mnemonic, commutes). Two addresses: dest = dest op source
392
+ _QTWO = {'qaddb': ('paddb', 1), 'qaddh': ('paddw', 1), 'qaddw': ('paddd', 1), 'qaddl': ('paddq', 1),
393
+ 'qadds': ('addps', 1), 'qaddd': ('addpd', 1), 'qsubb': ('psubb', 0), 'qsubh': ('psubw', 0),
394
+ 'qsubw': ('psubd', 0), 'qsubl': ('psubq', 0), 'qsubs': ('subps', 0), 'qsubd': ('subpd', 0),
395
+ 'qmulh': ('pmullw', 1), 'qmuls': ('mulps', 1), 'qmuld': ('mulpd', 1), 'qdivs': ('divps', 0), 'qdivd': ('divpd', 0),
396
+ 'qand': ('pand', 1), 'qor': ('por', 1), 'qxor': ('pxor', 1), 'qxandn': ('pandn', 0),
397
+ 'qminh': ('pminsw', 1), 'qmaxh': ('pmaxsw', 1), 'qumin' + 'b': ('pminub', 1), 'qumaxb': ('pmaxub', 1),
398
+ 'qceqb': ('pcmpeqb', 1), 'qceqh': ('pcmpeqw', 1), 'qceqw': ('pcmpeqd', 1),
399
+ 'qcgtb': ('pcmpgtb', 0), 'qcgth': ('pcmpgtw', 0), 'qcgtw': ('pcmpgtd', 0),
400
+ 'qxmuludq': ('pmuludq', 1), 'qxlo': ('punpckldq', 0), 'qxhi': ('punpckhdq', 0),
401
+ 'qxmins': ('minps', 0), 'qxmind': ('minpd', 0), 'qxmaxs': ('maxps', 0), 'qxmaxd': ('maxpd', 0),
402
+ 'qceqs': ('cmpps $0,', 1), 'qceqd': ('cmppd $0,', 1), 'qxunords': ('cmpps $3,', 1), 'qxunordd': ('cmppd $3,', 1)}
403
+ _QSWAPPED = {'qcgts': 'cmpps $1,', 'qcgtd': 'cmppd $1,', 'qcges': 'cmpps $2,', 'qcged': 'cmppd $2,'} # b < a, b <= a
404
+ _QSHIFT = {'qshlh': 'psllw', 'qshlw': 'pslld', 'qshll': 'psllq', 'qshrh': 'psrlw', 'qshrw': 'psrld', 'qshrl': 'psrlq',
405
+ 'qsarh': 'psraw', 'qsarw': 'psrad'}
406
+
407
+
408
+ def _qx(r):
409
+ return "%%xmm%d" % (rval(r) - XMM0)
410
+
411
+
412
+ def _qr(r, sz):
413
+ return "%%%s" % regtoa(rval(r), sz)
414
+
415
+
416
+ def _qtwo(mn, to, a, b, commutes, f):
417
+ """to = a op b, in two addresses, through xmm15 if b is in the way."""
418
+ if to == b and to != a:
419
+ if commutes:
420
+ a, b = b, a
421
+ else:
422
+ f.write("\tmovaps %s, %s\n\tmovaps %s, %s\n" % (_qx(b), _QX15, _qx(a), _qx(to)))
423
+ f.write("\t%s %s, %s\n" % (mn, _QX15, _qx(to)))
424
+ return
425
+ if to != a:
426
+ f.write("\tmovaps %s, %s\n" % (_qx(a), _qx(to)))
427
+ f.write("\t%s %s, %s\n" % (mn, _qx(b), _qx(to)))
428
+
429
+
430
+ def _qcopy(i, e):
431
+ f = e.f
432
+ to, a = i.to, i.arg[0]
433
+ if to == R or a == R or to == a:
434
+ return
435
+ if rtype(to) == RSlot and rtype(a) == RSlot:
436
+ f.write("\tmovups %d(%%%s), %s\n" % (slot(a, e), regtoa(e.fp, SLong), _QX15))
437
+ f.write("\tmovups %s, %d(%%%s)\n" % (_QX15, slot(to, e), regtoa(e.fp, SLong)))
438
+ elif rtype(to) == RSlot:
439
+ emitf("movups %0, %M=", i, e)
440
+ elif rtype(a) == RSlot:
441
+ emitf("movups %M0, %=", i, e)
442
+ else:
443
+ f.write("\tmovaps %s, %s\n" % (_qx(a), _qx(to)))
444
+
445
+
446
+ def _qins(i, e):
447
+ """cimo (ext.vector): one instruction on 128 bits; amd64/qlower.py has left only those SSE2 has. True if it was one."""
448
+ f = e.f
449
+ op = i.op
450
+ if op == Ocopy and i.cls == D.Kq:
451
+ _qcopy(i, e)
452
+ return True
453
+ if op == Oswap and i.cls == D.Kq:
454
+ a, b = _qx(i.arg[0]), _qx(i.arg[1])
455
+ f.write("\tmovaps %s, %s\n\tmovaps %s, %s\n\tmovaps %s, %s\n" % (a, _QX15, b, a, _QX15, b))
456
+ return True
457
+ if (op == Oload and i.cls == D.Kq) or op == D.Oqload:
458
+ emitf("movups %M0, %=", i, e)
459
+ return True
460
+ if op == D.Oqstore:
461
+ emitf("movups %0, %M1", i, e)
462
+ return True
463
+ if not D.isqop(op):
464
+ return False
465
+ name = optab[op].name
466
+ if name in _QTWO:
467
+ mn, commutes = _QTWO[name]
468
+ _qtwo(mn, i.to, i.arg[0], i.arg[1], commutes, f)
469
+ elif name in _QSWAPPED:
470
+ _qtwo(_QSWAPPED[name], i.to, i.arg[1], i.arg[0], 0, f)
471
+ elif name in _QSHIFT:
472
+ if i.to != i.arg[0]:
473
+ f.write("\tmovaps %s, %s\n" % (_qx(i.arg[0]), _qx(i.to)))
474
+ f.write("\t%s $%d, %s\n" % (_QSHIFT[name], e.fn.con[rval(i.arg[1])].i, _qx(i.to)))
475
+ elif name == 'qxshufd':
476
+ f.write("\tpshufd $%d, %s, %s\n" % (e.fn.con[rval(i.arg[1])].i, _qx(i.arg[0]), _qx(i.to)))
477
+ elif name in ('qsqrts', 'qsqrtd'):
478
+ f.write("\tsqrtp%s %s, %s\n" % (name[-1], _qx(i.arg[0]), _qx(i.to)))
479
+ elif name.startswith('qdup'):
480
+ _qdup(name[-1], i, e)
481
+ elif name.startswith('qget'):
482
+ _qget(name[-1], i, e)
483
+ else:
484
+ die("no x86-64 instruction for %s", name)
485
+ return True
486
+
487
+
488
+ def _qdup(x, i, e):
489
+ f = e.f
490
+ to = _qx(i.to)
491
+ a = i.arg[0]
492
+ if rtype(a) == RCon: # isel: 0 and -1 only
493
+ f.write("\t%s %s, %s\n" % ("pxor" if e.fn.con[rval(a)].i == 0 else "pcmpeqd", to, to))
494
+ elif x in 'sd':
495
+ f.write("\tpshufd $%d, %s, %s\n" % (0 if x == 's' else 0x44, _qx(a), to))
496
+ elif x == 'l':
497
+ f.write("\tmovq %s, %s\n\tpunpcklqdq %s, %s\n" % (_qr(a, SLong), to, to, to))
498
+ else:
499
+ f.write("\tmovd %s, %s\n" % (_qr(a, SWord), to))
500
+ if x == 'b':
501
+ f.write("\tpunpcklbw %s, %s\n" % (to, to))
502
+ if x in 'bh':
503
+ f.write("\tpshuflw $0, %s, %s\n" % (to, to))
504
+ f.write("\tpshufd $0, %s, %s\n" % (to, to))
505
+
506
+
507
+ def _qget(x, i, e):
508
+ f = e.f
509
+ n = e.fn.con[rval(i.arg[1])].i
510
+ a = _qx(i.arg[0])
511
+ if x == 's':
512
+ f.write("\tpshufd $%d, %s, %s\n" % (n, a, _qx(i.to)))
513
+ elif x == 'd':
514
+ f.write("\tpshufd $%d, %s, %s\n" % (0xee if n else 0x44, a, _qx(i.to)))
515
+ elif x == 'w':
516
+ if n:
517
+ f.write("\tpshufd $%d, %s, %s\n" % (n, a, _QX15))
518
+ a = _QX15
519
+ f.write("\tmovd %s, %s\n" % (a, _qr(i.to, SWord)))
520
+ elif x == 'l':
521
+ if n:
522
+ f.write("\tpshufd $238, %s, %s\n" % (a, _QX15))
523
+ a = _QX15
524
+ f.write("\tmovq %s, %s\n" % (a, _qr(i.to, SLong)))
525
+ elif x == 'h':
526
+ f.write("\tpextrw $%d, %s, %s\n" % (n, a, _qr(i.to, SWord)))
527
+ else:
528
+ f.write("\tpextrw $%d, %s, %s\n" % (n >> 1, a, _qr(i.to, SWord)))
529
+ if n & 1:
530
+ f.write("\tshrl $8, %s\n" % _qr(i.to, SWord))
531
+ else:
532
+ f.write("\tmovzbl %s, %s\n" % (_qr(i.to, SByte), _qr(i.to, SWord)))
533
+
534
+
372
535
  def emitins(i, e):
373
536
  """i: passed by value (copied here)."""
374
537
  i = i.copy()
375
538
  f = e.f
376
539
  op = i.op
540
+ if (i.cls == D.Kq or D.isqop(op)) and _qins(i, e):
541
+ return
542
+ if op in _FALSEDEP and _xreg(i.to) and i.to != i.arg[0]: # as _xcopy: these keep the upper bits too, as gcc's pxor
543
+ x = rval(i.to) - XMM0
544
+ f.write("\txorps %%xmm%d, %%xmm%d\n" % (x, x))
377
545
  if op == Onop:
378
546
  # just do nothing for nops, they are inserted
379
547
  # by some passes
@@ -402,7 +570,7 @@ def emitins(i, e):
402
570
  _table(i, e)
403
571
  elif op == Oneg:
404
572
  if i.to != i.arg[0]:
405
- emitf("mov%k %0, %=", i, e)
573
+ emitcopy(i.to, i.arg[0], i.cls, e)
406
574
  if KBASE(i.cls) == 0:
407
575
  emitf("neg%k %=", i, e)
408
576
  else:
@@ -414,8 +582,8 @@ def emitins(i, e):
414
582
  # conversion to 2-address in emitf() would fail
415
583
  if i.to == i.arg[1]:
416
584
  i.arg[1] = TMP(XMM0 + 15)
417
- emitf("mov%k %=, %1", i, e)
418
- emitf("mov%k %0, %=", i, e)
585
+ emitcopy(i.arg[1], i.to, i.cls, e)
586
+ emitcopy(i.to, i.arg[0], i.cls, e)
419
587
  i.arg[0] = i.to
420
588
  _table(i, e)
421
589
  elif op == Ocopy:
@@ -448,6 +616,9 @@ def emitins(i, e):
448
616
  emitf("mov%k %0, %1", i, e)
449
617
  emitf("mov%k %1, %=", i, e)
450
618
  return
619
+ if _xreg(i.to) and _xreg(i.arg[0]):
620
+ _xcopy(i.to, i.arg[0], e)
621
+ return
451
622
  # conveniently, the assembler knows if it
452
623
  # should use movabsq when reading movq
453
624
  emitf("mov%k %0, %=", i, e)
@@ -545,7 +716,7 @@ def emitins(i, e):
545
716
  emitf("sqrt%k %0, %=", i, e)
546
717
  elif op == Ofabs:
547
718
  if i.to != i.arg[0]:
548
- emitf("mov%k %0, %=", i, e)
719
+ emitcopy(i.to, i.arg[0], i.cls, e)
549
720
  f.write("\tandp%c %sfp%d(%%rip), %%%s\n" % (
550
721
  "xxsd"[i.cls], D.T.asloc, stashbits(absmask[i.cls], 16),
551
722
  regtoa(rval(i.to), SLong)))
@@ -596,6 +767,8 @@ def _usesxmm15(fn):
596
767
  b = fn.start
597
768
  while b:
598
769
  for i in b.ins[:b.nins]:
770
+ if i.cls == D.Kq or D.isqop(i.op): # ext.vector: moves, lanes, operands in the way
771
+ return True
599
772
  if i.op == Odiv and KBASE(i.cls) == 1 and i.to == i.arg[1]:
600
773
  return True
601
774
  if i.op == Ocopy and rtype(i.to) == RSlot and rtype(i.arg[0]) in (RSlot, RMem):
@@ -710,7 +883,8 @@ def _emitjmp(b, fn, e, id0, rclob, nclr, win):
710
883
  else:
711
884
  c = jt - Jjf
712
885
  if 0 <= c <= NCmp:
713
- if b.link is b.s2 or (win and c >= NCmpI):
886
+ # cimo: a loop's back edge is the conditional jump, not a jump after one that's rarely taken
887
+ if b.link is b.s2 or (win and c >= NCmpI) or (b.s1 is not b.link and b.s1.id <= b.id < b.s2.id):
714
888
  s = b.s1
715
889
  b.s1 = b.s2
716
890
  b.s2 = s
@@ -129,12 +129,22 @@ def fixarg(lst, idx, k, i, fn):
129
129
  r2 = newtmp("isel", Kl, fn)
130
130
  cc = Con(CBits, c.i)
131
131
  r3 = newcon(cc, fn)
132
- if noimm(r3, fn): # fix over C QBE: an add's immediate is 32 bits
132
+ # fix over C QBE: lea, not add. For a phi's argument this comes after the block's last instruction, between
133
+ # a compare and the jump that reads its flags (YARPGen: extern_array + 4 went the wrong way, then crashed)
134
+ a = Addr()
135
+ a.base = r2
136
+ if noimm(r3, fn): # an address's offset is 32 bits
133
137
  r4 = newtmp("isel", Kl, fn)
134
- emit(Oadd, Kl, r1, r2, r4)
135
- emit(Ocopy, Kl, r4, r3, R)
138
+ a.index = r4
139
+ a.scale = 1
136
140
  else:
137
- emit(Oadd, Kl, r1, r2, r3)
141
+ a.offset = cc
142
+ fn.nmem += 1
143
+ vgrow(fn.mem, fn.nmem, Addr)
144
+ fn.mem[fn.nmem - 1] = a
145
+ emit(Oaddr, Kl, r1, MEM(fn.nmem - 1), R)
146
+ if noimm(r3, fn):
147
+ emit(Ocopy, Kl, r4, r3, R)
138
148
  else:
139
149
  r2 = r1
140
150
  if D.T.apple and (c.sym.type & SThr):
@@ -275,7 +285,9 @@ def sel(i, tn, fn):
275
285
  i0 = D.curi
276
286
  k = i.cls
277
287
  op = i.op
278
- if op in (Odiv, Orem, Oudiv, Ourem):
288
+ if D.isqop(op):
289
+ _qsel(i, tn, fn)
290
+ elif op in (Odiv, Orem, Oudiv, Ourem):
279
291
  if KBASE(k) == 1:
280
292
  _emit_fix(i, fn)
281
293
  else:
@@ -403,6 +415,9 @@ def sel(i, tn, fn):
403
415
  fixarg(ci.arg, 0, Kl, ci, fn)
404
416
  elif op == Onop:
405
417
  pass
418
+ elif op in _RMW.values():
419
+ seladdr(i.arg, 1, tn, fn)
420
+ _emit_fix(i, fn)
406
421
  elif op in (Ostored, Ostores, Ostorel, Ostorew, Ostoreh, Ostoreb):
407
422
  if rtype(i.arg[0]) == RCon:
408
423
  if i.op == Ostored:
@@ -481,6 +496,35 @@ _EXTINT = frozenset((D.Obclz, D.Obctz, D.Obswap, D.Obswap16))
481
496
  _EXTOPS = _EXTINT | frozenset((D.Ogetsp, D.Osetsp, D.Ofsqrt, D.Ofabs))
482
497
 
483
498
 
499
+ def _qsel(i, tn, fn):
500
+ """cimo (ext.vector): registers, a whole addressing mode, and a constant for shifts, shuffles and lanes."""
501
+ op = i.op
502
+ if op == D.Oqload:
503
+ seladdr(i.arg, 0, tn, fn)
504
+ elif op == D.Oqstore:
505
+ seladdr(i.arg, 1, tn, fn)
506
+ if D.Oqdupb <= op <= D.Oqdupd and rtype(i.arg[0]) == RCon:
507
+ c = fn.con[rval(i.arg[0])]
508
+ if c.type == CBits and c.i in (0, -1) and op not in (D.Oqdups, D.Oqdupd):
509
+ emiti(i) # pxor, pcmpeqd
510
+ return
511
+ k = argcls(i, 0)
512
+ r = newtmp("isel", k, fn)
513
+ a = i.arg[0]
514
+ i.arg[0] = r
515
+ emiti(i)
516
+ emit(Ocopy, k, r, a, R)
517
+ ci = D.insb[D.curi]
518
+ fixarg(ci.arg, 0, k, ci, fn)
519
+ return
520
+ emiti(i)
521
+ i1 = D.insb[D.curi]
522
+ keep1 = D.Oqshlb <= op <= D.Oqsarl or D.Oqgetb <= op <= D.Oqgetd or op == D.Oqxshufd
523
+ fixarg(i1.arg, 0, argcls(i, 0), i1, fn)
524
+ if i1.arg[1] != R and argcls(i, 1) != D.Kx and not keep1:
525
+ fixarg(i1.arg, 1, argcls(i, 1), i1, fn)
526
+
527
+
484
528
  def _emit_fix(i, fn):
485
529
  emiti(i)
486
530
  _fix2(i, fn)
@@ -523,6 +567,15 @@ def selsel(fn, b, i, tn):
523
567
  isel0 -= 1
524
568
  assert ins[isel0].op == Osel0
525
569
  r = ins[isel0].arg[0]
570
+ if rtype(r) == RCon: # cimo: the middle end's if-conversion, its condition folded since: copies
571
+ yes = fn.con[rval(r)].type != CBits or fn.con[rval(r)].i != 0
572
+ isel1 = i
573
+ while isel0 < isel1:
574
+ x = ins[isel1]
575
+ sel(Ins(Ocopy, x.cls, x.to, x.arg[0] if yes else x.arg[1], R), tn, fn)
576
+ isel1 -= 1
577
+ ins[isel0] = Ins(Onop)
578
+ return isel0
526
579
  assert rtype(r) == RTmp
527
580
  t = fn.tmp[rval(r)]
528
581
  fi = flagi(ins, 0, isel0, fn)
@@ -866,6 +919,76 @@ def amatch(a, tn, r, fn):
866
919
  return 1
867
920
 
868
921
 
922
+ _RMW = {Oadd: D.Oxaddm, Osub: D.Oxsubm, Oand: D.Oxandm, Oor: D.Oxorm, Oxor: D.Oxxorm}
923
+ # an extension to 64 bits: the loads of a word it can be, and the load that does both. A 32-bit load is any of three, its
924
+ # extension says which half it means
925
+ _W = (Oload, D.Oloadsw, D.Oloaduw)
926
+ _ZEXT = {D.Oextub: ((D.Oloadub,), D.Oloadub), D.Oextuh: ((D.Oloaduh,), D.Oloaduh), D.Oextuw: (_W, D.Oloaduw),
927
+ D.Oextsb: ((D.Oloadsb,), D.Oloadsb), D.Oextsh: ((D.Oloadsh,), D.Oloadsh), D.Oextsw: (_W, D.Oloadsw)}
928
+
929
+
930
+ def _writes(op):
931
+ """Whether op may write memory."""
932
+ return isstore(op) or op in _RMW.values() or op in (Ocall, D.Oblit0, D.Oblit1, D.Ovastart, D.Oqstore)
933
+
934
+
935
+ def _loadsfold(fn):
936
+ """cimo: what x86-64 does in the load or the store itself, as gcc. A load extended to 64 bits extends to 64 bits
937
+ (movzbl and then movzbq of its byte: 8.8 to 7.2 ms on Zen 4's histogram). A load, an operation on it and a store
938
+ of the result to the same address, nothing in between that may write memory, are one instruction (addl $1, (mem):
939
+ 5.9 ms, gcc's 6.3). Needs use counts."""
940
+ tmp = fn.tmp
941
+ b = fn.start
942
+ while b:
943
+ ins = b.ins[:b.nins]
944
+ defs = {}
945
+ for k, i in enumerate(ins):
946
+ if rtype(i.to) == RTmp:
947
+ defs[rval(i.to)] = k
948
+ for k, i in enumerate(ins):
949
+ if i.op in _ZEXT and i.cls == Kl and rtype(i.arg[0]) == RTmp:
950
+ d = defs.get(rval(i.arg[0]))
951
+ if d is not None and d < k and ins[d].op in _ZEXT[i.op][0] and ins[d].cls == Kw \
952
+ and tmp[rval(i.arg[0])].nuse == 1:
953
+ ld = ins[d]
954
+ ld.op = _ZEXT[i.op][1]
955
+ ld.cls = Kl
956
+ ld.to = i.to
957
+ ins[k] = Ins(Onop)
958
+ for k, st in enumerate(ins):
959
+ k2 = {Ostorew: Kw, Ostorel: Kl}.get(st.op)
960
+ if k2 is None or rtype(st.arg[0]) != RTmp or fn.hasvolatile: # a volatile access stays as written
961
+ continue
962
+ o = defs.get(rval(st.arg[0]))
963
+ if o is None or o >= k or ins[o].op not in _RMW or ins[o].cls != k2 or tmp[rval(st.arg[0])].nuse != 1:
964
+ continue
965
+ op = ins[o]
966
+ for n in (0, 1):
967
+ a = op.arg[n]
968
+ if rtype(a) != RTmp:
969
+ continue
970
+ d = defs.get(rval(a))
971
+ if d is None or d >= o or tmp[rval(a)].nuse != 1:
972
+ continue
973
+ ld = ins[d]
974
+ if not ((ld.op == Oload or (k2 == Kw and ld.op in (D.Oloadsw, D.Oloaduw))) and ld.cls == k2
975
+ and ld.arg[0] == st.arg[1]):
976
+ continue
977
+ if n == 1 and op.op == Osub:
978
+ continue
979
+ if any(_writes(x.op) for x in ins[d + 1:k] if x is not op):
980
+ continue
981
+ v = op.arg[1 - n]
982
+ ins[k] = Ins(_RMW[op.op], k2, R, v, st.arg[1])
983
+ ins[o] = Ins(Onop)
984
+ ins[d] = Ins(Onop)
985
+ tmp[rval(st.arg[1])].nuse -= 1 if rtype(st.arg[1]) == RTmp else 0
986
+ break
987
+ b.ins = ins
988
+ b.nins = len(ins)
989
+ b = b.link
990
+
991
+
869
992
  def amd64_isel(fn):
870
993
  """instruction selection
871
994
  requires use counts (as given by parsing)"""
@@ -892,6 +1015,8 @@ def amd64_isel(fn):
892
1015
  b.ins[k] = Ins(Onop)
893
1016
  n *= 2
894
1017
 
1018
+ _loadsfold(fn)
1019
+
895
1020
  # process basic blocks
896
1021
  b = fn.start
897
1022
  while b: