tpy-lang 0.3.0.dev0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (333) hide show
  1. tpy_lang-0.3.0.dev0.dist-info/METADATA +151 -0
  2. tpy_lang-0.3.0.dev0.dist-info/RECORD +333 -0
  3. tpy_lang-0.3.0.dev0.dist-info/WHEEL +4 -0
  4. tpy_lang-0.3.0.dev0.dist-info/entry_points.txt +3 -0
  5. tpyc/__init__.py +104 -0
  6. tpyc/__main__.py +6 -0
  7. tpyc/_buildinfo.py +1 -0
  8. tpyc/_data/docs/LANGUAGE_FEATURES.md +6278 -0
  9. tpyc/_data/docs/STDLIB_ROADMAP.md +1258 -0
  10. tpyc/_data/docs/TPY_FOR_AGENTS.md +556 -0
  11. tpyc/_data/lib/tpy/_bindings/__init__.py +6 -0
  12. tpyc/_data/lib/tpy/_bindings/pcre2.py +173 -0
  13. tpyc/_data/lib/tpy/_bindings/posix_socket.py +161 -0
  14. tpyc/_data/lib/tpy/_functools_macros.py +80 -0
  15. tpyc/_data/lib/tpy/_macro_helpers.py +161 -0
  16. tpyc/_data/lib/tpy/argparse.py +2062 -0
  17. tpyc/_data/lib/tpy/asyncio/__init__.py +744 -0
  18. tpyc/_data/lib/tpy/asyncio/_executor.py +515 -0
  19. tpyc/_data/lib/tpy/base64.py +410 -0
  20. tpyc/_data/lib/tpy/bisect.py +39 -0
  21. tpyc/_data/lib/tpy/builtins.py +38 -0
  22. tpyc/_data/lib/tpy/dataclasses.py +354 -0
  23. tpyc/_data/lib/tpy/enum.py +23 -0
  24. tpyc/_data/lib/tpy/functools.py +33 -0
  25. tpyc/_data/lib/tpy/hashlib.py +206 -0
  26. tpyc/_data/lib/tpy/heapq.py +118 -0
  27. tpyc/_data/lib/tpy/io.py +395 -0
  28. tpyc/_data/lib/tpy/json.py +221 -0
  29. tpyc/_data/lib/tpy/math.py +406 -0
  30. tpyc/_data/lib/tpy/random.py +597 -0
  31. tpyc/_data/lib/tpy/re.py +467 -0
  32. tpyc/_data/lib/tpy/socket.py +379 -0
  33. tpyc/_data/lib/tpy/struct.py +178 -0
  34. tpyc/_data/lib/tpy/sys.py +40 -0
  35. tpyc/_data/lib/tpy/time.py +39 -0
  36. tpyc/_data/lib/tpy/tpy/__init__.py +78 -0
  37. tpyc/_data/lib/tpy/tpy/_bootstrap/__init__.py +10 -0
  38. tpyc/_data/lib/tpy/tpy/_bootstrap/_decorators.py +37 -0
  39. tpyc/_data/lib/tpy/tpy/_bootstrap/_extern.py +64 -0
  40. tpyc/_data/lib/tpy/tpy/_builtins/__init__.py +11 -0
  41. tpyc/_data/lib/tpy/tpy/_builtins/_bytes.py +378 -0
  42. tpyc/_data/lib/tpy/tpy/_builtins/_dict.py +151 -0
  43. tpyc/_data/lib/tpy/tpy/_builtins/_exceptions.py +125 -0
  44. tpyc/_data/lib/tpy/tpy/_builtins/_funcs.py +681 -0
  45. tpyc/_data/lib/tpy/tpy/_builtins/_io.py +97 -0
  46. tpyc/_data/lib/tpy/tpy/_builtins/_list.py +127 -0
  47. tpyc/_data/lib/tpy/tpy/_builtins/_range.py +52 -0
  48. tpyc/_data/lib/tpy/tpy/_builtins/_set.py +139 -0
  49. tpyc/_data/lib/tpy/tpy/_builtins/_super.py +11 -0
  50. tpyc/_data/lib/tpy/tpy/_builtins/_types.py +661 -0
  51. tpyc/_data/lib/tpy/tpy/_core/__init__.py +23 -0
  52. tpyc/_data/lib/tpy/tpy/_core/_bytes_view.py +129 -0
  53. tpyc/_data/lib/tpy/tpy/_core/_containers.py +137 -0
  54. tpyc/_data/lib/tpy/tpy/_core/_functions.py +40 -0
  55. tpyc/_data/lib/tpy/tpy/_core/_types.py +2061 -0
  56. tpyc/_data/lib/tpy/tpy/_typing/__init__.py +77 -0
  57. tpyc/_data/lib/tpy/tpy/_version.py +29 -0
  58. tpyc/_data/lib/tpy/tpy/bits.py +28 -0
  59. tpyc/_data/lib/tpy/tpy/coro/__init__.py +127 -0
  60. tpyc/_data/lib/tpy/tpy/extern.py +8 -0
  61. tpyc/_data/lib/tpy/tpy/mem.py +49 -0
  62. tpyc/_data/lib/tpy/tpy/unsafe.py +195 -0
  63. tpyc/_data/lib/tpy/tpy/version.py +21 -0
  64. tpyc/_data/lib/tpy/typing.py +13 -0
  65. tpyc/_data/runtime/cpp/include/tpy/any.hpp +461 -0
  66. tpyc/_data/runtime/cpp/include/tpy/as_ostream.hpp +117 -0
  67. tpyc/_data/runtime/cpp/include/tpy/async.hpp +76 -0
  68. tpyc/_data/runtime/cpp/include/tpy/bigint.hpp +1343 -0
  69. tpyc/_data/runtime/cpp/include/tpy/builtins.hpp +400 -0
  70. tpyc/_data/runtime/cpp/include/tpy/bytes_ops.hpp +469 -0
  71. tpyc/_data/runtime/cpp/include/tpy/container_ops.hpp +487 -0
  72. tpyc/_data/runtime/cpp/include/tpy/copy_iter.hpp +82 -0
  73. tpyc/_data/runtime/cpp/include/tpy/core.hpp +558 -0
  74. tpyc/_data/runtime/cpp/include/tpy/dict_ops.hpp +289 -0
  75. tpyc/_data/runtime/cpp/include/tpy/dunder.hpp +750 -0
  76. tpyc/_data/runtime/cpp/include/tpy/dynamic.hpp +44 -0
  77. tpyc/_data/runtime/cpp/include/tpy/enum.hpp +40 -0
  78. tpyc/_data/runtime/cpp/include/tpy/file.hpp +245 -0
  79. tpyc/_data/runtime/cpp/include/tpy/fixed_int.hpp +317 -0
  80. tpyc/_data/runtime/cpp/include/tpy/format.hpp +954 -0
  81. tpyc/_data/runtime/cpp/include/tpy/frame_slot.hpp +120 -0
  82. tpyc/_data/runtime/cpp/include/tpy/generator.hpp +47 -0
  83. tpyc/_data/runtime/cpp/include/tpy/iterable_ops.hpp +122 -0
  84. tpyc/_data/runtime/cpp/include/tpy/itertools.hpp +749 -0
  85. tpyc/_data/runtime/cpp/include/tpy/next_iter.hpp +82 -0
  86. tpyc/_data/runtime/cpp/include/tpy/ordered_map.hpp +518 -0
  87. tpyc/_data/runtime/cpp/include/tpy/ordered_set.hpp +337 -0
  88. tpyc/_data/runtime/cpp/include/tpy/own_iter.hpp +54 -0
  89. tpyc/_data/runtime/cpp/include/tpy/pascal_graph_sdl.hpp +192 -0
  90. tpyc/_data/runtime/cpp/include/tpy/printing.hpp +302 -0
  91. tpyc/_data/runtime/cpp/include/tpy/protocols.hpp +61 -0
  92. tpyc/_data/runtime/cpp/include/tpy/range.hpp +115 -0
  93. tpyc/_data/runtime/cpp/include/tpy/ranges.hpp +212 -0
  94. tpyc/_data/runtime/cpp/include/tpy/set_ops.hpp +265 -0
  95. tpyc/_data/runtime/cpp/include/tpy/slice.hpp +47 -0
  96. tpyc/_data/runtime/cpp/include/tpy/span_iter.hpp +42 -0
  97. tpyc/_data/runtime/cpp/include/tpy/stdlib/math.hpp +41 -0
  98. tpyc/_data/runtime/cpp/include/tpy/stdlib/pcre2_h.hpp +96 -0
  99. tpyc/_data/runtime/cpp/include/tpy/stdlib/random.hpp +25 -0
  100. tpyc/_data/runtime/cpp/include/tpy/stdlib/socket_h.hpp +145 -0
  101. tpyc/_data/runtime/cpp/include/tpy/stdlib/time.hpp +62 -0
  102. tpyc/_data/runtime/cpp/include/tpy/system.hpp +121 -0
  103. tpyc/_data/runtime/cpp/include/tpy/throwable.hpp +55 -0
  104. tpyc/_data/runtime/cpp/include/tpy/tpy.hpp +156 -0
  105. tpyc/_data/runtime/cpp/include/tpy/type_name.hpp +77 -0
  106. tpyc/_data/runtime/cpp/include/tpy/type_traits.hpp +240 -0
  107. tpyc/_data/runtime/cpp/include/tpy/uninit_array_storage.hpp +250 -0
  108. tpyc/_data/runtime/cpp/include/tpy/uninit_heap_storage.hpp +277 -0
  109. tpyc/_data/runtime/cpp/include/tpy/varargs.hpp +174 -0
  110. tpyc/_data/runtime/cpp/include/tpy/variant_ref.hpp +118 -0
  111. tpyc/_data/runtime/cpp/src/stdlib/socket_impl.cpp +104 -0
  112. tpyc/_data/runtime/cpp/third_party/README.md +58 -0
  113. tpyc/_data/runtime/cpp/third_party/pcre2/AUTHORS +36 -0
  114. tpyc/_data/runtime/cpp/third_party/pcre2/CMakeLists.txt +1233 -0
  115. tpyc/_data/runtime/cpp/third_party/pcre2/COPYING +5 -0
  116. tpyc/_data/runtime/cpp/third_party/pcre2/ChangeLog +3097 -0
  117. tpyc/_data/runtime/cpp/third_party/pcre2/HACKING +853 -0
  118. tpyc/_data/runtime/cpp/third_party/pcre2/INSTALL +368 -0
  119. tpyc/_data/runtime/cpp/third_party/pcre2/LICENCE +94 -0
  120. tpyc/_data/runtime/cpp/third_party/pcre2/NEWS +492 -0
  121. tpyc/_data/runtime/cpp/third_party/pcre2/NON-AUTOTOOLS-BUILD +430 -0
  122. tpyc/_data/runtime/cpp/third_party/pcre2/README +956 -0
  123. tpyc/_data/runtime/cpp/third_party/pcre2/cmake/COPYING-CMAKE-SCRIPTS +22 -0
  124. tpyc/_data/runtime/cpp/third_party/pcre2/cmake/FindEditline.cmake +16 -0
  125. tpyc/_data/runtime/cpp/third_party/pcre2/cmake/FindPackageHandleStandardArgs.cmake +58 -0
  126. tpyc/_data/runtime/cpp/third_party/pcre2/cmake/FindReadline.cmake +29 -0
  127. tpyc/_data/runtime/cpp/third_party/pcre2/cmake/pcre2-config-version.cmake.in +15 -0
  128. tpyc/_data/runtime/cpp/third_party/pcre2/cmake/pcre2-config.cmake.in +148 -0
  129. tpyc/_data/runtime/cpp/third_party/pcre2/config-cmake.h.in +56 -0
  130. tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-16.pc.in +13 -0
  131. tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-32.pc.in +13 -0
  132. tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-8.pc.in +13 -0
  133. tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-posix.pc.in +13 -0
  134. tpyc/_data/runtime/cpp/third_party/pcre2/pcre2-config.in +121 -0
  135. tpyc/_data/runtime/cpp/third_party/pcre2/src/config.h +483 -0
  136. tpyc/_data/runtime/cpp/third_party/pcre2/src/config.h.generic +483 -0
  137. tpyc/_data/runtime/cpp/third_party/pcre2/src/config.h.in +460 -0
  138. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2.h +1010 -0
  139. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2.h.generic +1010 -0
  140. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2.h.in +1010 -0
  141. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_auto_possess.c +1371 -0
  142. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_chartables.c +196 -0
  143. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_chartables.c.dist +196 -0
  144. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_chkdint.c +96 -0
  145. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_compile.c +11001 -0
  146. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_config.c +252 -0
  147. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_context.c +510 -0
  148. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_convert.c +1189 -0
  149. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_dfa_match.c +4119 -0
  150. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_dftables.c +297 -0
  151. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_error.c +345 -0
  152. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_extuni.c +162 -0
  153. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_find_bracket.c +219 -0
  154. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_fuzzsupport.c +792 -0
  155. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_internal.h +2084 -0
  156. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_intmodedep.h +940 -0
  157. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_compile.c +14972 -0
  158. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_match.c +200 -0
  159. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_misc.c +234 -0
  160. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_neon_inc.h +354 -0
  161. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_simd_inc.h +2355 -0
  162. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_test.c +2528 -0
  163. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_maketables.c +165 -0
  164. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_match.c +7777 -0
  165. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_match_data.c +185 -0
  166. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_newline.c +243 -0
  167. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ord2utf.c +120 -0
  168. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_pattern_info.c +432 -0
  169. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_printint.c +886 -0
  170. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_script_run.c +344 -0
  171. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_serialize.c +286 -0
  172. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_string_utils.c +237 -0
  173. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_study.c +1915 -0
  174. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_substitute.c +1009 -0
  175. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_substring.c +550 -0
  176. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_tables.c +234 -0
  177. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ucd.c +5460 -0
  178. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ucp.h +396 -0
  179. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ucptables.c +1533 -0
  180. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_valid_utf.c +398 -0
  181. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_xclass.c +308 -0
  182. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2demo.c +497 -0
  183. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2grep.c +4606 -0
  184. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2posix.c +425 -0
  185. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2posix.h +187 -0
  186. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2posix_test.c +209 -0
  187. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2test.c +9708 -0
  188. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorApple.c +137 -0
  189. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorCore.c +327 -0
  190. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorFreeBSD.c +89 -0
  191. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorPosix.c +62 -0
  192. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorWindows.c +40 -0
  193. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorNetBSD.c +72 -0
  194. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorPosix.c +172 -0
  195. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorPosix.c +141 -0
  196. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorWindows.c +102 -0
  197. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitConfig.h +142 -0
  198. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitConfigCPU.h +188 -0
  199. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitConfigInternal.h +907 -0
  200. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitLir.c +3561 -0
  201. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitLir.h +2466 -0
  202. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeARM_32.c +4636 -0
  203. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeARM_64.c +3491 -0
  204. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeARM_T2_32.c +4302 -0
  205. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeLOONGARCH_64.c +3765 -0
  206. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeMIPS_32.c +472 -0
  207. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeMIPS_64.c +387 -0
  208. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeMIPS_common.c +4259 -0
  209. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativePPC_32.c +485 -0
  210. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativePPC_64.c +719 -0
  211. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativePPC_common.c +3161 -0
  212. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeRISCV_32.c +142 -0
  213. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeRISCV_64.c +222 -0
  214. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeRISCV_common.c +3121 -0
  215. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeS390X.c +4526 -0
  216. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeX86_32.c +1685 -0
  217. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeX86_64.c +1398 -0
  218. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeX86_common.c +5001 -0
  219. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitSerialize.c +516 -0
  220. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitUtils.c +344 -0
  221. tpyc/_data/runtime/cpp/third_party/pcre2.sources.txt +54 -0
  222. tpyc/_data/runtime/cpp/third_party/pcre2.vendor.json +7 -0
  223. tpyc/build/__init__.py +7 -0
  224. tpyc/build/pcre2.py +122 -0
  225. tpyc/build/third_party.py +413 -0
  226. tpyc/cli.py +822 -0
  227. tpyc/codegen_cpp/__init__.py +18 -0
  228. tpyc/codegen_cpp/builtins.py +484 -0
  229. tpyc/codegen_cpp/context.py +2064 -0
  230. tpyc/codegen_cpp/expressions.py +5940 -0
  231. tpyc/codegen_cpp/functions.py +1913 -0
  232. tpyc/codegen_cpp/gen_async.py +3258 -0
  233. tpyc/codegen_cpp/gen_generators.py +657 -0
  234. tpyc/codegen_cpp/generator.py +2258 -0
  235. tpyc/codegen_cpp/match.py +1997 -0
  236. tpyc/codegen_cpp/param_const.py +172 -0
  237. tpyc/codegen_cpp/protocols.py +907 -0
  238. tpyc/codegen_cpp/records.py +1654 -0
  239. tpyc/codegen_cpp/resumable_cfg.py +1651 -0
  240. tpyc/codegen_cpp/statements.py +4963 -0
  241. tpyc/codegen_cpp/string_dispatch.py +76 -0
  242. tpyc/codegen_cpp/test_context.py +46 -0
  243. tpyc/codegen_cpp/test_param_const.py +113 -0
  244. tpyc/codegen_cpp/test_resumable_cfg.py +182 -0
  245. tpyc/codegen_cpp/type_resolution.py +53 -0
  246. tpyc/codegen_cpp/types.py +436 -0
  247. tpyc/codegen_cpp/variant_access.py +135 -0
  248. tpyc/coercions.py +749 -0
  249. tpyc/compilation_context.py +57 -0
  250. tpyc/compiler.py +3945 -0
  251. tpyc/cycle_detection.py +358 -0
  252. tpyc/diagnostics.py +135 -0
  253. tpyc/dump_types.py +353 -0
  254. tpyc/frontend_diagnostics.py +47 -0
  255. tpyc/frontend_ir/__init__.py +140 -0
  256. tpyc/frontend_ir/lower.py +1098 -0
  257. tpyc/frontend_ir/nodes.py +718 -0
  258. tpyc/frontend_ir/resolver_adapter.py +151 -0
  259. tpyc/frontend_plugin.py +209 -0
  260. tpyc/install_docs.py +81 -0
  261. tpyc/liveness.py +756 -0
  262. tpyc/macro_api.py +1724 -0
  263. tpyc/macro_loader.py +497 -0
  264. tpyc/module_names.py +64 -0
  265. tpyc/modules/__init__.py +31 -0
  266. tpyc/modules/defs.py +89 -0
  267. tpyc/modules/registry.py +36 -0
  268. tpyc/modules/resolver.py +192 -0
  269. tpyc/modules/type_resolution.py +629 -0
  270. tpyc/namespace.py +172 -0
  271. tpyc/parse/__init__.py +84 -0
  272. tpyc/parse/imports.py +490 -0
  273. tpyc/parse/nodes.py +1732 -0
  274. tpyc/parse/parser.py +4043 -0
  275. tpyc/parse/resolve_refs.py +466 -0
  276. tpyc/parse/type_resolver.py +1060 -0
  277. tpyc/prescan.py +254 -0
  278. tpyc/qnames.py +149 -0
  279. tpyc/repl.py +529 -0
  280. tpyc/repl_backends.py +848 -0
  281. tpyc/sema/__init__.py +21 -0
  282. tpyc/sema/analyzer.py +3625 -0
  283. tpyc/sema/bound_check.py +72 -0
  284. tpyc/sema/builder_trace.py +684 -0
  285. tpyc/sema/calls.py +5406 -0
  286. tpyc/sema/compatibility.py +2107 -0
  287. tpyc/sema/context.py +1243 -0
  288. tpyc/sema/expressions.py +3737 -0
  289. tpyc/sema/flow_facts.py +199 -0
  290. tpyc/sema/init_tracker.py +150 -0
  291. tpyc/sema/list_literals.py +69 -0
  292. tpyc/sema/literal_utils.py +27 -0
  293. tpyc/sema/local_deduction.py +1088 -0
  294. tpyc/sema/macros.py +179 -0
  295. tpyc/sema/match.py +1177 -0
  296. tpyc/sema/method_expansion.py +347 -0
  297. tpyc/sema/methods.py +2197 -0
  298. tpyc/sema/mutation_propagation.py +268 -0
  299. tpyc/sema/narrowing.py +857 -0
  300. tpyc/sema/numeric_lattice.py +160 -0
  301. tpyc/sema/operators.py +402 -0
  302. tpyc/sema/overloads.py +841 -0
  303. tpyc/sema/protocols.py +1209 -0
  304. tpyc/sema/reach_analysis.py +202 -0
  305. tpyc/sema/registration.py +3156 -0
  306. tpyc/sema/scope_tracker.py +193 -0
  307. tpyc/sema/statements.py +4426 -0
  308. tpyc/sema/type_ops.py +1879 -0
  309. tpyc/sema/value_range.py +181 -0
  310. tpyc/symbol_binding.py +259 -0
  311. tpyc/test_c3_mro.py +208 -0
  312. tpyc/test_cli_argv.py +52 -0
  313. tpyc/test_compiler.py +559 -0
  314. tpyc/test_contains_type_param.py +101 -0
  315. tpyc/test_cycle_detection.py +221 -0
  316. tpyc/test_dump_types.py +225 -0
  317. tpyc/test_install_docs.py +65 -0
  318. tpyc/test_local_cpp_form.py +135 -0
  319. tpyc/test_macro_loader.py +76 -0
  320. tpyc/test_method_expansion.py +254 -0
  321. tpyc/test_nominal_identity.py +182 -0
  322. tpyc/test_overloads.py +410 -0
  323. tpyc/test_parse.py +303 -0
  324. tpyc/test_parse_type_ref.py +506 -0
  325. tpyc/test_parse_version_info.py +58 -0
  326. tpyc/test_reach_analysis.py +72 -0
  327. tpyc/test_ref_type.py +216 -0
  328. tpyc/test_send_sync_substitution.py +276 -0
  329. tpyc/test_tuple_mutation_propagation.py +206 -0
  330. tpyc/test_type_def_registry.py +1729 -0
  331. tpyc/test_union_types.py +195 -0
  332. tpyc/type_def_registry.py +975 -0
  333. tpyc/typesys.py +5104 -0
@@ -0,0 +1,4259 @@
1
+ /*
2
+ * Stack-less Just-In-Time compiler
3
+ *
4
+ * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without modification, are
7
+ * permitted provided that the following conditions are met:
8
+ *
9
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
10
+ * conditions and the following disclaimer.
11
+ *
12
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
13
+ * of conditions and the following disclaimer in the documentation and/or other materials
14
+ * provided with the distribution.
15
+ *
16
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
17
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
22
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
24
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+ */
26
+
27
+ /* Latest MIPS architecture. */
28
+
29
+ #ifdef HAVE_PRCTL
30
+ #include <sys/prctl.h>
31
+ #endif
32
+
33
+ #if !defined(__mips_hard_float) || defined(__mips_single_float)
34
+ /* Disable automatic detection, covers both -msoft-float and -mno-float */
35
+ #define SLJIT_IS_FPU_AVAILABLE 0
36
+ #endif
37
+
38
+ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
39
+ {
40
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
41
+
42
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
43
+ return "MIPS32-R6" SLJIT_CPUINFO;
44
+ #else /* !SLJIT_CONFIG_MIPS_32 */
45
+ return "MIPS64-R6" SLJIT_CPUINFO;
46
+ #endif /* SLJIT_CONFIG_MIPS_32 */
47
+
48
+ #elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 5)
49
+
50
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
51
+ return "MIPS32-R5" SLJIT_CPUINFO;
52
+ #else /* !SLJIT_CONFIG_MIPS_32 */
53
+ return "MIPS64-R5" SLJIT_CPUINFO;
54
+ #endif /* SLJIT_CONFIG_MIPS_32 */
55
+
56
+ #elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
57
+
58
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
59
+ return "MIPS32-R2" SLJIT_CPUINFO;
60
+ #else /* !SLJIT_CONFIG_MIPS_32 */
61
+ return "MIPS64-R2" SLJIT_CPUINFO;
62
+ #endif /* SLJIT_CONFIG_MIPS_32 */
63
+
64
+ #elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
65
+
66
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
67
+ return "MIPS32-R1" SLJIT_CPUINFO;
68
+ #else /* !SLJIT_CONFIG_MIPS_32 */
69
+ return "MIPS64-R1" SLJIT_CPUINFO;
70
+ #endif /* SLJIT_CONFIG_MIPS_32 */
71
+
72
+ #else /* SLJIT_MIPS_REV < 1 */
73
+ return "MIPS III" SLJIT_CPUINFO;
74
+ #endif /* SLJIT_MIPS_REV >= 6 */
75
+ }
76
+
77
+ /* Length of an instruction word
78
+ Both for mips-32 and mips-64 */
79
+ typedef sljit_u32 sljit_ins;
80
+
81
+ #define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
82
+ #define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
83
+ #define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
84
+
85
+ /* For position independent code, t9 must contain the function address. */
86
+ #define PIC_ADDR_REG TMP_REG1
87
+
88
+ /* Floating point status register. */
89
+ #define FCSR_REG 31
90
+ /* Return address register. */
91
+ #define RETURN_ADDR_REG 31
92
+
93
+ /* Flags are kept in volatile registers. */
94
+ #define EQUAL_FLAG 3
95
+ #define OTHER_FLAG 1
96
+
97
+ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 7] = {
98
+ 0, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 25, 4, 31, 3, 1
99
+ };
100
+
101
+ #define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
102
+ #define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
103
+ #define TMP_FREG3 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3)
104
+
105
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
106
+
107
+ static const sljit_u8 freg_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3) << 1) + 1] = {
108
+ 0,
109
+ 0, 14, 2, 4, 6, 8, 18, 30, 28, 26, 24, 22, 20,
110
+ 12, 10, 16,
111
+ 1, 15, 3, 5, 7, 9, 19, 31, 29, 27, 25, 23, 21,
112
+ 13, 11, 17
113
+ };
114
+
115
+ #else /* !SLJIT_CONFIG_MIPS_32 */
116
+
117
+ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
118
+ 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 1, 2, 3, 4, 5, 6, 7, 8, 9, 31, 30, 29, 28, 27, 26, 25, 24, 12, 11, 10
119
+ };
120
+
121
+ #endif /* SLJIT_CONFIG_MIPS_32 */
122
+
123
+ /* --------------------------------------------------------------------- */
124
+ /* Instrucion forms */
125
+ /* --------------------------------------------------------------------- */
126
+
127
+ #define S(s) ((sljit_ins)reg_map[s] << 21)
128
+ #define T(t) ((sljit_ins)reg_map[t] << 16)
129
+ #define D(d) ((sljit_ins)reg_map[d] << 11)
130
+ #define FT(t) ((sljit_ins)freg_map[t] << 16)
131
+ #define FS(s) ((sljit_ins)freg_map[s] << 11)
132
+ #define FD(d) ((sljit_ins)freg_map[d] << 6)
133
+ /* Absolute registers. */
134
+ #define SA(s) ((sljit_ins)(s) << 21)
135
+ #define TA(t) ((sljit_ins)(t) << 16)
136
+ #define DA(d) ((sljit_ins)(d) << 11)
137
+ #define IMM(imm) ((sljit_ins)(imm) & 0xffff)
138
+ #define SH_IMM(imm) ((sljit_ins)(imm) << 6)
139
+
140
+ #define DR(dr) (reg_map[dr])
141
+ #define FR(dr) (freg_map[dr])
142
+ #define HI(opcode) ((sljit_ins)(opcode) << 26)
143
+ #define LO(opcode) ((sljit_ins)(opcode))
144
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
145
+ /* CMP.cond.fmt */
146
+ /* S = (20 << 21) D = (21 << 21) */
147
+ #define CMP_FMT_S (20 << 21)
148
+ #endif /* SLJIT_MIPS_REV >= 6 */
149
+ /* S = (16 << 21) D = (17 << 21) */
150
+ #define FMT_S (16 << 21)
151
+ #define FMT_D (17 << 21)
152
+
153
+ #define ABS_S (HI(17) | FMT_S | LO(5))
154
+ #define ADD_S (HI(17) | FMT_S | LO(0))
155
+ #define ADDIU (HI(9))
156
+ #define ADDU (HI(0) | LO(33))
157
+ #define AND (HI(0) | LO(36))
158
+ #define ANDI (HI(12))
159
+ #define B (HI(4))
160
+ #define BAL (HI(1) | (17 << 16))
161
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
162
+ #define BC1EQZ (HI(17) | (9 << 21) | FT(TMP_FREG3))
163
+ #define BC1NEZ (HI(17) | (13 << 21) | FT(TMP_FREG3))
164
+ #else /* SLJIT_MIPS_REV < 6 */
165
+ #define BC1F (HI(17) | (8 << 21))
166
+ #define BC1T (HI(17) | (8 << 21) | (1 << 16))
167
+ #endif /* SLJIT_MIPS_REV >= 6 */
168
+ #define BEQ (HI(4))
169
+ #define BGEZ (HI(1) | (1 << 16))
170
+ #define BGTZ (HI(7))
171
+ #define BLEZ (HI(6))
172
+ #define BLTZ (HI(1) | (0 << 16))
173
+ #define BNE (HI(5))
174
+ #define BREAK (HI(0) | LO(13))
175
+ #define CFC1 (HI(17) | (2 << 21))
176
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
177
+ #define C_EQ_S (HI(17) | CMP_FMT_S | LO(2))
178
+ #define C_OLE_S (HI(17) | CMP_FMT_S | LO(6))
179
+ #define C_OLT_S (HI(17) | CMP_FMT_S | LO(4))
180
+ #define C_UEQ_S (HI(17) | CMP_FMT_S | LO(3))
181
+ #define C_ULE_S (HI(17) | CMP_FMT_S | LO(7))
182
+ #define C_ULT_S (HI(17) | CMP_FMT_S | LO(5))
183
+ #define C_UN_S (HI(17) | CMP_FMT_S | LO(1))
184
+ #define C_FD (FD(TMP_FREG3))
185
+ #else /* SLJIT_MIPS_REV < 6 */
186
+ #define C_EQ_S (HI(17) | FMT_S | LO(50))
187
+ #define C_OLE_S (HI(17) | FMT_S | LO(54))
188
+ #define C_OLT_S (HI(17) | FMT_S | LO(52))
189
+ #define C_UEQ_S (HI(17) | FMT_S | LO(51))
190
+ #define C_ULE_S (HI(17) | FMT_S | LO(55))
191
+ #define C_ULT_S (HI(17) | FMT_S | LO(53))
192
+ #define C_UN_S (HI(17) | FMT_S | LO(49))
193
+ #define C_FD (0)
194
+ #endif /* SLJIT_MIPS_REV >= 6 */
195
+ #define CVT_S_S (HI(17) | FMT_S | LO(32))
196
+ #define DADDIU (HI(25))
197
+ #define DADDU (HI(0) | LO(45))
198
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
199
+ #define DDIV (HI(0) | (2 << 6) | LO(30))
200
+ #define DDIVU (HI(0) | (2 << 6) | LO(31))
201
+ #define DMOD (HI(0) | (3 << 6) | LO(30))
202
+ #define DMODU (HI(0) | (3 << 6) | LO(31))
203
+ #define DIV (HI(0) | (2 << 6) | LO(26))
204
+ #define DIVU (HI(0) | (2 << 6) | LO(27))
205
+ #define DMUH (HI(0) | (3 << 6) | LO(28))
206
+ #define DMUHU (HI(0) | (3 << 6) | LO(29))
207
+ #define DMUL (HI(0) | (2 << 6) | LO(28))
208
+ #define DMULU (HI(0) | (2 << 6) | LO(29))
209
+ #else /* SLJIT_MIPS_REV < 6 */
210
+ #define DDIV (HI(0) | LO(30))
211
+ #define DDIVU (HI(0) | LO(31))
212
+ #define DIV (HI(0) | LO(26))
213
+ #define DIVU (HI(0) | LO(27))
214
+ #define DMULT (HI(0) | LO(28))
215
+ #define DMULTU (HI(0) | LO(29))
216
+ #endif /* SLJIT_MIPS_REV >= 6 */
217
+ #define DIV_S (HI(17) | FMT_S | LO(3))
218
+ #if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
219
+ #define DINSU (HI(31) | LO(6))
220
+ #endif /* SLJIT_MIPS_REV >= 2 */
221
+ #define DMFC1 (HI(17) | (1 << 21))
222
+ #define DMTC1 (HI(17) | (5 << 21))
223
+ #if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
224
+ #define DROTR (HI(0) | (1 << 21) | LO(58))
225
+ #define DROTR32 (HI(0) | (1 << 21) | LO(62))
226
+ #define DROTRV (HI(0) | (1 << 6) | LO(22))
227
+ #define DSBH (HI(31) | (2 << 6) | LO(36))
228
+ #define DSHD (HI(31) | (5 << 6) | LO(36))
229
+ #endif /* SLJIT_MIPS_REV >= 2 */
230
+ #define DSLL (HI(0) | LO(56))
231
+ #define DSLL32 (HI(0) | LO(60))
232
+ #define DSLLV (HI(0) | LO(20))
233
+ #define DSRA (HI(0) | LO(59))
234
+ #define DSRA32 (HI(0) | LO(63))
235
+ #define DSRAV (HI(0) | LO(23))
236
+ #define DSRL (HI(0) | LO(58))
237
+ #define DSRL32 (HI(0) | LO(62))
238
+ #define DSRLV (HI(0) | LO(22))
239
+ #define DSUBU (HI(0) | LO(47))
240
+ #define J (HI(2))
241
+ #define JAL (HI(3))
242
+ #define JALR (HI(0) | LO(9))
243
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
244
+ #define JR (HI(0) | LO(9))
245
+ #else /* SLJIT_MIPS_REV < 6 */
246
+ #define JR (HI(0) | LO(8))
247
+ #endif /* SLJIT_MIPS_REV >= 6 */
248
+ #define LD (HI(55))
249
+ #define LDL (HI(26))
250
+ #define LDR (HI(27))
251
+ #define LDC1 (HI(53))
252
+ #define LUI (HI(15))
253
+ #define LW (HI(35))
254
+ #define LWL (HI(34))
255
+ #define LWR (HI(38))
256
+ #define LWC1 (HI(49))
257
+ #define MFC1 (HI(17))
258
+ #if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
259
+ #define MFHC1 (HI(17) | (3 << 21))
260
+ #endif /* SLJIT_MIPS_REV >= 2 */
261
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
262
+ #define MOD (HI(0) | (3 << 6) | LO(26))
263
+ #define MODU (HI(0) | (3 << 6) | LO(27))
264
+ #else /* SLJIT_MIPS_REV < 6 */
265
+ #define MFHI (HI(0) | LO(16))
266
+ #define MFLO (HI(0) | LO(18))
267
+ #endif /* SLJIT_MIPS_REV >= 6 */
268
+ #define MTC1 (HI(17) | (4 << 21))
269
+ #if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
270
+ #define MTHC1 (HI(17) | (7 << 21))
271
+ #endif /* SLJIT_MIPS_REV >= 2 */
272
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
273
+ #define MUH (HI(0) | (3 << 6) | LO(24))
274
+ #define MUHU (HI(0) | (3 << 6) | LO(25))
275
+ #define MUL (HI(0) | (2 << 6) | LO(24))
276
+ #define MULU (HI(0) | (2 << 6) | LO(25))
277
+ #else /* SLJIT_MIPS_REV < 6 */
278
+ #define MULT (HI(0) | LO(24))
279
+ #define MULTU (HI(0) | LO(25))
280
+ #endif /* SLJIT_MIPS_REV >= 6 */
281
+ #define MUL_S (HI(17) | FMT_S | LO(2))
282
+ #define NEG_S (HI(17) | FMT_S | LO(7))
283
+ #define NOP (HI(0) | LO(0))
284
+ #define NOR (HI(0) | LO(39))
285
+ #define OR (HI(0) | LO(37))
286
+ #define ORI (HI(13))
287
+ #if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
288
+ #define ROTR (HI(0) | (1 << 21) | LO(2))
289
+ #define ROTRV (HI(0) | (1 << 6) | LO(6))
290
+ #endif /* SLJIT_MIPS_REV >= 2 */
291
+ #define SD (HI(63))
292
+ #define SDL (HI(44))
293
+ #define SDR (HI(45))
294
+ #define SDC1 (HI(61))
295
+ #define SLT (HI(0) | LO(42))
296
+ #define SLTI (HI(10))
297
+ #define SLTIU (HI(11))
298
+ #define SLTU (HI(0) | LO(43))
299
+ #define SLL (HI(0) | LO(0))
300
+ #define SLLV (HI(0) | LO(4))
301
+ #define SRL (HI(0) | LO(2))
302
+ #define SRLV (HI(0) | LO(6))
303
+ #define SRA (HI(0) | LO(3))
304
+ #define SRAV (HI(0) | LO(7))
305
+ #define SUB_S (HI(17) | FMT_S | LO(1))
306
+ #define SUBU (HI(0) | LO(35))
307
+ #define SW (HI(43))
308
+ #define SWL (HI(42))
309
+ #define SWR (HI(46))
310
+ #define SWC1 (HI(57))
311
+ #define TRUNC_W_S (HI(17) | FMT_S | LO(13))
312
+ #if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
313
+ #define WSBH (HI(31) | (2 << 6) | LO(32))
314
+ #endif /* SLJIT_MIPS_REV >= 2 */
315
+ #define XOR (HI(0) | LO(38))
316
+ #define XORI (HI(14))
317
+
318
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
319
+ #define CLZ (HI(28) | LO(32))
320
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
321
+ #define DCLZ (LO(18))
322
+ #else /* SLJIT_MIPS_REV < 6 */
323
+ #define DCLZ (HI(28) | LO(36))
324
+ #define MOVF (HI(0) | (0 << 16) | LO(1))
325
+ #define MOVF_S (HI(17) | FMT_S | (0 << 16) | LO(17))
326
+ #define MOVN (HI(0) | LO(11))
327
+ #define MOVN_S (HI(17) | FMT_S | LO(19))
328
+ #define MOVT (HI(0) | (1 << 16) | LO(1))
329
+ #define MOVT_S (HI(17) | FMT_S | (1 << 16) | LO(17))
330
+ #define MOVZ (HI(0) | LO(10))
331
+ #define MOVZ_S (HI(17) | FMT_S | LO(18))
332
+ #define MUL (HI(28) | LO(2))
333
+ #endif /* SLJIT_MIPS_REV >= 6 */
334
+ #define PREF (HI(51))
335
+ #define PREFX (HI(19) | LO(15))
336
+ #if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
337
+ #define SEB (HI(31) | (16 << 6) | LO(32))
338
+ #define SEH (HI(31) | (24 << 6) | LO(32))
339
+ #endif /* SLJIT_MIPS_REV >= 2 */
340
+ #endif /* SLJIT_MIPS_REV >= 1 */
341
+
342
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
343
+ #define ADDU_W ADDU
344
+ #define ADDIU_W ADDIU
345
+ #define SLL_W SLL
346
+ #define SRA_W SRA
347
+ #define SUBU_W SUBU
348
+ #define STORE_W SW
349
+ #define LOAD_W LW
350
+ #else
351
+ #define ADDU_W DADDU
352
+ #define ADDIU_W DADDIU
353
+ #define SLL_W DSLL
354
+ #define SRA_W DSRA
355
+ #define SUBU_W DSUBU
356
+ #define STORE_W SD
357
+ #define LOAD_W LD
358
+ #endif
359
+
360
+ #define MOV_fmt(f) (HI(17) | f | LO(6))
361
+
362
+ #define SIMM_MAX (0x7fff)
363
+ #define SIMM_MIN (-0x8000)
364
+ #define UIMM_MAX (0xffff)
365
+
366
+ #define CPU_FEATURE_DETECTED (1 << 0)
367
+ #define CPU_FEATURE_FPU (1 << 1)
368
+ #define CPU_FEATURE_FP64 (1 << 2)
369
+ #define CPU_FEATURE_FR (1 << 3)
370
+
371
+ static sljit_u32 cpu_feature_list = 0;
372
+
373
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
374
+ && (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
375
+
376
+ static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s32 fr, sljit_s32 is_32)
377
+ {
378
+ if (compiler->scratches == -1)
379
+ return 0;
380
+
381
+ if (is_32 && fr >= SLJIT_F64_SECOND(SLJIT_FR0))
382
+ fr -= SLJIT_F64_SECOND(0);
383
+
384
+ return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->fscratches))
385
+ || (fr > (SLJIT_FS0 - compiler->fsaveds) && fr <= SLJIT_FS0)
386
+ || (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS));
387
+ }
388
+
389
+ #endif /* SLJIT_CONFIG_MIPS_32 && SLJIT_ARGUMENT_CHECKS */
390
+
391
+ static void get_cpu_features(void)
392
+ {
393
+ #if !defined(SLJIT_IS_FPU_AVAILABLE) && defined(__GNUC__)
394
+ sljit_u32 fir = 0;
395
+ #endif /* !SLJIT_IS_FPU_AVAILABLE && __GNUC__ */
396
+ sljit_u32 feature_list = CPU_FEATURE_DETECTED;
397
+
398
+ #if defined(SLJIT_IS_FPU_AVAILABLE)
399
+ #if SLJIT_IS_FPU_AVAILABLE
400
+ feature_list |= CPU_FEATURE_FPU;
401
+ #if SLJIT_IS_FPU_AVAILABLE == 64
402
+ feature_list |= CPU_FEATURE_FP64;
403
+ #endif /* SLJIT_IS_FPU_AVAILABLE == 64 */
404
+ #endif /* SLJIT_IS_FPU_AVAILABLE */
405
+ #elif defined(__GNUC__)
406
+ __asm__ ("cfc1 %0, $0" : "=r"(fir));
407
+ if ((fir & (0x3 << 16)) == (0x3 << 16))
408
+ feature_list |= CPU_FEATURE_FPU;
409
+
410
+ #if (defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64) \
411
+ && (!defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV < 2)
412
+ if ((feature_list & CPU_FEATURE_FPU))
413
+ feature_list |= CPU_FEATURE_FP64;
414
+ #else /* SLJIT_CONFIG_MIPS32 || SLJIT_MIPS_REV >= 2 */
415
+ if ((fir & (1 << 22)))
416
+ feature_list |= CPU_FEATURE_FP64;
417
+ #endif /* SLJIT_CONFIG_MIPS_64 && SLJIT_MIPS_REV < 2 */
418
+ #endif /* SLJIT_IS_FPU_AVAILABLE */
419
+
420
+ if ((feature_list & CPU_FEATURE_FPU) && (feature_list & CPU_FEATURE_FP64)) {
421
+ #if defined(SLJIT_CONFIG_MIPS_32) && SLJIT_CONFIG_MIPS_32
422
+ #if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 6
423
+ feature_list |= CPU_FEATURE_FR;
424
+ #elif defined(SLJIT_DETECT_FR) && SLJIT_DETECT_FR == 0
425
+ #if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 5
426
+ feature_list |= CPU_FEATURE_FR;
427
+ #endif /* SLJIT_MIPS_REV >= 5 */
428
+ #else
429
+ sljit_s32 flag = -1;
430
+ #ifndef FR_GET_FP_MODE
431
+ sljit_f64 zero = 0.0;
432
+ #else /* PR_GET_FP_MODE */
433
+ flag = prctl(PR_GET_FP_MODE);
434
+
435
+ if (flag > 0)
436
+ feature_list |= CPU_FEATURE_FR;
437
+ #endif /* FP_GET_PR_MODE */
438
+ #if ((defined(SLJIT_DETECT_FR) && SLJIT_DETECT_FR == 2) \
439
+ || (!defined(PR_GET_FP_MODE) && (!defined(SLJIT_DETECT_FR) || SLJIT_DETECT_FR >= 1))) \
440
+ && (defined(__GNUC__) && (defined(__mips) && __mips >= 2))
441
+ if (flag < 0) {
442
+ __asm__ (".set oddspreg\n"
443
+ "lwc1 $f17, %0\n"
444
+ "ldc1 $f16, %1\n"
445
+ "swc1 $f17, %0\n"
446
+ : "+m" (flag) : "m" (zero) : "$f16", "$f17");
447
+ if (flag)
448
+ feature_list |= CPU_FEATURE_FR;
449
+ }
450
+ #endif /* (!PR_GET_FP_MODE || (PR_GET_FP_MODE && SLJIT_DETECT_FR == 2)) && __GNUC__ */
451
+ #endif /* SLJIT_MIPS_REV >= 6 */
452
+ #else /* !SLJIT_CONFIG_MIPS_32 */
453
+ /* StatusFR=1 is the only mode supported by the code in MIPS64 */
454
+ feature_list |= CPU_FEATURE_FR;
455
+ #endif /* SLJIT_CONFIG_MIPS_32 */
456
+ }
457
+
458
+ cpu_feature_list = feature_list;
459
+ }
460
+
461
+ /* dest_reg is the absolute name of the register
462
+ Useful for reordering instructions in the delay slot. */
463
+ static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 delay_slot)
464
+ {
465
+ sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
466
+ SLJIT_ASSERT(delay_slot == MOVABLE_INS || delay_slot >= UNMOVABLE_INS
467
+ || (sljit_ins)delay_slot == ((ins >> 11) & 0x1f)
468
+ || (sljit_ins)delay_slot == ((ins >> 16) & 0x1f));
469
+ FAIL_IF(!ptr);
470
+ *ptr = ins;
471
+ compiler->size++;
472
+ compiler->delay_slot = delay_slot;
473
+ return SLJIT_SUCCESS;
474
+ }
475
+
476
+ static SLJIT_INLINE sljit_ins invert_branch(sljit_uw flags)
477
+ {
478
+ if (flags & IS_BIT26_COND)
479
+ return (1 << 26);
480
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
481
+ if (flags & IS_BIT23_COND)
482
+ return (1 << 23);
483
+ #endif /* SLJIT_MIPS_REV >= 6 */
484
+ return (1 << 16);
485
+ }
486
+
487
+ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code, sljit_sw executable_offset)
488
+ {
489
+ sljit_sw diff;
490
+ sljit_uw target_addr;
491
+ sljit_ins *inst;
492
+ sljit_ins saved_inst;
493
+
494
+ inst = (sljit_ins *)jump->addr;
495
+
496
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
497
+ if (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_CALL))
498
+ goto exit;
499
+ #else
500
+ if (jump->flags & SLJIT_REWRITABLE_JUMP)
501
+ goto exit;
502
+ #endif
503
+
504
+ if (jump->flags & JUMP_ADDR)
505
+ target_addr = jump->u.target;
506
+ else {
507
+ SLJIT_ASSERT(jump->u.label != NULL);
508
+ target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
509
+ }
510
+
511
+ if (jump->flags & IS_COND)
512
+ inst--;
513
+
514
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
515
+ if (jump->flags & IS_CALL)
516
+ goto preserve_addr;
517
+ #endif
518
+
519
+ /* B instructions. */
520
+ if (jump->flags & IS_MOVABLE) {
521
+ diff = ((sljit_sw)target_addr - (sljit_sw)inst - executable_offset) >> 2;
522
+ if (diff <= SIMM_MAX && diff >= SIMM_MIN) {
523
+ jump->flags |= PATCH_B;
524
+
525
+ if (!(jump->flags & IS_COND)) {
526
+ inst[0] = inst[-1];
527
+ inst[-1] = (jump->flags & IS_JAL) ? BAL : B;
528
+ jump->addr -= sizeof(sljit_ins);
529
+ return inst;
530
+ }
531
+ saved_inst = inst[0];
532
+ inst[0] = inst[-1];
533
+ inst[-1] = saved_inst ^ invert_branch(jump->flags);
534
+ jump->addr -= 2 * sizeof(sljit_ins);
535
+ return inst;
536
+ }
537
+ } else {
538
+ diff = ((sljit_sw)target_addr - (sljit_sw)(inst + 1) - executable_offset) >> 2;
539
+ if (diff <= SIMM_MAX && diff >= SIMM_MIN) {
540
+ jump->flags |= PATCH_B;
541
+
542
+ if (!(jump->flags & IS_COND)) {
543
+ inst[0] = (jump->flags & IS_JAL) ? BAL : B;
544
+ /* Keep inst[1] */
545
+ return inst + 1;
546
+ }
547
+ inst[0] ^= invert_branch(jump->flags);
548
+ inst[1] = NOP;
549
+ jump->addr -= sizeof(sljit_ins);
550
+ return inst + 1;
551
+ }
552
+ }
553
+
554
+ if (jump->flags & IS_COND) {
555
+ if ((jump->flags & IS_MOVABLE) && (target_addr & ~(sljit_uw)0xfffffff) == ((jump->addr + 2 * sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff)) {
556
+ jump->flags |= PATCH_J;
557
+ saved_inst = inst[0];
558
+ inst[0] = inst[-1];
559
+ inst[-1] = (saved_inst & 0xffff0000) | 3;
560
+ inst[1] = J;
561
+ inst[2] = NOP;
562
+ return inst + 2;
563
+ }
564
+ else if ((target_addr & ~(sljit_uw)0xfffffff) == ((jump->addr + 3 * sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff)) {
565
+ jump->flags |= PATCH_J;
566
+ inst[0] = (inst[0] & 0xffff0000) | 3;
567
+ inst[1] = NOP;
568
+ inst[2] = J;
569
+ inst[3] = NOP;
570
+ jump->addr += sizeof(sljit_ins);
571
+ return inst + 3;
572
+ }
573
+ }
574
+ else {
575
+ /* J instuctions. */
576
+ if ((jump->flags & IS_MOVABLE) && (target_addr & ~(sljit_uw)0xfffffff) == (jump->addr & ~(sljit_uw)0xfffffff)) {
577
+ jump->flags |= PATCH_J;
578
+ inst[0] = inst[-1];
579
+ inst[-1] = (jump->flags & IS_JAL) ? JAL : J;
580
+ jump->addr -= sizeof(sljit_ins);
581
+ return inst;
582
+ }
583
+
584
+ if ((target_addr & ~(sljit_uw)0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff)) {
585
+ jump->flags |= PATCH_J;
586
+ inst[0] = (jump->flags & IS_JAL) ? JAL : J;
587
+ /* Keep inst[1] */
588
+ return inst + 1;
589
+ }
590
+ }
591
+
592
+ if (jump->flags & IS_COND)
593
+ inst++;
594
+
595
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
596
+ preserve_addr:
597
+ if (target_addr <= 0x7fffffff) {
598
+ jump->flags |= PATCH_ABS32;
599
+ if (jump->flags & IS_COND)
600
+ inst[-1] -= 4;
601
+
602
+ inst[2] = inst[0];
603
+ inst[3] = inst[1];
604
+ return inst + 3;
605
+ }
606
+ if (target_addr <= 0x7fffffffffffl) {
607
+ jump->flags |= PATCH_ABS48;
608
+ if (jump->flags & IS_COND)
609
+ inst[-1] -= 2;
610
+
611
+ inst[4] = inst[0];
612
+ inst[5] = inst[1];
613
+ return inst + 5;
614
+ }
615
+ #endif
616
+
617
+ exit:
618
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
619
+ inst[2] = inst[0];
620
+ inst[3] = inst[1];
621
+ return inst + 3;
622
+ #else
623
+ inst[6] = inst[0];
624
+ inst[7] = inst[1];
625
+ return inst + 7;
626
+ #endif
627
+ }
628
+
629
+ #ifdef __GNUC__
630
+ static __attribute__ ((noinline)) void sljit_cache_flush(void* code, void* code_ptr)
631
+ {
632
+ SLJIT_CACHE_FLUSH(code, code_ptr);
633
+ }
634
+ #endif
635
+
636
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
637
+
638
+ static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_ins *code, sljit_sw executable_offset)
639
+ {
640
+ sljit_uw addr;
641
+ SLJIT_UNUSED_ARG(executable_offset);
642
+
643
+ if (jump->flags & JUMP_ADDR)
644
+ addr = jump->u.target;
645
+ else
646
+ addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset);
647
+
648
+ if (addr < 0x80000000l) {
649
+ jump->flags |= PATCH_ABS32;
650
+ return 1;
651
+ }
652
+
653
+ if (addr < 0x800000000000l) {
654
+ jump->flags |= PATCH_ABS48;
655
+ return 3;
656
+ }
657
+
658
+ return 5;
659
+ }
660
+
661
+ #endif /* SLJIT_CONFIG_MIPS_64 */
662
+
663
+ static SLJIT_INLINE void load_addr_to_reg(struct sljit_jump *jump)
664
+ {
665
+ sljit_uw flags = jump->flags;
666
+ sljit_ins *ins = (sljit_ins*)jump->addr;
667
+ sljit_uw addr = (flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;
668
+ sljit_u32 reg = (flags & JUMP_MOV_ADDR) ? *ins : PIC_ADDR_REG;
669
+
670
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
671
+ ins[0] = LUI | T(reg) | IMM(addr >> 16);
672
+ #else /* !SLJIT_CONFIG_MIPS_32 */
673
+ if (flags & PATCH_ABS32) {
674
+ SLJIT_ASSERT(addr < 0x80000000l);
675
+ ins[0] = LUI | T(reg) | IMM(addr >> 16);
676
+ }
677
+ else if (flags & PATCH_ABS48) {
678
+ SLJIT_ASSERT(addr < 0x800000000000l);
679
+ ins[0] = LUI | T(reg) | IMM(addr >> 32);
680
+ ins[1] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff);
681
+ ins[2] = DSLL | T(reg) | D(reg) | SH_IMM(16);
682
+ ins += 2;
683
+ }
684
+ else {
685
+ ins[0] = LUI | T(reg) | IMM(addr >> 48);
686
+ ins[1] = ORI | S(reg) | T(reg) | IMM((addr >> 32) & 0xffff);
687
+ ins[2] = DSLL | T(reg) | D(reg) | SH_IMM(16);
688
+ ins[3] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff);
689
+ ins[4] = DSLL | T(reg) | D(reg) | SH_IMM(16);
690
+ ins += 4;
691
+ }
692
+ #endif /* SLJIT_CONFIG_MIPS_32 */
693
+
694
+ ins[1] = ORI | S(reg) | T(reg) | IMM(addr & 0xffff);
695
+ }
696
+
697
+ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)
698
+ {
699
+ struct sljit_memory_fragment *buf;
700
+ sljit_ins *code;
701
+ sljit_ins *code_ptr;
702
+ sljit_ins *buf_ptr;
703
+ sljit_ins *buf_end;
704
+ sljit_uw word_count;
705
+ SLJIT_NEXT_DEFINE_TYPES;
706
+ sljit_sw executable_offset;
707
+ sljit_uw addr;
708
+ struct sljit_label *label;
709
+ struct sljit_jump *jump;
710
+ struct sljit_const *const_;
711
+
712
+ CHECK_ERROR_PTR();
713
+ CHECK_PTR(check_sljit_generate_code(compiler));
714
+ reverse_buf(compiler);
715
+
716
+ code = (sljit_ins*)allocate_executable_memory(compiler->size * sizeof(sljit_ins), options, exec_allocator_data, &executable_offset);
717
+ PTR_FAIL_WITH_EXEC_IF(code);
718
+ buf = compiler->buf;
719
+
720
+ code_ptr = code;
721
+ word_count = 0;
722
+ label = compiler->labels;
723
+ jump = compiler->jumps;
724
+ const_ = compiler->consts;
725
+ SLJIT_NEXT_INIT_TYPES();
726
+ SLJIT_GET_NEXT_MIN();
727
+
728
+ do {
729
+ buf_ptr = (sljit_ins*)buf->memory;
730
+ buf_end = buf_ptr + (buf->used_size >> 2);
731
+ do {
732
+ *code_ptr = *buf_ptr++;
733
+ if (next_min_addr == word_count) {
734
+ SLJIT_ASSERT(!label || label->size >= word_count);
735
+ SLJIT_ASSERT(!jump || jump->addr >= word_count);
736
+ SLJIT_ASSERT(!const_ || const_->addr >= word_count);
737
+
738
+ /* These structures are ordered by their address. */
739
+ if (next_min_addr == next_label_size) {
740
+ label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
741
+ label->size = (sljit_uw)(code_ptr - code);
742
+ label = label->next;
743
+ next_label_size = SLJIT_GET_NEXT_SIZE(label);
744
+ }
745
+
746
+ if (next_min_addr == next_jump_addr) {
747
+ if (!(jump->flags & JUMP_MOV_ADDR)) {
748
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
749
+ word_count += 2;
750
+ #else /* !SLJIT_CONFIG_MIPS_32 */
751
+ word_count += 6;
752
+ #endif /* SLJIT_CONFIG_MIPS_32 */
753
+ jump->addr = (sljit_uw)(code_ptr - 1);
754
+ code_ptr = detect_jump_type(jump, code, executable_offset);
755
+ } else {
756
+ jump->addr = (sljit_uw)code_ptr;
757
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
758
+ code_ptr += 1;
759
+ word_count += 1;
760
+ #else /* !SLJIT_CONFIG_MIPS_32 */
761
+ code_ptr += mov_addr_get_length(jump, code, executable_offset);
762
+ word_count += 5;
763
+ #endif /* SLJIT_CONFIG_MIPS_32 */
764
+ }
765
+
766
+ jump = jump->next;
767
+ next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);
768
+ } else if (next_min_addr == next_const_addr) {
769
+ const_->addr = (sljit_uw)code_ptr;
770
+ const_ = const_->next;
771
+ next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);
772
+ }
773
+
774
+ SLJIT_GET_NEXT_MIN();
775
+ }
776
+ code_ptr++;
777
+ word_count++;
778
+ } while (buf_ptr < buf_end);
779
+
780
+ buf = buf->next;
781
+ } while (buf);
782
+
783
+ if (label && label->size == word_count) {
784
+ label->u.addr = (sljit_uw)code_ptr;
785
+ label->size = (sljit_uw)(code_ptr - code);
786
+ label = label->next;
787
+ }
788
+
789
+ SLJIT_ASSERT(!label);
790
+ SLJIT_ASSERT(!jump);
791
+ SLJIT_ASSERT(!const_);
792
+ SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
793
+
794
+ jump = compiler->jumps;
795
+ while (jump) {
796
+ do {
797
+ addr = (jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;
798
+ buf_ptr = (sljit_ins *)jump->addr;
799
+
800
+ if (jump->flags & PATCH_B) {
801
+ addr = (sljit_uw)((sljit_sw)(addr - (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) - sizeof(sljit_ins)) >> 2);
802
+ SLJIT_ASSERT((sljit_sw)addr <= SIMM_MAX && (sljit_sw)addr >= SIMM_MIN);
803
+ buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((sljit_ins)addr & 0xffff);
804
+ break;
805
+ }
806
+ if (jump->flags & PATCH_J) {
807
+ SLJIT_ASSERT((addr & ~(sljit_uw)0xfffffff)
808
+ == (((sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) + sizeof(sljit_ins)) & ~(sljit_uw)0xfffffff));
809
+ buf_ptr[0] |= (sljit_ins)(addr >> 2) & 0x03ffffff;
810
+ break;
811
+ }
812
+
813
+ load_addr_to_reg(jump);
814
+ } while (0);
815
+
816
+ jump = jump->next;
817
+ }
818
+
819
+ compiler->error = SLJIT_ERR_COMPILED;
820
+ compiler->executable_offset = executable_offset;
821
+ compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins);
822
+
823
+ code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
824
+ code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
825
+
826
+ #ifndef __GNUC__
827
+ SLJIT_CACHE_FLUSH(code, code_ptr);
828
+ #else
829
+ /* GCC workaround for invalid code generation with -O2. */
830
+ sljit_cache_flush(code, code_ptr);
831
+ #endif
832
+ SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
833
+ return code;
834
+ }
835
+
836
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
837
+ {
838
+ switch (feature_type) {
839
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
840
+ && (!defined(SLJIT_IS_FPU_AVAILABLE) || SLJIT_IS_FPU_AVAILABLE)
841
+ case SLJIT_HAS_F64_AS_F32_PAIR:
842
+ if (!cpu_feature_list)
843
+ get_cpu_features();
844
+
845
+ return (cpu_feature_list & CPU_FEATURE_FR) != 0;
846
+ #endif /* SLJIT_CONFIG_MIPS_32 && SLJIT_IS_FPU_AVAILABLE */
847
+ case SLJIT_HAS_FPU:
848
+ if (!cpu_feature_list)
849
+ get_cpu_features();
850
+
851
+ return (cpu_feature_list & CPU_FEATURE_FPU) != 0;
852
+ case SLJIT_HAS_ZERO_REGISTER:
853
+ case SLJIT_HAS_COPY_F32:
854
+ case SLJIT_HAS_COPY_F64:
855
+ return 1;
856
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
857
+ case SLJIT_HAS_CLZ:
858
+ case SLJIT_HAS_CMOV:
859
+ case SLJIT_HAS_PREFETCH:
860
+ return 1;
861
+
862
+ case SLJIT_HAS_CTZ:
863
+ return 2;
864
+ #endif /* SLJIT_MIPS_REV >= 1 */
865
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
866
+ case SLJIT_HAS_REV:
867
+ case SLJIT_HAS_ROT:
868
+ return 1;
869
+ #endif /* SLJIT_MIPS_REV >= 2 */
870
+ default:
871
+ return 0;
872
+ }
873
+ }
874
+
875
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)
876
+ {
877
+ SLJIT_UNUSED_ARG(type);
878
+ return 0;
879
+ }
880
+
881
+ /* --------------------------------------------------------------------- */
882
+ /* Entry, exit */
883
+ /* --------------------------------------------------------------------- */
884
+
885
+ /* Creates an index in data_transfer_insts array. */
886
+ #define LOAD_DATA 0x01
887
+ #define WORD_DATA 0x00
888
+ #define BYTE_DATA 0x02
889
+ #define HALF_DATA 0x04
890
+ #define INT_DATA 0x06
891
+ #define SIGNED_DATA 0x08
892
+ /* Separates integer and floating point registers */
893
+ #define GPR_REG 0x0f
894
+ #define DOUBLE_DATA 0x10
895
+ #define SINGLE_DATA 0x12
896
+
897
+ #define MEM_MASK 0x1f
898
+
899
+ #define ARG_TEST 0x00020
900
+ #define ALT_KEEP_CACHE 0x00040
901
+ #define CUMULATIVE_OP 0x00080
902
+ #define LOGICAL_OP 0x00100
903
+ #define IMM_OP 0x00200
904
+ #define MOVE_OP 0x00400
905
+ #define SRC2_IMM 0x00800
906
+
907
+ #define UNUSED_DEST 0x01000
908
+ #define REG_DEST 0x02000
909
+ #define REG1_SOURCE 0x04000
910
+ #define REG2_SOURCE 0x08000
911
+ #define SLOW_SRC1 0x10000
912
+ #define SLOW_SRC2 0x20000
913
+ #define SLOW_DEST 0x40000
914
+
915
+ static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw);
916
+ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 frame_size, sljit_ins *ins_ptr);
917
+
918
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
919
+ #define SELECT_OP(d, w) (w)
920
+ #else
921
+ #define SELECT_OP(d, w) (!(op & SLJIT_32) ? (d) : (w))
922
+ #endif
923
+
924
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
925
+ #include "sljitNativeMIPS_32.c"
926
+ #else
927
+ #include "sljitNativeMIPS_64.c"
928
+ #endif
929
+
930
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
931
+ sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
932
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
933
+ {
934
+ sljit_ins base;
935
+ sljit_s32 i, tmp, offset;
936
+ sljit_s32 arg_count, word_arg_count, float_arg_count;
937
+ sljit_s32 saved_arg_count = SLJIT_KEPT_SAVEDS_COUNT(options);
938
+
939
+ CHECK_ERROR();
940
+ CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
941
+ set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
942
+
943
+ local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 1);
944
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
945
+ if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
946
+ if ((local_size & SSIZE_OF(sw)) != 0)
947
+ local_size += SSIZE_OF(sw);
948
+ local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);
949
+ }
950
+
951
+ local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;
952
+ #else
953
+ local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);
954
+ local_size = (local_size + SLJIT_LOCALS_OFFSET + 31) & ~0x1f;
955
+ #endif
956
+ compiler->local_size = local_size;
957
+
958
+ offset = 0;
959
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
960
+ if (!(options & SLJIT_ENTER_REG_ARG)) {
961
+ tmp = arg_types >> SLJIT_ARG_SHIFT;
962
+ arg_count = 0;
963
+
964
+ while (tmp) {
965
+ offset = arg_count;
966
+ if ((tmp & SLJIT_ARG_MASK) == SLJIT_ARG_TYPE_F64) {
967
+ if ((arg_count & 0x1) != 0)
968
+ arg_count++;
969
+ arg_count++;
970
+ }
971
+
972
+ arg_count++;
973
+ tmp >>= SLJIT_ARG_SHIFT;
974
+ }
975
+
976
+ compiler->args_size = (sljit_uw)arg_count << 2;
977
+ offset = (offset >= 4) ? (offset << 2) : 0;
978
+ }
979
+ #endif /* SLJIT_CONFIG_MIPS_32 */
980
+
981
+ if (local_size + offset <= -SIMM_MIN) {
982
+ /* Frequent case. */
983
+ FAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(-local_size), DR(SLJIT_SP)));
984
+ base = S(SLJIT_SP);
985
+ offset = local_size - SSIZE_OF(sw);
986
+ } else {
987
+ FAIL_IF(load_immediate(compiler, OTHER_FLAG, local_size));
988
+ FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
989
+ FAIL_IF(push_inst(compiler, SUBU_W | S(SLJIT_SP) | TA(OTHER_FLAG) | D(SLJIT_SP), DR(SLJIT_SP)));
990
+ base = S(TMP_REG1);
991
+ offset = -SSIZE_OF(sw);
992
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
993
+ local_size = 0;
994
+ #endif
995
+ }
996
+
997
+ FAIL_IF(push_inst(compiler, STORE_W | base | TA(RETURN_ADDR_REG) | IMM(offset), UNMOVABLE_INS));
998
+
999
+ tmp = SLJIT_S0 - saveds;
1000
+ for (i = SLJIT_S0 - saved_arg_count; i > tmp; i--) {
1001
+ offset -= SSIZE_OF(sw);
1002
+ FAIL_IF(push_inst(compiler, STORE_W | base | T(i) | IMM(offset), MOVABLE_INS));
1003
+ }
1004
+
1005
+ for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
1006
+ offset -= SSIZE_OF(sw);
1007
+ FAIL_IF(push_inst(compiler, STORE_W | base | T(i) | IMM(offset), MOVABLE_INS));
1008
+ }
1009
+
1010
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1011
+ /* This alignment is valid because offset is not used after storing FPU regs. */
1012
+ if ((offset & SSIZE_OF(sw)) != 0)
1013
+ offset -= SSIZE_OF(sw);
1014
+ #endif
1015
+
1016
+ tmp = SLJIT_FS0 - fsaveds;
1017
+ for (i = SLJIT_FS0; i > tmp; i--) {
1018
+ offset -= SSIZE_OF(f64);
1019
+ FAIL_IF(push_inst(compiler, SDC1 | base | FT(i) | IMM(offset), MOVABLE_INS));
1020
+ }
1021
+
1022
+ for (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
1023
+ offset -= SSIZE_OF(f64);
1024
+ FAIL_IF(push_inst(compiler, SDC1 | base | FT(i) | IMM(offset), MOVABLE_INS));
1025
+ }
1026
+
1027
+ if (options & SLJIT_ENTER_REG_ARG)
1028
+ return SLJIT_SUCCESS;
1029
+
1030
+ arg_types >>= SLJIT_ARG_SHIFT;
1031
+ arg_count = 0;
1032
+ word_arg_count = 0;
1033
+ float_arg_count = 0;
1034
+
1035
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1036
+ /* The first maximum two floating point arguments are passed in floating point
1037
+ registers if no integer argument precedes them. The first 16 byte data is
1038
+ passed in four integer registers, the rest is placed onto the stack.
1039
+ The floating point registers are also part of the first 16 byte data, so
1040
+ their corresponding integer registers are not used when they are present. */
1041
+
1042
+ while (arg_types) {
1043
+ switch (arg_types & SLJIT_ARG_MASK) {
1044
+ case SLJIT_ARG_TYPE_F64:
1045
+ float_arg_count++;
1046
+ if ((arg_count & 0x1) != 0)
1047
+ arg_count++;
1048
+
1049
+ if (word_arg_count == 0 && float_arg_count <= 2) {
1050
+ if (float_arg_count == 1)
1051
+ FAIL_IF(push_inst(compiler, MOV_fmt(FMT_D) | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
1052
+ } else if (arg_count < 4) {
1053
+ FAIL_IF(push_inst(compiler, MTC1 | TA(4 + arg_count) | FS(float_arg_count), MOVABLE_INS));
1054
+ switch (cpu_feature_list & CPU_FEATURE_FR) {
1055
+ #if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
1056
+ case CPU_FEATURE_FR:
1057
+ FAIL_IF(push_inst(compiler, MTHC1 | TA(5 + arg_count) | FS(float_arg_count), MOVABLE_INS));
1058
+ break;
1059
+ #endif /* SLJIT_MIPS_REV >= 2 */
1060
+ default:
1061
+ FAIL_IF(push_inst(compiler, MTC1 | TA(5 + arg_count) | FS(float_arg_count) | (1 << 11), MOVABLE_INS));
1062
+ break;
1063
+ }
1064
+ } else
1065
+ FAIL_IF(push_inst(compiler, LDC1 | base | FT(float_arg_count) | IMM(local_size + (arg_count << 2)), MOVABLE_INS));
1066
+ arg_count++;
1067
+ break;
1068
+ case SLJIT_ARG_TYPE_F32:
1069
+ float_arg_count++;
1070
+
1071
+ if (word_arg_count == 0 && float_arg_count <= 2) {
1072
+ if (float_arg_count == 1)
1073
+ FAIL_IF(push_inst(compiler, MOV_fmt(FMT_S) | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
1074
+ } else if (arg_count < 4)
1075
+ FAIL_IF(push_inst(compiler, MTC1 | TA(4 + arg_count) | FS(float_arg_count), MOVABLE_INS));
1076
+ else
1077
+ FAIL_IF(push_inst(compiler, LWC1 | base | FT(float_arg_count) | IMM(local_size + (arg_count << 2)), MOVABLE_INS));
1078
+ break;
1079
+ default:
1080
+ word_arg_count++;
1081
+
1082
+ if (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {
1083
+ tmp = SLJIT_S0 - saved_arg_count;
1084
+ saved_arg_count++;
1085
+ } else if (word_arg_count != arg_count + 1 || arg_count == 0)
1086
+ tmp = word_arg_count;
1087
+ else
1088
+ break;
1089
+
1090
+ if (arg_count < 4)
1091
+ FAIL_IF(push_inst(compiler, ADDU_W | SA(4 + arg_count) | TA(0) | D(tmp), DR(tmp)));
1092
+ else
1093
+ FAIL_IF(push_inst(compiler, LW | base | T(tmp) | IMM(local_size + (arg_count << 2)), DR(tmp)));
1094
+ break;
1095
+ }
1096
+ arg_count++;
1097
+ arg_types >>= SLJIT_ARG_SHIFT;
1098
+ }
1099
+
1100
+ SLJIT_ASSERT(compiler->args_size == (sljit_uw)arg_count << 2);
1101
+ #else /* !SLJIT_CONFIG_MIPS_32 */
1102
+ while (arg_types) {
1103
+ arg_count++;
1104
+ switch (arg_types & SLJIT_ARG_MASK) {
1105
+ case SLJIT_ARG_TYPE_F64:
1106
+ float_arg_count++;
1107
+ if (arg_count != float_arg_count)
1108
+ FAIL_IF(push_inst(compiler, MOV_fmt(FMT_D) | FS(arg_count) | FD(float_arg_count), MOVABLE_INS));
1109
+ else if (arg_count == 1)
1110
+ FAIL_IF(push_inst(compiler, MOV_fmt(FMT_D) | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
1111
+ break;
1112
+ case SLJIT_ARG_TYPE_F32:
1113
+ float_arg_count++;
1114
+ if (arg_count != float_arg_count)
1115
+ FAIL_IF(push_inst(compiler, MOV_fmt(FMT_S) | FS(arg_count) | FD(float_arg_count), MOVABLE_INS));
1116
+ else if (arg_count == 1)
1117
+ FAIL_IF(push_inst(compiler, MOV_fmt(FMT_S) | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS));
1118
+ break;
1119
+ default:
1120
+ word_arg_count++;
1121
+
1122
+ if (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {
1123
+ tmp = SLJIT_S0 - saved_arg_count;
1124
+ saved_arg_count++;
1125
+ } else if (word_arg_count != arg_count || word_arg_count <= 1)
1126
+ tmp = word_arg_count;
1127
+ else
1128
+ break;
1129
+
1130
+ FAIL_IF(push_inst(compiler, ADDU_W | SA(3 + arg_count) | TA(0) | D(tmp), DR(tmp)));
1131
+ break;
1132
+ }
1133
+ arg_types >>= SLJIT_ARG_SHIFT;
1134
+ }
1135
+ #endif /* SLJIT_CONFIG_MIPS_32 */
1136
+
1137
+ return SLJIT_SUCCESS;
1138
+ }
1139
+
1140
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
1141
+ sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
1142
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
1143
+ {
1144
+ CHECK_ERROR();
1145
+ CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
1146
+ set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
1147
+
1148
+ local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1);
1149
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1150
+ if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
1151
+ if ((local_size & SSIZE_OF(sw)) != 0)
1152
+ local_size += SSIZE_OF(sw);
1153
+ local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);
1154
+ }
1155
+
1156
+ compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf;
1157
+ #else
1158
+ local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);
1159
+ compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 31) & ~0x1f;
1160
+ #endif
1161
+ return SLJIT_SUCCESS;
1162
+ }
1163
+
1164
+ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 frame_size, sljit_ins *ins_ptr)
1165
+ {
1166
+ sljit_s32 local_size, i, tmp, offset;
1167
+ sljit_s32 load_return_addr = (frame_size == 0);
1168
+ sljit_s32 scratches = compiler->scratches;
1169
+ sljit_s32 saveds = compiler->saveds;
1170
+ sljit_s32 fsaveds = compiler->fsaveds;
1171
+ sljit_s32 fscratches = compiler->fscratches;
1172
+ sljit_s32 kept_saveds_count = SLJIT_KEPT_SAVEDS_COUNT(compiler->options);
1173
+
1174
+ SLJIT_ASSERT(frame_size == 1 || (frame_size & 0xf) == 0);
1175
+ frame_size &= ~0xf;
1176
+
1177
+ local_size = compiler->local_size;
1178
+
1179
+ tmp = GET_SAVED_REGISTERS_SIZE(scratches, saveds - kept_saveds_count, 1);
1180
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1181
+ if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) {
1182
+ if ((tmp & SSIZE_OF(sw)) != 0)
1183
+ tmp += SSIZE_OF(sw);
1184
+ tmp += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);
1185
+ }
1186
+ #else
1187
+ tmp += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64);
1188
+ #endif
1189
+
1190
+ if (local_size <= SIMM_MAX) {
1191
+ if (local_size < frame_size) {
1192
+ FAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(local_size - frame_size), DR(SLJIT_SP)));
1193
+ local_size = frame_size;
1194
+ }
1195
+ } else {
1196
+ if (tmp < frame_size)
1197
+ tmp = frame_size;
1198
+
1199
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG2), local_size - tmp));
1200
+ FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | T(TMP_REG2) | D(SLJIT_SP), DR(SLJIT_SP)));
1201
+ local_size = tmp;
1202
+ }
1203
+
1204
+ SLJIT_ASSERT(local_size >= frame_size);
1205
+
1206
+ offset = local_size - SSIZE_OF(sw);
1207
+ if (load_return_addr)
1208
+ FAIL_IF(push_inst(compiler, LOAD_W | S(SLJIT_SP) | TA(RETURN_ADDR_REG) | IMM(offset), RETURN_ADDR_REG));
1209
+
1210
+ tmp = SLJIT_S0 - saveds;
1211
+ for (i = SLJIT_S0 - kept_saveds_count; i > tmp; i--) {
1212
+ offset -= SSIZE_OF(sw);
1213
+ FAIL_IF(push_inst(compiler, LOAD_W | S(SLJIT_SP) | T(i) | IMM(offset), MOVABLE_INS));
1214
+ }
1215
+
1216
+ for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
1217
+ offset -= SSIZE_OF(sw);
1218
+ FAIL_IF(push_inst(compiler, LOAD_W | S(SLJIT_SP) | T(i) | IMM(offset), MOVABLE_INS));
1219
+ }
1220
+
1221
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1222
+ /* This alignment is valid because offset is not used after storing FPU regs. */
1223
+ if ((offset & SSIZE_OF(sw)) != 0)
1224
+ offset -= SSIZE_OF(sw);
1225
+ #endif
1226
+
1227
+ tmp = SLJIT_FS0 - fsaveds;
1228
+ for (i = SLJIT_FS0; i > tmp; i--) {
1229
+ offset -= SSIZE_OF(f64);
1230
+ FAIL_IF(push_inst(compiler, LDC1 | S(SLJIT_SP) | FT(i) | IMM(offset), MOVABLE_INS));
1231
+ }
1232
+
1233
+ for (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
1234
+ offset -= SSIZE_OF(f64);
1235
+ FAIL_IF(push_inst(compiler, LDC1 | S(SLJIT_SP) | FT(i) | IMM(offset), MOVABLE_INS));
1236
+ }
1237
+
1238
+ if (local_size > frame_size)
1239
+ *ins_ptr = ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(local_size - frame_size);
1240
+ else
1241
+ *ins_ptr = NOP;
1242
+
1243
+ return SLJIT_SUCCESS;
1244
+ }
1245
+
1246
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)
1247
+ {
1248
+ sljit_ins ins;
1249
+
1250
+ CHECK_ERROR();
1251
+ CHECK(check_sljit_emit_return_void(compiler));
1252
+
1253
+ emit_stack_frame_release(compiler, 0, &ins);
1254
+
1255
+ FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
1256
+ return push_inst(compiler, ins, UNMOVABLE_INS);
1257
+ }
1258
+
1259
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,
1260
+ sljit_s32 src, sljit_sw srcw)
1261
+ {
1262
+ sljit_ins ins;
1263
+
1264
+ CHECK_ERROR();
1265
+ CHECK(check_sljit_emit_return_to(compiler, src, srcw));
1266
+
1267
+ if (src & SLJIT_MEM) {
1268
+ ADJUST_LOCAL_OFFSET(src, srcw);
1269
+ FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(PIC_ADDR_REG), src, srcw));
1270
+ src = PIC_ADDR_REG;
1271
+ srcw = 0;
1272
+ } else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
1273
+ FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG)));
1274
+ src = PIC_ADDR_REG;
1275
+ srcw = 0;
1276
+ }
1277
+
1278
+ FAIL_IF(emit_stack_frame_release(compiler, 1, &ins));
1279
+
1280
+ if (src != SLJIT_IMM) {
1281
+ FAIL_IF(push_inst(compiler, JR | S(src), UNMOVABLE_INS));
1282
+ return push_inst(compiler, ins, UNMOVABLE_INS);
1283
+ }
1284
+
1285
+ if (ins != NOP)
1286
+ FAIL_IF(push_inst(compiler, ins, MOVABLE_INS));
1287
+
1288
+ SLJIT_SKIP_CHECKS(compiler);
1289
+ return sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);
1290
+ }
1291
+
1292
+ /* --------------------------------------------------------------------- */
1293
+ /* Operators */
1294
+ /* --------------------------------------------------------------------- */
1295
+
1296
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1297
+ #define ARCH_32_64(a, b) a
1298
+ #else
1299
+ #define ARCH_32_64(a, b) b
1300
+ #endif
1301
+
1302
+ static const sljit_ins data_transfer_insts[16 + 4] = {
1303
+ /* u w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */),
1304
+ /* u w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */),
1305
+ /* u b s */ HI(40) /* sb */,
1306
+ /* u b l */ HI(36) /* lbu */,
1307
+ /* u h s */ HI(41) /* sh */,
1308
+ /* u h l */ HI(37) /* lhu */,
1309
+ /* u i s */ HI(43) /* sw */,
1310
+ /* u i l */ ARCH_32_64(HI(35) /* lw */, HI(39) /* lwu */),
1311
+
1312
+ /* s w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */),
1313
+ /* s w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */),
1314
+ /* s b s */ HI(40) /* sb */,
1315
+ /* s b l */ HI(32) /* lb */,
1316
+ /* s h s */ HI(41) /* sh */,
1317
+ /* s h l */ HI(33) /* lh */,
1318
+ /* s i s */ HI(43) /* sw */,
1319
+ /* s i l */ HI(35) /* lw */,
1320
+
1321
+ /* d s */ HI(61) /* sdc1 */,
1322
+ /* d l */ HI(53) /* ldc1 */,
1323
+ /* s s */ HI(57) /* swc1 */,
1324
+ /* s l */ HI(49) /* lwc1 */,
1325
+ };
1326
+
1327
+ #undef ARCH_32_64
1328
+
1329
+ /* reg_ar is an absoulute register! */
1330
+
1331
+ /* Can perform an operation using at most 1 instruction. */
1332
+ static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw)
1333
+ {
1334
+ SLJIT_ASSERT(arg & SLJIT_MEM);
1335
+
1336
+ if (!(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN) {
1337
+ /* Works for both absoulte and relative addresses. */
1338
+ if (SLJIT_UNLIKELY(flags & ARG_TEST))
1339
+ return 1;
1340
+ FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(arg & REG_MASK)
1341
+ | TA(reg_ar) | IMM(argw), ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? reg_ar : MOVABLE_INS));
1342
+ return -1;
1343
+ }
1344
+ return 0;
1345
+ }
1346
+
1347
+ #define TO_ARGW_HI(argw) (((argw) & ~0xffff) + (((argw) & 0x8000) ? 0x10000 : 0))
1348
+
1349
+ /* See getput_arg below.
1350
+ Note: can_cache is called only for binary operators. */
1351
+ static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
1352
+ {
1353
+ SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));
1354
+
1355
+ /* Simple operation except for updates. */
1356
+ if (arg & OFFS_REG_MASK) {
1357
+ argw &= 0x3;
1358
+ next_argw &= 0x3;
1359
+ if (argw && argw == next_argw && (arg == next_arg || (arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK)))
1360
+ return 1;
1361
+ return 0;
1362
+ }
1363
+
1364
+ if (arg == next_arg) {
1365
+ if (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN)
1366
+ || TO_ARGW_HI(argw) == TO_ARGW_HI(next_argw))
1367
+ return 1;
1368
+ return 0;
1369
+ }
1370
+
1371
+ return 0;
1372
+ }
1373
+
1374
+ /* Emit the necessary instructions. See can_cache above. */
1375
+ static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
1376
+ {
1377
+ sljit_s32 tmp_ar, base, delay_slot;
1378
+ sljit_sw offset, argw_hi;
1379
+
1380
+ SLJIT_ASSERT(arg & SLJIT_MEM);
1381
+ if (!(next_arg & SLJIT_MEM)) {
1382
+ next_arg = 0;
1383
+ next_argw = 0;
1384
+ }
1385
+
1386
+ /* Since tmp can be the same as base or offset registers,
1387
+ * these might be unavailable after modifying tmp. */
1388
+ if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) {
1389
+ tmp_ar = reg_ar;
1390
+ delay_slot = reg_ar;
1391
+ }
1392
+ else {
1393
+ tmp_ar = DR(TMP_REG1);
1394
+ delay_slot = MOVABLE_INS;
1395
+ }
1396
+ base = arg & REG_MASK;
1397
+
1398
+ if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
1399
+ argw &= 0x3;
1400
+
1401
+ /* Using the cache. */
1402
+ if (argw == compiler->cache_argw) {
1403
+ if (arg == compiler->cache_arg)
1404
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);
1405
+
1406
+ if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) {
1407
+ if (arg == next_arg && argw == (next_argw & 0x3)) {
1408
+ compiler->cache_arg = arg;
1409
+ compiler->cache_argw = argw;
1410
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(TMP_REG3), DR(TMP_REG3)));
1411
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot);
1412
+ }
1413
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | DA(tmp_ar), tmp_ar));
1414
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
1415
+ }
1416
+ }
1417
+
1418
+ if (SLJIT_UNLIKELY(argw)) {
1419
+ compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK);
1420
+ compiler->cache_argw = argw;
1421
+ FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | D(TMP_REG3) | SH_IMM(argw), DR(TMP_REG3)));
1422
+ }
1423
+
1424
+ if (arg == next_arg && argw == (next_argw & 0x3)) {
1425
+ compiler->cache_arg = arg;
1426
+ compiler->cache_argw = argw;
1427
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | D(TMP_REG3), DR(TMP_REG3)));
1428
+ tmp_ar = DR(TMP_REG3);
1429
+ }
1430
+ else
1431
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? OFFS_REG(arg) : TMP_REG3) | DA(tmp_ar), tmp_ar));
1432
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
1433
+ }
1434
+
1435
+ if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN)
1436
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar) | IMM(argw - compiler->cache_argw), delay_slot);
1437
+
1438
+ if (compiler->cache_arg == SLJIT_MEM && (argw - compiler->cache_argw) <= SIMM_MAX && (argw - compiler->cache_argw) >= SIMM_MIN) {
1439
+ offset = argw - compiler->cache_argw;
1440
+ } else {
1441
+ compiler->cache_arg = SLJIT_MEM;
1442
+
1443
+ argw_hi = TO_ARGW_HI(argw);
1444
+
1445
+ if (next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN && argw_hi != TO_ARGW_HI(next_argw)) {
1446
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw));
1447
+ compiler->cache_argw = argw;
1448
+ offset = 0;
1449
+ } else {
1450
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw_hi));
1451
+ compiler->cache_argw = argw_hi;
1452
+ offset = argw & 0xffff;
1453
+ argw = argw_hi;
1454
+ }
1455
+ }
1456
+
1457
+ if (!base)
1458
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar) | IMM(offset), delay_slot);
1459
+
1460
+ if (arg == next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN) {
1461
+ compiler->cache_arg = arg;
1462
+ FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | D(TMP_REG3), DR(TMP_REG3)));
1463
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar) | IMM(offset), delay_slot);
1464
+ }
1465
+
1466
+ FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | DA(tmp_ar), tmp_ar));
1467
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar) | IMM(offset), delay_slot);
1468
+ }
1469
+
1470
+ static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw)
1471
+ {
1472
+ sljit_s32 tmp_ar, base, delay_slot;
1473
+
1474
+ if (getput_arg_fast(compiler, flags, reg_ar, arg, argw))
1475
+ return compiler->error;
1476
+
1477
+ if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) {
1478
+ tmp_ar = reg_ar;
1479
+ delay_slot = reg_ar;
1480
+ }
1481
+ else {
1482
+ tmp_ar = DR(TMP_REG1);
1483
+ delay_slot = MOVABLE_INS;
1484
+ }
1485
+ base = arg & REG_MASK;
1486
+
1487
+ if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
1488
+ argw &= 0x3;
1489
+
1490
+ if (SLJIT_UNLIKELY(argw)) {
1491
+ FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | DA(tmp_ar) | SH_IMM(argw), tmp_ar));
1492
+ FAIL_IF(push_inst(compiler, ADDU_W | SA(tmp_ar) | T(base) | DA(tmp_ar), tmp_ar));
1493
+ }
1494
+ else
1495
+ FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(OFFS_REG(arg)) | DA(tmp_ar), tmp_ar));
1496
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
1497
+ }
1498
+
1499
+ FAIL_IF(load_immediate(compiler, tmp_ar, TO_ARGW_HI(argw)));
1500
+
1501
+ if (base != 0)
1502
+ FAIL_IF(push_inst(compiler, ADDU_W | SA(tmp_ar) | T(base) | DA(tmp_ar), tmp_ar));
1503
+
1504
+ return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar) | IMM(argw), delay_slot);
1505
+ }
1506
+
1507
+ static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
1508
+ {
1509
+ if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
1510
+ return compiler->error;
1511
+ return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
1512
+ }
1513
+
1514
+ #define EMIT_LOGICAL(op_imm, op_reg) \
1515
+ if (flags & SRC2_IMM) { \
1516
+ if (op & SLJIT_SET_Z) \
1517
+ FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \
1518
+ if (!(flags & UNUSED_DEST)) \
1519
+ FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \
1520
+ } \
1521
+ else { \
1522
+ if (op & SLJIT_SET_Z) \
1523
+ FAIL_IF(push_inst(compiler, op_reg | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
1524
+ if (!(flags & UNUSED_DEST)) \
1525
+ FAIL_IF(push_inst(compiler, op_reg | S(src1) | T(src2) | D(dst), DR(dst))); \
1526
+ }
1527
+
1528
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1529
+
1530
+ #define EMIT_SHIFT(dimm, dimm32, imm, dv, v) \
1531
+ op_imm = (imm); \
1532
+ op_v = (v);
1533
+
1534
+ #else /* !SLJIT_CONFIG_MIPS_32 */
1535
+
1536
+
1537
+ #define EMIT_SHIFT(dimm, dimm32, imm, dv, v) \
1538
+ op_dimm = (dimm); \
1539
+ op_dimm32 = (dimm32); \
1540
+ op_imm = (imm); \
1541
+ op_dv = (dv); \
1542
+ op_v = (v);
1543
+
1544
+ #endif /* SLJIT_CONFIG_MIPS_32 */
1545
+
1546
+ #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV < 1)
1547
+
1548
+ static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src)
1549
+ {
1550
+ sljit_s32 is_clz = (GET_OPCODE(op) == SLJIT_CLZ);
1551
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1552
+ sljit_ins word_size = (op & SLJIT_32) ? 32 : 64;
1553
+ #else /* !SLJIT_CONFIG_MIPS_64 */
1554
+ sljit_ins word_size = 32;
1555
+ #endif /* SLJIT_CONFIG_MIPS_64 */
1556
+
1557
+ /* The TMP_REG2 is the next value. */
1558
+ if (src != TMP_REG2)
1559
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
1560
+
1561
+ FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG2) | TA(0) | IMM(is_clz ? 13 : 14), UNMOVABLE_INS));
1562
+ /* The OTHER_FLAG is the counter. Delay slot. */
1563
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OTHER_FLAG) | IMM(word_size), OTHER_FLAG));
1564
+
1565
+ if (!is_clz) {
1566
+ FAIL_IF(push_inst(compiler, ANDI | S(TMP_REG2) | T(TMP_REG1) | IMM(1), DR(TMP_REG1)));
1567
+ FAIL_IF(push_inst(compiler, BNE | S(TMP_REG1) | TA(0) | IMM(11), UNMOVABLE_INS));
1568
+ } else
1569
+ FAIL_IF(push_inst(compiler, BLTZ | S(TMP_REG2) | TA(0) | IMM(11), UNMOVABLE_INS));
1570
+
1571
+ /* Delay slot. */
1572
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OTHER_FLAG) | IMM(0), OTHER_FLAG));
1573
+
1574
+ /* The TMP_REG1 is the next shift. */
1575
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | T(TMP_REG1) | IMM(word_size), DR(TMP_REG1)));
1576
+
1577
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(TMP_REG2) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));
1578
+ FAIL_IF(push_inst(compiler, SELECT_OP(DSRL, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1)));
1579
+
1580
+ FAIL_IF(push_inst(compiler, (is_clz ? SELECT_OP(DSRLV, SRLV) : SELECT_OP(DSLLV, SLLV)) | S(TMP_REG1) | TA(EQUAL_FLAG) | D(TMP_REG2), DR(TMP_REG2)));
1581
+ FAIL_IF(push_inst(compiler, BNE | S(TMP_REG2) | TA(0) | IMM(-4), UNMOVABLE_INS));
1582
+ /* Delay slot. */
1583
+ FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
1584
+
1585
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(TMP_REG1) | T(TMP_REG2) | IMM(-1), DR(TMP_REG2)));
1586
+ FAIL_IF(push_inst(compiler, (is_clz ? SELECT_OP(DSRLV, SRLV) : SELECT_OP(DSLLV, SLLV)) | S(TMP_REG2) | TA(EQUAL_FLAG) | D(TMP_REG2), DR(TMP_REG2)));
1587
+
1588
+ FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG2) | TA(0) | IMM(-7), UNMOVABLE_INS));
1589
+ /* Delay slot. */
1590
+ FAIL_IF(push_inst(compiler, OR | SA(OTHER_FLAG) | T(TMP_REG1) | DA(OTHER_FLAG), OTHER_FLAG));
1591
+
1592
+ return push_inst(compiler, SELECT_OP(DADDU, ADDU) | SA(OTHER_FLAG) | TA(0) | D(dst), DR(dst));
1593
+ }
1594
+
1595
+ #endif /* SLJIT_MIPS_REV < 1 */
1596
+
1597
+ static sljit_s32 emit_rev(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src)
1598
+ {
1599
+ #if defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64
1600
+ int is_32 = (op & SLJIT_32);
1601
+ #endif /* SLJIT_CONFIG_MIPS_64 */
1602
+
1603
+ op = GET_OPCODE(op);
1604
+ #if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
1605
+ #if defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64
1606
+ if (!is_32 && (op == SLJIT_REV)) {
1607
+ FAIL_IF(push_inst(compiler, DSBH | T(src) | D(dst), DR(dst)));
1608
+ return push_inst(compiler, DSHD | T(dst) | D(dst), DR(dst));
1609
+ }
1610
+ if (op != SLJIT_REV && src != TMP_REG2) {
1611
+ FAIL_IF(push_inst(compiler, SLL | T(src) | D(TMP_REG1), DR(TMP_REG1)));
1612
+ src = TMP_REG1;
1613
+ }
1614
+ #endif /* SLJIT_CONFIG_MIPS_64 */
1615
+ FAIL_IF(push_inst(compiler, WSBH | T(src) | D(dst), DR(dst)));
1616
+ FAIL_IF(push_inst(compiler, ROTR | T(dst) | D(dst) | SH_IMM(16), DR(dst)));
1617
+ #if defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64
1618
+ if (op == SLJIT_REV_U32 && dst != TMP_REG2 && dst != TMP_REG3)
1619
+ FAIL_IF(push_inst(compiler, DINSU | T(dst) | SA(0) | (31 << 11), DR(dst)));
1620
+ #endif /* SLJIT_CONFIG_MIPS_64 */
1621
+ #else /* SLJIT_MIPS_REV < 2 */
1622
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1623
+ if (!is_32) {
1624
+ FAIL_IF(push_inst(compiler, DSRL32 | T(src) | D(TMP_REG1) | SH_IMM(0), DR(TMP_REG1)));
1625
+ FAIL_IF(push_inst(compiler, ORI | SA(0) | TA(OTHER_FLAG) | 0xffff, OTHER_FLAG));
1626
+ FAIL_IF(push_inst(compiler, DSLL32 | T(src) | D(dst) | SH_IMM(0), DR(dst)));
1627
+ FAIL_IF(push_inst(compiler, DSLL32 | TA(OTHER_FLAG) | DA(OTHER_FLAG) | SH_IMM(0), OTHER_FLAG));
1628
+ FAIL_IF(push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst)));
1629
+
1630
+ FAIL_IF(push_inst(compiler, DSRL | T(dst) | D(TMP_REG1) | SH_IMM(16), DR(TMP_REG1)));
1631
+ FAIL_IF(push_inst(compiler, ORI | SA(OTHER_FLAG) | TA(OTHER_FLAG) | 0xffff, OTHER_FLAG));
1632
+ FAIL_IF(push_inst(compiler, AND | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));
1633
+ FAIL_IF(push_inst(compiler, AND | S(TMP_REG1) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
1634
+ FAIL_IF(push_inst(compiler, DSLL | TA(OTHER_FLAG) | DA(EQUAL_FLAG) | SH_IMM(8), EQUAL_FLAG));
1635
+ FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst)));
1636
+ FAIL_IF(push_inst(compiler, XOR | SA(OTHER_FLAG) | TA(EQUAL_FLAG) | DA(OTHER_FLAG), OTHER_FLAG));
1637
+ FAIL_IF(push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst)));
1638
+
1639
+ FAIL_IF(push_inst(compiler, DSRL | T(dst) | D(TMP_REG1) | SH_IMM(8), DR(TMP_REG1)));
1640
+ FAIL_IF(push_inst(compiler, AND | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));
1641
+ FAIL_IF(push_inst(compiler, AND | S(TMP_REG1) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
1642
+ FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(8), DR(dst)));
1643
+ return push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst));
1644
+ }
1645
+
1646
+ if (op != SLJIT_REV && src != TMP_REG2) {
1647
+ FAIL_IF(push_inst(compiler, SLL | T(src) | D(TMP_REG2) | SH_IMM(0), DR(TMP_REG2)));
1648
+ src = TMP_REG2;
1649
+ }
1650
+ #endif /* SLJIT_CONFIG_MIPS_64 */
1651
+
1652
+ FAIL_IF(push_inst(compiler, SRL | T(src) | D(TMP_REG1) | SH_IMM(16), DR(TMP_REG1)));
1653
+ FAIL_IF(push_inst(compiler, LUI | TA(OTHER_FLAG) | 0xff, OTHER_FLAG));
1654
+ FAIL_IF(push_inst(compiler, SLL | T(src) | D(dst) | SH_IMM(16), DR(dst)));
1655
+ FAIL_IF(push_inst(compiler, ORI | SA(OTHER_FLAG) | TA(OTHER_FLAG) | 0xff, OTHER_FLAG));
1656
+ FAIL_IF(push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst)));
1657
+
1658
+ FAIL_IF(push_inst(compiler, SRL | T(dst) | D(TMP_REG1) | SH_IMM(8), DR(TMP_REG1)));
1659
+ FAIL_IF(push_inst(compiler, AND | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));
1660
+ FAIL_IF(push_inst(compiler, AND | S(TMP_REG1) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
1661
+ FAIL_IF(push_inst(compiler, SLL | T(dst) | D(dst) | SH_IMM(8), DR(dst)));
1662
+ FAIL_IF(push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst)));
1663
+
1664
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1665
+ if (op == SLJIT_REV_U32 && dst != TMP_REG2 && dst != TMP_REG3) {
1666
+ FAIL_IF(push_inst(compiler, DSLL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst)));
1667
+ FAIL_IF(push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst)));
1668
+ }
1669
+ #endif /* SLJIT_CONFIG_MIPS_64 */
1670
+ #endif /* SLJIT_MIPR_REV >= 2 */
1671
+ return SLJIT_SUCCESS;
1672
+ }
1673
+
1674
+ static sljit_s32 emit_rev16(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src)
1675
+ {
1676
+ #if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
1677
+ #if defined(SLJIT_CONFIG_MIPS_32) && SLJIT_CONFIG_MIPS_32
1678
+ FAIL_IF(push_inst(compiler, WSBH | T(src) | D(dst), DR(dst)));
1679
+ #else /* !SLJIT_CONFIG_MIPS_32 */
1680
+ FAIL_IF(push_inst(compiler, DSBH | T(src) | D(dst), DR(dst)));
1681
+ #endif /* SLJIT_CONFIG_MIPS_32 */
1682
+ if (GET_OPCODE(op) == SLJIT_REV_U16)
1683
+ return push_inst(compiler, ANDI | S(dst) | T(dst) | 0xffff, DR(dst));
1684
+ else
1685
+ return push_inst(compiler, SEH | T(dst) | D(dst), DR(dst));
1686
+ #else /* SLJIT_MIPS_REV < 2 */
1687
+ FAIL_IF(push_inst(compiler, SELECT_OP(DSRL, SRL) | T(src) | D(TMP_REG1) | SH_IMM(8), DR(TMP_REG1)));
1688
+ FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | T(src) | D(dst) | SH_IMM(24), DR(dst)));
1689
+ FAIL_IF(push_inst(compiler, ANDI | S(TMP_REG1) | T(TMP_REG1) | 0xff, DR(TMP_REG1)));
1690
+ FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U16 ? SELECT_OP(DSRL32, SRL) : SELECT_OP(DSRA32, SRA)) | T(dst) | D(dst) | SH_IMM(16), DR(dst)));
1691
+ return push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst));
1692
+ #endif /* SLJIT_MIPS_REV >= 2 */
1693
+ }
1694
+
1695
+ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
1696
+ sljit_s32 dst, sljit_s32 src1, sljit_sw src2)
1697
+ {
1698
+ sljit_s32 is_overflow, is_carry, carry_src_ar, is_handled, reg;
1699
+ sljit_ins op_imm, op_v;
1700
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1701
+ sljit_ins ins, op_dimm, op_dimm32, op_dv;
1702
+ #endif
1703
+
1704
+ switch (GET_OPCODE(op)) {
1705
+ case SLJIT_MOV:
1706
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1707
+ if (dst != src2)
1708
+ return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(dst), DR(dst));
1709
+ return SLJIT_SUCCESS;
1710
+
1711
+ case SLJIT_MOV_U8:
1712
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1713
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))
1714
+ return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));
1715
+ SLJIT_ASSERT(dst == src2);
1716
+ return SLJIT_SUCCESS;
1717
+
1718
+ case SLJIT_MOV_S8:
1719
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1720
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
1721
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1722
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
1723
+ return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
1724
+ #else /* SLJIT_MIPS_REV < 2 */
1725
+ FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
1726
+ return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst));
1727
+ #endif /* SLJIT_MIPS_REV >= 2 */
1728
+ #else /* !SLJIT_CONFIG_MIPS_32 */
1729
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
1730
+ if (op & SLJIT_32)
1731
+ return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
1732
+ #endif /* SLJIT_MIPS_REV >= 2 */
1733
+ FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
1734
+ return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(24), DR(dst));
1735
+ #endif /* SLJIT_CONFIG_MIPS_32 */
1736
+ }
1737
+ SLJIT_ASSERT(dst == src2);
1738
+ return SLJIT_SUCCESS;
1739
+
1740
+ case SLJIT_MOV_U16:
1741
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1742
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))
1743
+ return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));
1744
+ SLJIT_ASSERT(dst == src2);
1745
+ return SLJIT_SUCCESS;
1746
+
1747
+ case SLJIT_MOV_S16:
1748
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1749
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
1750
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
1751
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
1752
+ return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
1753
+ #else /* SLJIT_MIPS_REV < 2 */
1754
+ FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
1755
+ return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst));
1756
+ #endif /* SLJIT_MIPS_REV >= 2 */
1757
+ #else /* !SLJIT_CONFIG_MIPS_32 */
1758
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
1759
+ if (op & SLJIT_32)
1760
+ return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
1761
+ #endif /* SLJIT_MIPS_REV >= 2 */
1762
+ FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
1763
+ return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(16), DR(dst));
1764
+ #endif /* SLJIT_CONFIG_MIPS_32 */
1765
+ }
1766
+ SLJIT_ASSERT(dst == src2);
1767
+ return SLJIT_SUCCESS;
1768
+
1769
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
1770
+ case SLJIT_MOV_U32:
1771
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM) && !(op & SLJIT_32));
1772
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
1773
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
1774
+ if (dst == src2)
1775
+ return push_inst(compiler, DINSU | T(src2) | SA(0) | (31 << 11), DR(dst));
1776
+ #endif /* SLJIT_MIPS_REV >= 2 */
1777
+ FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(0), DR(dst)));
1778
+ return push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst));
1779
+ }
1780
+ SLJIT_ASSERT(dst == src2);
1781
+ return SLJIT_SUCCESS;
1782
+
1783
+ case SLJIT_MOV_S32:
1784
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM) && !(op & SLJIT_32));
1785
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
1786
+ return push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(0), DR(dst));
1787
+ }
1788
+ SLJIT_ASSERT(dst == src2);
1789
+ return SLJIT_SUCCESS;
1790
+ #endif /* SLJIT_CONFIG_MIPS_64 */
1791
+
1792
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
1793
+ case SLJIT_CLZ:
1794
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1795
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
1796
+ return push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | D(dst), DR(dst));
1797
+ #else /* SLJIT_MIPS_REV < 6 */
1798
+ return push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | T(dst) | D(dst), DR(dst));
1799
+ #endif /* SLJIT_MIPS_REV >= 6 */
1800
+ case SLJIT_CTZ:
1801
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1802
+ FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(0) | T(src2) | D(TMP_REG1), DR(TMP_REG1)));
1803
+ FAIL_IF(push_inst(compiler, AND | S(src2) | T(TMP_REG1) | D(dst), DR(dst)));
1804
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
1805
+ FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(dst) | D(dst), DR(dst)));
1806
+ #else /* SLJIT_MIPS_REV < 6 */
1807
+ FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(dst) | T(dst) | D(dst), DR(dst)));
1808
+ #endif /* SLJIT_MIPS_REV >= 6 */
1809
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(dst) | T(TMP_REG1) | IMM(SELECT_OP(-64, -32)), DR(TMP_REG1)));
1810
+ FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(SELECT_OP(26, 27)), DR(TMP_REG1)));
1811
+ return push_inst(compiler, XOR | S(dst) | T(TMP_REG1) | D(dst), DR(dst));
1812
+ #else /* SLJIT_MIPS_REV < 1 */
1813
+ case SLJIT_CLZ:
1814
+ case SLJIT_CTZ:
1815
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1816
+ return emit_clz_ctz(compiler, op, dst, src2);
1817
+ #endif /* SLJIT_MIPS_REV >= 1 */
1818
+
1819
+ case SLJIT_REV:
1820
+ case SLJIT_REV_U32:
1821
+ case SLJIT_REV_S32:
1822
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM) && src2 != TMP_REG1 && dst != TMP_REG1);
1823
+ return emit_rev(compiler, op, dst, src2);
1824
+
1825
+ case SLJIT_REV_U16:
1826
+ case SLJIT_REV_S16:
1827
+ SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
1828
+ return emit_rev16(compiler, op, dst, src2);
1829
+
1830
+ case SLJIT_ADD:
1831
+ /* Overflow computation (both add and sub): overflow = src1_sign ^ src2_sign ^ result_sign ^ carry_flag */
1832
+ is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW;
1833
+ carry_src_ar = GET_FLAG_TYPE(op) == SLJIT_CARRY;
1834
+
1835
+ if (flags & SRC2_IMM) {
1836
+ if (is_overflow) {
1837
+ if (src2 >= 0)
1838
+ FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
1839
+ else
1840
+ FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
1841
+ }
1842
+ else if (op & SLJIT_SET_Z)
1843
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
1844
+
1845
+ /* Only the zero flag is needed. */
1846
+ if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
1847
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst)));
1848
+ }
1849
+ else {
1850
+ if (is_overflow)
1851
+ FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
1852
+ else if (op & SLJIT_SET_Z)
1853
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
1854
+
1855
+ if (is_overflow || carry_src_ar != 0) {
1856
+ if (src1 != dst)
1857
+ carry_src_ar = DR(src1);
1858
+ else if (src2 != dst)
1859
+ carry_src_ar = DR(src2);
1860
+ else {
1861
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | TA(0) | DA(OTHER_FLAG), OTHER_FLAG));
1862
+ carry_src_ar = OTHER_FLAG;
1863
+ }
1864
+ }
1865
+
1866
+ /* Only the zero flag is needed. */
1867
+ if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
1868
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst)));
1869
+ }
1870
+
1871
+ /* Carry is zero if a + b >= a or a + b >= b, otherwise it is 1. */
1872
+ if (is_overflow || carry_src_ar != 0) {
1873
+ if (flags & SRC2_IMM)
1874
+ FAIL_IF(push_inst(compiler, SLTIU | S(dst) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
1875
+ else
1876
+ FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(carry_src_ar) | DA(OTHER_FLAG), OTHER_FLAG));
1877
+ }
1878
+
1879
+ if (!is_overflow)
1880
+ return SLJIT_SUCCESS;
1881
+
1882
+ FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(EQUAL_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
1883
+ if (op & SLJIT_SET_Z)
1884
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));
1885
+ FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
1886
+ return push_inst(compiler, XOR | S(TMP_REG1) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
1887
+
1888
+ case SLJIT_ADDC:
1889
+ carry_src_ar = GET_FLAG_TYPE(op) == SLJIT_CARRY;
1890
+
1891
+ if (flags & SRC2_IMM) {
1892
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst)));
1893
+ } else {
1894
+ if (carry_src_ar != 0) {
1895
+ if (src1 != dst)
1896
+ carry_src_ar = DR(src1);
1897
+ else if (src2 != dst)
1898
+ carry_src_ar = DR(src2);
1899
+ else {
1900
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));
1901
+ carry_src_ar = EQUAL_FLAG;
1902
+ }
1903
+ }
1904
+
1905
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst)));
1906
+ }
1907
+
1908
+ /* Carry is zero if a + b >= a or a + b >= b, otherwise it is 1. */
1909
+ if (carry_src_ar != 0) {
1910
+ if (flags & SRC2_IMM)
1911
+ FAIL_IF(push_inst(compiler, SLTIU | S(dst) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
1912
+ else
1913
+ FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(carry_src_ar) | DA(EQUAL_FLAG), EQUAL_FLAG));
1914
+ }
1915
+
1916
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));
1917
+
1918
+ if (carry_src_ar == 0)
1919
+ return SLJIT_SUCCESS;
1920
+
1921
+ /* Set ULESS_FLAG (dst == 0) && (OTHER_FLAG == 1). */
1922
+ FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG));
1923
+ /* Set carry flag. */
1924
+ return push_inst(compiler, OR | SA(OTHER_FLAG) | TA(EQUAL_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
1925
+
1926
+ case SLJIT_SUB:
1927
+ if ((flags & SRC2_IMM) && src2 == SIMM_MIN) {
1928
+ FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
1929
+ src2 = TMP_REG2;
1930
+ flags &= ~SRC2_IMM;
1931
+ }
1932
+
1933
+ is_handled = 0;
1934
+
1935
+ if (flags & SRC2_IMM) {
1936
+ if (GET_FLAG_TYPE(op) == SLJIT_LESS) {
1937
+ FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
1938
+ is_handled = 1;
1939
+ }
1940
+ else if (GET_FLAG_TYPE(op) == SLJIT_SIG_LESS) {
1941
+ FAIL_IF(push_inst(compiler, SLTI | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
1942
+ is_handled = 1;
1943
+ }
1944
+ }
1945
+
1946
+ if (!is_handled && GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL) {
1947
+ is_handled = 1;
1948
+
1949
+ if (flags & SRC2_IMM) {
1950
+ reg = (src1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;
1951
+ FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(reg) | IMM(src2), DR(reg)));
1952
+ src2 = reg;
1953
+ flags &= ~SRC2_IMM;
1954
+ }
1955
+
1956
+ switch (GET_FLAG_TYPE(op)) {
1957
+ case SLJIT_LESS:
1958
+ FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));
1959
+ break;
1960
+ case SLJIT_GREATER:
1961
+ FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));
1962
+ break;
1963
+ case SLJIT_SIG_LESS:
1964
+ FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));
1965
+ break;
1966
+ case SLJIT_SIG_GREATER:
1967
+ FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));
1968
+ break;
1969
+ }
1970
+ }
1971
+
1972
+ if (is_handled) {
1973
+ if (flags & SRC2_IMM) {
1974
+ if (op & SLJIT_SET_Z)
1975
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));
1976
+ if (!(flags & UNUSED_DEST))
1977
+ return push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst));
1978
+ }
1979
+ else {
1980
+ if (op & SLJIT_SET_Z)
1981
+ FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
1982
+ if (!(flags & UNUSED_DEST))
1983
+ return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst));
1984
+ }
1985
+ return SLJIT_SUCCESS;
1986
+ }
1987
+
1988
+ is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW;
1989
+ is_carry = GET_FLAG_TYPE(op) == SLJIT_CARRY;
1990
+
1991
+ if (flags & SRC2_IMM) {
1992
+ if (is_overflow) {
1993
+ if (src2 >= 0)
1994
+ FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
1995
+ else
1996
+ FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
1997
+ }
1998
+ else if (op & SLJIT_SET_Z)
1999
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));
2000
+
2001
+ if (is_overflow || is_carry)
2002
+ FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG));
2003
+
2004
+ /* Only the zero flag is needed. */
2005
+ if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
2006
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst)));
2007
+ }
2008
+ else {
2009
+ if (is_overflow)
2010
+ FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
2011
+ else if (op & SLJIT_SET_Z)
2012
+ FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
2013
+
2014
+ if (is_overflow || is_carry)
2015
+ FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG));
2016
+
2017
+ /* Only the zero flag is needed. */
2018
+ if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
2019
+ FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst)));
2020
+ }
2021
+
2022
+ if (!is_overflow)
2023
+ return SLJIT_SUCCESS;
2024
+
2025
+ FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(EQUAL_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
2026
+ if (op & SLJIT_SET_Z)
2027
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG));
2028
+ FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(31), DR(TMP_REG1)));
2029
+ return push_inst(compiler, XOR | S(TMP_REG1) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
2030
+
2031
+ case SLJIT_SUBC:
2032
+ if ((flags & SRC2_IMM) && src2 == SIMM_MIN) {
2033
+ FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
2034
+ src2 = TMP_REG2;
2035
+ flags &= ~SRC2_IMM;
2036
+ }
2037
+
2038
+ is_carry = GET_FLAG_TYPE(op) == SLJIT_CARRY;
2039
+
2040
+ if (flags & SRC2_IMM) {
2041
+ if (is_carry)
2042
+ FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
2043
+
2044
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst)));
2045
+ }
2046
+ else {
2047
+ if (is_carry)
2048
+ FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
2049
+
2050
+ FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst)));
2051
+ }
2052
+
2053
+ if (is_carry)
2054
+ FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1)));
2055
+
2056
+ FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst)));
2057
+
2058
+ if (!is_carry)
2059
+ return SLJIT_SUCCESS;
2060
+
2061
+ return push_inst(compiler, OR | SA(EQUAL_FLAG) | T(TMP_REG1) | DA(OTHER_FLAG), OTHER_FLAG);
2062
+
2063
+ case SLJIT_MUL:
2064
+ SLJIT_ASSERT(!(flags & SRC2_IMM));
2065
+
2066
+ if (GET_FLAG_TYPE(op) != SLJIT_OVERFLOW) {
2067
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
2068
+ return push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst));
2069
+ #elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
2070
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2071
+ return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
2072
+ #else /* !SLJIT_CONFIG_MIPS_32 */
2073
+ if (op & SLJIT_32)
2074
+ return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
2075
+ FAIL_IF(push_inst(compiler, DMULT | S(src1) | T(src2), MOVABLE_INS));
2076
+ return push_inst(compiler, MFLO | D(dst), DR(dst));
2077
+ #endif /* SLJIT_CONFIG_MIPS_32 */
2078
+ #else /* SLJIT_MIPS_REV < 1 */
2079
+ FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));
2080
+ return push_inst(compiler, MFLO | D(dst), DR(dst));
2081
+ #endif /* SLJIT_MIPS_REV >= 6 */
2082
+ }
2083
+
2084
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
2085
+ FAIL_IF(push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst)));
2086
+ FAIL_IF(push_inst(compiler, SELECT_OP(DMUH, MUH) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
2087
+ #else /* SLJIT_MIPS_REV < 6 */
2088
+ FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));
2089
+ FAIL_IF(push_inst(compiler, MFHI | DA(EQUAL_FLAG), EQUAL_FLAG));
2090
+ FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));
2091
+ #endif /* SLJIT_MIPS_REV >= 6 */
2092
+ FAIL_IF(push_inst(compiler, SELECT_OP(DSRA32, SRA) | T(dst) | DA(OTHER_FLAG) | SH_IMM(31), OTHER_FLAG));
2093
+ return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(EQUAL_FLAG) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
2094
+
2095
+ case SLJIT_AND:
2096
+ EMIT_LOGICAL(ANDI, AND);
2097
+ return SLJIT_SUCCESS;
2098
+
2099
+ case SLJIT_OR:
2100
+ EMIT_LOGICAL(ORI, OR);
2101
+ return SLJIT_SUCCESS;
2102
+
2103
+ case SLJIT_XOR:
2104
+ if (!(flags & LOGICAL_OP)) {
2105
+ SLJIT_ASSERT((flags & SRC2_IMM) && src2 == -1);
2106
+ if (op & SLJIT_SET_Z)
2107
+ FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
2108
+ if (!(flags & UNUSED_DEST))
2109
+ FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | D(dst), DR(dst)));
2110
+ return SLJIT_SUCCESS;
2111
+ }
2112
+ EMIT_LOGICAL(XORI, XOR);
2113
+ return SLJIT_SUCCESS;
2114
+
2115
+ case SLJIT_SHL:
2116
+ case SLJIT_MSHL:
2117
+ EMIT_SHIFT(DSLL, DSLL32, SLL, DSLLV, SLLV);
2118
+ break;
2119
+
2120
+ case SLJIT_LSHR:
2121
+ case SLJIT_MLSHR:
2122
+ EMIT_SHIFT(DSRL, DSRL32, SRL, DSRLV, SRLV);
2123
+ break;
2124
+
2125
+ case SLJIT_ASHR:
2126
+ case SLJIT_MASHR:
2127
+ EMIT_SHIFT(DSRA, DSRA32, SRA, DSRAV, SRAV);
2128
+ break;
2129
+
2130
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
2131
+ case SLJIT_ROTL:
2132
+ if ((flags & SRC2_IMM) || src2 == 0) {
2133
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2134
+ src2 = -src2 & 0x1f;
2135
+ #else /* !SLJIT_CONFIG_MIPS_32 */
2136
+ src2 = -src2 & ((op & SLJIT_32) ? 0x1f : 0x3f);
2137
+ #endif /* SLJIT_CONFIG_MIPS_32 */
2138
+ } else {
2139
+ FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(0) | T(src2) | D(TMP_REG2), DR(TMP_REG2)));
2140
+ src2 = TMP_REG2;
2141
+ }
2142
+ /* fallthrough */
2143
+
2144
+ case SLJIT_ROTR:
2145
+ EMIT_SHIFT(DROTR, DROTR32, ROTR, DROTRV, ROTRV);
2146
+ break;
2147
+ #else /* SLJIT_MIPS_REV < 1 */
2148
+ case SLJIT_ROTL:
2149
+ case SLJIT_ROTR:
2150
+ if (flags & SRC2_IMM) {
2151
+ SLJIT_ASSERT(src2 != 0);
2152
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2153
+ if (!(op & SLJIT_32)) {
2154
+ if (GET_OPCODE(op) == SLJIT_ROTL)
2155
+ op_imm = ((src2 < 32) ? DSLL : DSLL32);
2156
+ else
2157
+ op_imm = ((src2 < 32) ? DSRL : DSRL32);
2158
+
2159
+ FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(OTHER_FLAG) | (((sljit_ins)src2 & 0x1f) << 6), OTHER_FLAG));
2160
+
2161
+ src2 = 64 - src2;
2162
+ if (GET_OPCODE(op) == SLJIT_ROTL)
2163
+ op_imm = ((src2 < 32) ? DSRL : DSRL32);
2164
+ else
2165
+ op_imm = ((src2 < 32) ? DSLL : DSLL32);
2166
+
2167
+ FAIL_IF(push_inst(compiler, op_imm | T(src1) | D(dst) | (((sljit_ins)src2 & 0x1f) << 6), DR(dst)));
2168
+ return push_inst(compiler, OR | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst));
2169
+ }
2170
+ #endif /* SLJIT_CONFIG_MIPS_64 */
2171
+
2172
+ op_imm = (GET_OPCODE(op) == SLJIT_ROTL) ? SLL : SRL;
2173
+ FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(OTHER_FLAG) | ((sljit_ins)src2 << 6), OTHER_FLAG));
2174
+
2175
+ src2 = 32 - src2;
2176
+ op_imm = (GET_OPCODE(op) == SLJIT_ROTL) ? SRL : SLL;
2177
+ FAIL_IF(push_inst(compiler, op_imm | T(src1) | D(dst) | (((sljit_ins)src2 & 0x1f) << 6), DR(dst)));
2178
+ return push_inst(compiler, OR | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst));
2179
+ }
2180
+
2181
+ if (src2 == 0) {
2182
+ if (dst != src1)
2183
+ return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | TA(0) | D(dst), DR(dst));
2184
+ return SLJIT_SUCCESS;
2185
+ }
2186
+
2187
+ FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(0) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
2188
+
2189
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2190
+ if (!(op & SLJIT_32)) {
2191
+ op_v = (GET_OPCODE(op) == SLJIT_ROTL) ? DSLLV : DSRLV;
2192
+ FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));
2193
+ op_v = (GET_OPCODE(op) == SLJIT_ROTL) ? DSRLV : DSLLV;
2194
+ FAIL_IF(push_inst(compiler, op_v | SA(EQUAL_FLAG) | T(src1) | D(dst), DR(dst)));
2195
+ return push_inst(compiler, OR | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst));
2196
+ }
2197
+ #endif /* SLJIT_CONFIG_MIPS_64 */
2198
+
2199
+ op_v = (GET_OPCODE(op) == SLJIT_ROTL) ? SLLV : SRLV;
2200
+ FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG));
2201
+ op_v = (GET_OPCODE(op) == SLJIT_ROTL) ? SRLV : SLLV;
2202
+ FAIL_IF(push_inst(compiler, op_v | SA(EQUAL_FLAG) | T(src1) | D(dst), DR(dst)));
2203
+ return push_inst(compiler, OR | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst));
2204
+ #endif /* SLJIT_MIPS_REV >= 2 */
2205
+
2206
+ default:
2207
+ SLJIT_UNREACHABLE();
2208
+ return SLJIT_SUCCESS;
2209
+ }
2210
+
2211
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2212
+ if ((flags & SRC2_IMM) || src2 == 0) {
2213
+ if (op & SLJIT_SET_Z)
2214
+ FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG));
2215
+
2216
+ if (flags & UNUSED_DEST)
2217
+ return SLJIT_SUCCESS;
2218
+ return push_inst(compiler, op_imm | T(src1) | D(dst) | SH_IMM(src2), DR(dst));
2219
+ }
2220
+
2221
+ if (op & SLJIT_SET_Z)
2222
+ FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
2223
+
2224
+ if (flags & UNUSED_DEST)
2225
+ return SLJIT_SUCCESS;
2226
+ return push_inst(compiler, op_v | S(src2) | T(src1) | D(dst), DR(dst));
2227
+ #else /* !SLJIT_CONFIG_MIPS_32 */
2228
+ if ((flags & SRC2_IMM) || src2 == 0) {
2229
+ if (src2 >= 32) {
2230
+ SLJIT_ASSERT(!(op & SLJIT_32));
2231
+ ins = op_dimm32;
2232
+ src2 -= 32;
2233
+ }
2234
+ else
2235
+ ins = (op & SLJIT_32) ? op_imm : op_dimm;
2236
+
2237
+ if (op & SLJIT_SET_Z)
2238
+ FAIL_IF(push_inst(compiler, ins | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG));
2239
+
2240
+ if (flags & UNUSED_DEST)
2241
+ return SLJIT_SUCCESS;
2242
+ return push_inst(compiler, ins | T(src1) | D(dst) | SH_IMM(src2), DR(dst));
2243
+ }
2244
+
2245
+ ins = (op & SLJIT_32) ? op_v : op_dv;
2246
+ if (op & SLJIT_SET_Z)
2247
+ FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG));
2248
+
2249
+ if (flags & UNUSED_DEST)
2250
+ return SLJIT_SUCCESS;
2251
+ return push_inst(compiler, ins | S(src2) | T(src1) | D(dst), DR(dst));
2252
+ #endif /* SLJIT_CONFIG_MIPS_32 */
2253
+ }
2254
+
2255
+ #define CHECK_IMM(flags, srcw) \
2256
+ ((!((flags) & LOGICAL_OP) && ((srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN)) \
2257
+ || (((flags) & LOGICAL_OP) && !((srcw) & ~UIMM_MAX)))
2258
+
2259
+ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
2260
+ sljit_s32 dst, sljit_sw dstw,
2261
+ sljit_s32 src1, sljit_sw src1w,
2262
+ sljit_s32 src2, sljit_sw src2w)
2263
+ {
2264
+ /* arg1 goes to TMP_REG1 or src reg
2265
+ arg2 goes to TMP_REG2, imm or src reg
2266
+ TMP_REG3 can be used for caching
2267
+ result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
2268
+ sljit_s32 dst_r = TMP_REG2;
2269
+ sljit_s32 src1_r;
2270
+ sljit_sw src2_r = 0;
2271
+ sljit_s32 src2_tmp_reg = (GET_OPCODE(op) >= SLJIT_OP2_BASE && FAST_IS_REG(src1)) ? TMP_REG1 : TMP_REG2;
2272
+
2273
+ if (!(flags & ALT_KEEP_CACHE)) {
2274
+ compiler->cache_arg = 0;
2275
+ compiler->cache_argw = 0;
2276
+ }
2277
+
2278
+ if (dst == 0) {
2279
+ SLJIT_ASSERT(HAS_FLAGS(op));
2280
+ flags |= UNUSED_DEST;
2281
+ dst = TMP_REG2;
2282
+ }
2283
+ else if (FAST_IS_REG(dst)) {
2284
+ dst_r = dst;
2285
+ flags |= REG_DEST;
2286
+ if (flags & MOVE_OP)
2287
+ src2_tmp_reg = dst_r;
2288
+ }
2289
+ else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, DR(TMP_REG1), dst, dstw))
2290
+ flags |= SLOW_DEST;
2291
+
2292
+ if (flags & IMM_OP) {
2293
+ if (src2 == SLJIT_IMM && src2w != 0 && CHECK_IMM(flags, src2w)) {
2294
+ flags |= SRC2_IMM;
2295
+ src2_r = src2w;
2296
+ } else if ((flags & CUMULATIVE_OP) && src1 == SLJIT_IMM && src1w != 0 && CHECK_IMM(flags, src1w)) {
2297
+ flags |= SRC2_IMM;
2298
+ src2_r = src1w;
2299
+
2300
+ /* And swap arguments. */
2301
+ src1 = src2;
2302
+ src1w = src2w;
2303
+ src2 = SLJIT_IMM;
2304
+ /* src2w = src2_r unneeded. */
2305
+ }
2306
+ }
2307
+
2308
+ /* Source 1. */
2309
+ if (FAST_IS_REG(src1)) {
2310
+ src1_r = src1;
2311
+ flags |= REG1_SOURCE;
2312
+ }
2313
+ else if (src1 == SLJIT_IMM) {
2314
+ if (src1w) {
2315
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w));
2316
+ src1_r = TMP_REG1;
2317
+ }
2318
+ else
2319
+ src1_r = 0;
2320
+ }
2321
+ else {
2322
+ if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w))
2323
+ FAIL_IF(compiler->error);
2324
+ else
2325
+ flags |= SLOW_SRC1;
2326
+ src1_r = TMP_REG1;
2327
+ }
2328
+
2329
+ /* Source 2. */
2330
+ if (FAST_IS_REG(src2)) {
2331
+ src2_r = src2;
2332
+ flags |= REG2_SOURCE;
2333
+ if ((flags & (REG_DEST | MOVE_OP)) == MOVE_OP)
2334
+ dst_r = (sljit_s32)src2_r;
2335
+ }
2336
+ else if (src2 == SLJIT_IMM) {
2337
+ if (!(flags & SRC2_IMM)) {
2338
+ if (src2w) {
2339
+ FAIL_IF(load_immediate(compiler, DR(src2_tmp_reg), src2w));
2340
+ src2_r = src2_tmp_reg;
2341
+ }
2342
+ else {
2343
+ src2_r = 0;
2344
+ if (flags & MOVE_OP) {
2345
+ if (dst & SLJIT_MEM)
2346
+ dst_r = 0;
2347
+ else
2348
+ op = SLJIT_MOV;
2349
+ }
2350
+ }
2351
+ }
2352
+ }
2353
+ else {
2354
+ if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(src2_tmp_reg), src2, src2w))
2355
+ FAIL_IF(compiler->error);
2356
+ else
2357
+ flags |= SLOW_SRC2;
2358
+ src2_r = src2_tmp_reg;
2359
+ }
2360
+
2361
+ if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
2362
+ SLJIT_ASSERT(src2_r == TMP_REG2);
2363
+ if ((flags & SLOW_DEST) && !can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
2364
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, src1, src1w));
2365
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));
2366
+ }
2367
+ else {
2368
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, src2, src2w));
2369
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, dst, dstw));
2370
+ }
2371
+ }
2372
+ else if (flags & SLOW_SRC1)
2373
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));
2374
+ else if (flags & SLOW_SRC2)
2375
+ FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(src2_tmp_reg), src2, src2w, dst, dstw));
2376
+
2377
+ FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
2378
+
2379
+ if (dst & SLJIT_MEM) {
2380
+ if (!(flags & SLOW_DEST)) {
2381
+ getput_arg_fast(compiler, flags, DR(dst_r), dst, dstw);
2382
+ return compiler->error;
2383
+ }
2384
+ return getput_arg(compiler, flags, DR(dst_r), dst, dstw, 0, 0);
2385
+ }
2386
+
2387
+ return SLJIT_SUCCESS;
2388
+ }
2389
+
2390
+ #undef CHECK_IMM
2391
+
2392
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
2393
+ {
2394
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2395
+ sljit_s32 int_op = op & SLJIT_32;
2396
+ #endif
2397
+
2398
+ CHECK_ERROR();
2399
+ CHECK(check_sljit_emit_op0(compiler, op));
2400
+
2401
+ op = GET_OPCODE(op);
2402
+ switch (op) {
2403
+ case SLJIT_BREAKPOINT:
2404
+ return push_inst(compiler, BREAK, UNMOVABLE_INS);
2405
+ case SLJIT_NOP:
2406
+ return push_inst(compiler, NOP, UNMOVABLE_INS);
2407
+ case SLJIT_LMUL_UW:
2408
+ case SLJIT_LMUL_SW:
2409
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
2410
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2411
+ FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULU : DMUL) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
2412
+ FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMUHU : DMUH) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
2413
+ #else /* !SLJIT_CONFIG_MIPS_64 */
2414
+ FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MULU : MUL) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
2415
+ FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MUHU : MUH) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
2416
+ #endif /* SLJIT_CONFIG_MIPS_64 */
2417
+ FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0)));
2418
+ return push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1));
2419
+ #else /* SLJIT_MIPS_REV < 6 */
2420
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2421
+ FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULTU : DMULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
2422
+ #else /* !SLJIT_CONFIG_MIPS_64 */
2423
+ FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MULTU : MULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
2424
+ #endif /* SLJIT_CONFIG_MIPS_64 */
2425
+ FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
2426
+ return push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
2427
+ #endif /* SLJIT_MIPS_REV >= 6 */
2428
+ case SLJIT_DIVMOD_UW:
2429
+ case SLJIT_DIVMOD_SW:
2430
+ case SLJIT_DIV_UW:
2431
+ case SLJIT_DIV_SW:
2432
+ SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);
2433
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
2434
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2435
+ if (int_op) {
2436
+ FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
2437
+ FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? MODU : MOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
2438
+ }
2439
+ else {
2440
+ FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
2441
+ FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DMODU : DMOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
2442
+ }
2443
+ #else /* !SLJIT_CONFIG_MIPS_64 */
2444
+ FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
2445
+ FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? MODU : MOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
2446
+ #endif /* SLJIT_CONFIG_MIPS_64 */
2447
+ FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0)));
2448
+ return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1));
2449
+ #else /* SLJIT_MIPS_REV < 6 */
2450
+ #if !(defined SLJIT_MIPS_REV)
2451
+ FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
2452
+ FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
2453
+ #endif /* !SLJIT_MIPS_REV */
2454
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2455
+ if (int_op)
2456
+ FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
2457
+ else
2458
+ FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
2459
+ #else /* !SLJIT_CONFIG_MIPS_64 */
2460
+ FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
2461
+ #endif /* SLJIT_CONFIG_MIPS_64 */
2462
+ FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
2463
+ return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
2464
+ #endif /* SLJIT_MIPS_REV >= 6 */
2465
+ case SLJIT_ENDBR:
2466
+ case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
2467
+ return SLJIT_SUCCESS;
2468
+ }
2469
+
2470
+ return SLJIT_SUCCESS;
2471
+ }
2472
+
2473
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
2474
+ static sljit_s32 emit_prefetch(struct sljit_compiler *compiler,
2475
+ sljit_s32 src, sljit_sw srcw)
2476
+ {
2477
+ if (!(src & OFFS_REG_MASK)) {
2478
+ if (srcw <= SIMM_MAX && srcw >= SIMM_MIN)
2479
+ return push_inst(compiler, PREF | S(src & REG_MASK) | IMM(srcw), MOVABLE_INS);
2480
+
2481
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw));
2482
+ return push_inst(compiler, PREFX | S(src & REG_MASK) | T(TMP_REG1), MOVABLE_INS);
2483
+ }
2484
+
2485
+ srcw &= 0x3;
2486
+
2487
+ if (SLJIT_UNLIKELY(srcw != 0)) {
2488
+ FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(src)) | D(TMP_REG1) | SH_IMM(srcw), DR(TMP_REG1)));
2489
+ return push_inst(compiler, PREFX | S(src & REG_MASK) | T(TMP_REG1), MOVABLE_INS);
2490
+ }
2491
+
2492
+ return push_inst(compiler, PREFX | S(src & REG_MASK) | T(OFFS_REG(src)), MOVABLE_INS);
2493
+ }
2494
+ #endif /* SLJIT_MIPS_REV >= 1 */
2495
+
2496
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
2497
+ sljit_s32 dst, sljit_sw dstw,
2498
+ sljit_s32 src, sljit_sw srcw)
2499
+ {
2500
+ sljit_s32 flags = 0;
2501
+
2502
+ CHECK_ERROR();
2503
+ CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
2504
+ ADJUST_LOCAL_OFFSET(dst, dstw);
2505
+ ADJUST_LOCAL_OFFSET(src, srcw);
2506
+
2507
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2508
+ if (op & SLJIT_32)
2509
+ flags = INT_DATA | SIGNED_DATA;
2510
+ #endif
2511
+
2512
+ switch (GET_OPCODE(op)) {
2513
+ case SLJIT_MOV:
2514
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2515
+ case SLJIT_MOV_U32:
2516
+ case SLJIT_MOV_S32:
2517
+ case SLJIT_MOV32:
2518
+ #endif
2519
+ case SLJIT_MOV_P:
2520
+ return emit_op(compiler, SLJIT_MOV, WORD_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, srcw);
2521
+
2522
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2523
+ case SLJIT_MOV_U32:
2524
+ return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u32)srcw : srcw);
2525
+
2526
+ case SLJIT_MOV_S32:
2527
+ case SLJIT_MOV32:
2528
+ return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s32)srcw : srcw);
2529
+ #endif
2530
+
2531
+ case SLJIT_MOV_U8:
2532
+ return emit_op(compiler, op, BYTE_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u8)srcw : srcw);
2533
+
2534
+ case SLJIT_MOV_S8:
2535
+ return emit_op(compiler, op, BYTE_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s8)srcw : srcw);
2536
+
2537
+ case SLJIT_MOV_U16:
2538
+ return emit_op(compiler, op, HALF_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u16)srcw : srcw);
2539
+
2540
+ case SLJIT_MOV_S16:
2541
+ return emit_op(compiler, op, HALF_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s16)srcw : srcw);
2542
+
2543
+ case SLJIT_CLZ:
2544
+ case SLJIT_CTZ:
2545
+ case SLJIT_REV:
2546
+ return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
2547
+
2548
+ case SLJIT_REV_U16:
2549
+ case SLJIT_REV_S16:
2550
+ return emit_op(compiler, op, HALF_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
2551
+
2552
+ case SLJIT_REV_U32:
2553
+ case SLJIT_REV_S32:
2554
+ return emit_op(compiler, op | SLJIT_32, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
2555
+ }
2556
+
2557
+ SLJIT_UNREACHABLE();
2558
+ return SLJIT_SUCCESS;
2559
+ }
2560
+
2561
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
2562
+ sljit_s32 dst, sljit_sw dstw,
2563
+ sljit_s32 src1, sljit_sw src1w,
2564
+ sljit_s32 src2, sljit_sw src2w)
2565
+ {
2566
+ sljit_s32 flags = 0;
2567
+
2568
+ CHECK_ERROR();
2569
+ CHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));
2570
+ ADJUST_LOCAL_OFFSET(dst, dstw);
2571
+ ADJUST_LOCAL_OFFSET(src1, src1w);
2572
+ ADJUST_LOCAL_OFFSET(src2, src2w);
2573
+
2574
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2575
+ if (op & SLJIT_32) {
2576
+ flags |= INT_DATA | SIGNED_DATA;
2577
+ if (src1 == SLJIT_IMM)
2578
+ src1w = (sljit_s32)src1w;
2579
+ if (src2 == SLJIT_IMM)
2580
+ src2w = (sljit_s32)src2w;
2581
+ }
2582
+ #endif
2583
+
2584
+ switch (GET_OPCODE(op)) {
2585
+ case SLJIT_ADD:
2586
+ case SLJIT_ADDC:
2587
+ compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;
2588
+ return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
2589
+
2590
+ case SLJIT_SUB:
2591
+ case SLJIT_SUBC:
2592
+ compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;
2593
+ return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
2594
+
2595
+ case SLJIT_MUL:
2596
+ compiler->status_flags_state = 0;
2597
+ return emit_op(compiler, op, flags | CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w);
2598
+
2599
+ case SLJIT_XOR:
2600
+ if ((src1 == SLJIT_IMM && src1w == -1) || (src2 == SLJIT_IMM && src2w == -1)) {
2601
+ return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
2602
+ }
2603
+ /* fallthrough */
2604
+ case SLJIT_AND:
2605
+ case SLJIT_OR:
2606
+ return emit_op(compiler, op, flags | CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
2607
+
2608
+ case SLJIT_SHL:
2609
+ case SLJIT_MSHL:
2610
+ case SLJIT_LSHR:
2611
+ case SLJIT_MLSHR:
2612
+ case SLJIT_ASHR:
2613
+ case SLJIT_MASHR:
2614
+ case SLJIT_ROTL:
2615
+ case SLJIT_ROTR:
2616
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2617
+ if (src2 == SLJIT_IMM)
2618
+ src2w &= 0x1f;
2619
+ #else
2620
+ if (src2 == SLJIT_IMM) {
2621
+ if (op & SLJIT_32)
2622
+ src2w &= 0x1f;
2623
+ else
2624
+ src2w &= 0x3f;
2625
+ }
2626
+ #endif
2627
+ return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
2628
+ }
2629
+
2630
+ SLJIT_UNREACHABLE();
2631
+ return SLJIT_SUCCESS;
2632
+ }
2633
+
2634
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,
2635
+ sljit_s32 src1, sljit_sw src1w,
2636
+ sljit_s32 src2, sljit_sw src2w)
2637
+ {
2638
+ CHECK_ERROR();
2639
+ CHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w));
2640
+
2641
+ SLJIT_SKIP_CHECKS(compiler);
2642
+ return sljit_emit_op2(compiler, op, 0, 0, src1, src1w, src2, src2w);
2643
+ }
2644
+
2645
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2646
+ #define SELECT_OP3(op, src2w, D, D32, W) (((op & SLJIT_32) ? (W) : ((src2w) < 32) ? (D) : (D32)) | (((sljit_ins)src2w & 0x1f) << 6))
2647
+ #else /* !SLJIT_CONFIG_MIPS_64 */
2648
+ #define SELECT_OP3(op, src2w, D, D32, W) ((W) | ((sljit_ins)(src2w) << 6))
2649
+ #endif /* SLJIT_CONFIG_MIPS_64 */
2650
+
2651
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,
2652
+ sljit_s32 dst_reg,
2653
+ sljit_s32 src1, sljit_sw src1w,
2654
+ sljit_s32 src2, sljit_sw src2w)
2655
+ {
2656
+ CHECK_ERROR();
2657
+ CHECK(check_sljit_emit_op2r(compiler, op, dst_reg, src1, src1w, src2, src2w));
2658
+
2659
+ switch (GET_OPCODE(op)) {
2660
+ case SLJIT_MULADD:
2661
+ SLJIT_SKIP_CHECKS(compiler);
2662
+ FAIL_IF(sljit_emit_op2(compiler, SLJIT_MUL | (op & SLJIT_32), TMP_REG2, 0, src1, src1w, src2, src2w));
2663
+ return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst_reg) | T(TMP_REG2) | D(dst_reg), DR(dst_reg));
2664
+ }
2665
+
2666
+ return SLJIT_SUCCESS;
2667
+ }
2668
+
2669
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
2670
+ sljit_s32 dst_reg,
2671
+ sljit_s32 src1_reg,
2672
+ sljit_s32 src2_reg,
2673
+ sljit_s32 src3, sljit_sw src3w)
2674
+ {
2675
+ sljit_s32 is_left;
2676
+ sljit_ins ins1, ins2, ins3;
2677
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2678
+ sljit_s32 inp_flags = ((op & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;
2679
+ sljit_sw bit_length = (op & SLJIT_32) ? 32 : 64;
2680
+ #else /* !SLJIT_CONFIG_MIPS_64 */
2681
+ sljit_s32 inp_flags = WORD_DATA | LOAD_DATA;
2682
+ sljit_sw bit_length = 32;
2683
+ #endif /* SLJIT_CONFIG_MIPS_64 */
2684
+
2685
+ CHECK_ERROR();
2686
+ CHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w));
2687
+
2688
+ is_left = (GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_MSHL);
2689
+
2690
+ if (src1_reg == src2_reg) {
2691
+ SLJIT_SKIP_CHECKS(compiler);
2692
+ return sljit_emit_op2(compiler, (is_left ? SLJIT_ROTL : SLJIT_ROTR) | (op & SLJIT_32), dst_reg, 0, src1_reg, 0, src3, src3w);
2693
+ }
2694
+
2695
+ ADJUST_LOCAL_OFFSET(src3, src3w);
2696
+
2697
+ if (src3 == SLJIT_IMM) {
2698
+ src3w &= bit_length - 1;
2699
+
2700
+ if (src3w == 0)
2701
+ return SLJIT_SUCCESS;
2702
+
2703
+ if (is_left) {
2704
+ ins1 = SELECT_OP3(op, src3w, DSLL, DSLL32, SLL);
2705
+ src3w = bit_length - src3w;
2706
+ ins2 = SELECT_OP3(op, src3w, DSRL, DSRL32, SRL);
2707
+ } else {
2708
+ ins1 = SELECT_OP3(op, src3w, DSRL, DSRL32, SRL);
2709
+ src3w = bit_length - src3w;
2710
+ ins2 = SELECT_OP3(op, src3w, DSLL, DSLL32, SLL);
2711
+ }
2712
+
2713
+ FAIL_IF(push_inst(compiler, ins1 | T(src1_reg) | D(dst_reg), DR(dst_reg)));
2714
+ FAIL_IF(push_inst(compiler, ins2 | T(src2_reg) | D(TMP_REG1), DR(TMP_REG1)));
2715
+ return push_inst(compiler, OR | S(dst_reg) | T(TMP_REG1) | D(dst_reg), DR(dst_reg));
2716
+ }
2717
+
2718
+ if (src3 & SLJIT_MEM) {
2719
+ FAIL_IF(emit_op_mem(compiler, inp_flags, DR(TMP_REG2), src3, src3w));
2720
+ src3 = TMP_REG2;
2721
+ } else if (dst_reg == src3) {
2722
+ FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src3) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
2723
+ src3 = TMP_REG2;
2724
+ }
2725
+
2726
+ if (is_left) {
2727
+ ins1 = SELECT_OP(DSRL, SRL);
2728
+ ins2 = SELECT_OP(DSLLV, SLLV);
2729
+ ins3 = SELECT_OP(DSRLV, SRLV);
2730
+ } else {
2731
+ ins1 = SELECT_OP(DSLL, SLL);
2732
+ ins2 = SELECT_OP(DSRLV, SRLV);
2733
+ ins3 = SELECT_OP(DSLLV, SLLV);
2734
+ }
2735
+
2736
+ FAIL_IF(push_inst(compiler, ins2 | S(src3) | T(src1_reg) | D(dst_reg), DR(dst_reg)));
2737
+
2738
+ if (!(op & SLJIT_SHIFT_INTO_NON_ZERO)) {
2739
+ FAIL_IF(push_inst(compiler, ins1 | T(src2_reg) | D(TMP_REG1) | (1 << 6), DR(TMP_REG1)));
2740
+ FAIL_IF(push_inst(compiler, XORI | S(src3) | T(TMP_REG2) | ((sljit_ins)bit_length - 1), DR(TMP_REG2)));
2741
+ src2_reg = TMP_REG1;
2742
+ } else
2743
+ FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(0) | T(src3) | D(TMP_REG2), DR(TMP_REG2)));
2744
+
2745
+ FAIL_IF(push_inst(compiler, ins3 | S(TMP_REG2) | T(src2_reg) | D(TMP_REG1), DR(TMP_REG1)));
2746
+ return push_inst(compiler, OR | S(dst_reg) | T(TMP_REG1) | D(dst_reg), DR(dst_reg));
2747
+ }
2748
+
2749
+ #undef SELECT_OP3
2750
+
2751
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
2752
+ sljit_s32 src, sljit_sw srcw)
2753
+ {
2754
+ CHECK_ERROR();
2755
+ CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
2756
+ ADJUST_LOCAL_OFFSET(src, srcw);
2757
+
2758
+ switch (op) {
2759
+ case SLJIT_FAST_RETURN:
2760
+ if (FAST_IS_REG(src))
2761
+ FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG));
2762
+ else
2763
+ FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw));
2764
+
2765
+ FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
2766
+ return push_inst(compiler, NOP, UNMOVABLE_INS);
2767
+ case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
2768
+ return SLJIT_SUCCESS;
2769
+ case SLJIT_PREFETCH_L1:
2770
+ case SLJIT_PREFETCH_L2:
2771
+ case SLJIT_PREFETCH_L3:
2772
+ case SLJIT_PREFETCH_ONCE:
2773
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
2774
+ return emit_prefetch(compiler, src, srcw);
2775
+ #else /* SLJIT_MIPS_REV < 1 */
2776
+ return SLJIT_SUCCESS;
2777
+ #endif /* SLJIT_MIPS_REV >= 1 */
2778
+ }
2779
+
2780
+ return SLJIT_SUCCESS;
2781
+ }
2782
+
2783
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op,
2784
+ sljit_s32 dst, sljit_sw dstw)
2785
+ {
2786
+ sljit_s32 dst_ar = RETURN_ADDR_REG;
2787
+
2788
+ CHECK_ERROR();
2789
+ CHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw));
2790
+ ADJUST_LOCAL_OFFSET(dst, dstw);
2791
+
2792
+ switch (op) {
2793
+ case SLJIT_FAST_ENTER:
2794
+ if (FAST_IS_REG(dst))
2795
+ return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), UNMOVABLE_INS);
2796
+ break;
2797
+ case SLJIT_GET_RETURN_ADDRESS:
2798
+ dst_ar = DR(FAST_IS_REG(dst) ? dst : TMP_REG2);
2799
+ FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, dst_ar, SLJIT_MEM1(SLJIT_SP), compiler->local_size - SSIZE_OF(sw)));
2800
+ break;
2801
+ }
2802
+
2803
+ if (dst & SLJIT_MEM) {
2804
+ FAIL_IF(emit_op_mem(compiler, WORD_DATA, dst_ar, dst, dstw));
2805
+
2806
+ if (op == SLJIT_FAST_ENTER)
2807
+ compiler->delay_slot = UNMOVABLE_INS;
2808
+ }
2809
+
2810
+ return SLJIT_SUCCESS;
2811
+ }
2812
+
2813
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg)
2814
+ {
2815
+ CHECK_REG_INDEX(check_sljit_get_register_index(type, reg));
2816
+
2817
+ if (type == SLJIT_GP_REGISTER)
2818
+ return reg_map[reg];
2819
+
2820
+ if (type != SLJIT_FLOAT_REGISTER)
2821
+ return -1;
2822
+
2823
+ return FR(reg);
2824
+ }
2825
+
2826
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
2827
+ void *instruction, sljit_u32 size)
2828
+ {
2829
+ SLJIT_UNUSED_ARG(size);
2830
+
2831
+ CHECK_ERROR();
2832
+ CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
2833
+
2834
+ return push_inst(compiler, *(sljit_ins*)instruction, UNMOVABLE_INS);
2835
+ }
2836
+
2837
+ /* --------------------------------------------------------------------- */
2838
+ /* Floating point operators */
2839
+ /* --------------------------------------------------------------------- */
2840
+
2841
+ #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_32) >> 7))
2842
+ #define FMT(op) (FMT_S | (~(sljit_ins)op & SLJIT_32) << (21 - (5 + 3)))
2843
+
2844
+ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
2845
+ sljit_s32 dst, sljit_sw dstw,
2846
+ sljit_s32 src, sljit_sw srcw)
2847
+ {
2848
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2849
+ sljit_u32 flags = 0;
2850
+ #else
2851
+ sljit_u32 flags = ((sljit_u32)(GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64)) << 21;
2852
+ #endif
2853
+
2854
+ if (src & SLJIT_MEM) {
2855
+ FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src, srcw, dst, dstw));
2856
+ src = TMP_FREG1;
2857
+ }
2858
+
2859
+ FAIL_IF(push_inst(compiler, (TRUNC_W_S ^ (flags >> 19)) | FMT(op) | FS(src) | FD(TMP_FREG1), MOVABLE_INS));
2860
+
2861
+ if (FAST_IS_REG(dst)) {
2862
+ FAIL_IF(push_inst(compiler, MFC1 | flags | T(dst) | FS(TMP_FREG1), MOVABLE_INS));
2863
+ #if !defined(SLJIT_MIPS_REV) || (SLJIT_CONFIG_MIPS_32 && SLJIT_MIPS_REV <= 1)
2864
+ FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
2865
+ #endif /* MIPS III */
2866
+ return SLJIT_SUCCESS;
2867
+ }
2868
+
2869
+ return emit_op_mem2(compiler, flags ? DOUBLE_DATA : SINGLE_DATA, FR(TMP_FREG1), dst, dstw, 0, 0);
2870
+ }
2871
+
2872
+ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
2873
+ sljit_s32 dst, sljit_sw dstw,
2874
+ sljit_s32 src, sljit_sw srcw)
2875
+ {
2876
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2877
+ sljit_u32 flags = 0;
2878
+ #else
2879
+ sljit_u32 flags = ((sljit_u32)(GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW)) << 21;
2880
+ #endif
2881
+ sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
2882
+
2883
+ if (src & SLJIT_MEM)
2884
+ FAIL_IF(emit_op_mem2(compiler, (flags ? DOUBLE_DATA : SINGLE_DATA) | LOAD_DATA, FR(TMP_FREG1), src, srcw, dst, dstw));
2885
+ else {
2886
+ if (src == SLJIT_IMM) {
2887
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2888
+ if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
2889
+ srcw = (sljit_s32)srcw;
2890
+ #endif
2891
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw));
2892
+ src = TMP_REG1;
2893
+ }
2894
+
2895
+ FAIL_IF(push_inst(compiler, MTC1 | flags | T(src) | FS(TMP_FREG1), MOVABLE_INS));
2896
+ #if !defined(SLJIT_MIPS_REV) || (SLJIT_CONFIG_MIPS_32 && SLJIT_MIPS_REV <= 1)
2897
+ FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
2898
+ #endif /* MIPS III */
2899
+ }
2900
+
2901
+ FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | ((~(sljit_ins)op & SLJIT_32) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS));
2902
+
2903
+ if (dst & SLJIT_MEM)
2904
+ return emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0);
2905
+ return SLJIT_SUCCESS;
2906
+ }
2907
+
2908
+ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op,
2909
+ sljit_s32 dst, sljit_sw dstw,
2910
+ sljit_s32 src, sljit_sw srcw)
2911
+ {
2912
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
2913
+ sljit_u32 flags = 0;
2914
+ #else
2915
+ sljit_u32 flags = 1 << 21;
2916
+ #endif
2917
+ sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
2918
+
2919
+ if (src & SLJIT_MEM) {
2920
+ FAIL_IF(emit_op_mem2(compiler, (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_UW ? WORD_DATA : INT_DATA) | LOAD_DATA, DR(TMP_REG1), src, srcw, dst, dstw));
2921
+ src = TMP_REG1;
2922
+ } else if (src == SLJIT_IMM) {
2923
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2924
+ if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_U32)
2925
+ srcw = (sljit_u32)srcw;
2926
+ #endif
2927
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw));
2928
+ src = TMP_REG1;
2929
+ }
2930
+
2931
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
2932
+ if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_U32) {
2933
+ if (src != TMP_REG1) {
2934
+ FAIL_IF(push_inst(compiler, DSLL32 | T(src) | D(TMP_REG1) | SH_IMM(0), DR(TMP_REG1)));
2935
+ FAIL_IF(push_inst(compiler, DSRL32 | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(0), DR(TMP_REG1)));
2936
+ }
2937
+
2938
+ FAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG1) | FS(TMP_FREG1), MOVABLE_INS));
2939
+ #if !defined(SLJIT_MIPS_REV)
2940
+ FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
2941
+ #endif /* MIPS III */
2942
+
2943
+ FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | ((~(sljit_ins)op & SLJIT_32) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS));
2944
+
2945
+ if (dst & SLJIT_MEM)
2946
+ return emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0);
2947
+ return SLJIT_SUCCESS;
2948
+ }
2949
+ #else /* !SLJIT_CONFIG_MIPS_64 */
2950
+ if (!(op & SLJIT_32)) {
2951
+ FAIL_IF(push_inst(compiler, SLL | T(src) | D(TMP_REG2) | SH_IMM(1), DR(TMP_REG2)));
2952
+ FAIL_IF(push_inst(compiler, SRL | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(1), DR(TMP_REG2)));
2953
+
2954
+ FAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG2) | FS(TMP_FREG1), MOVABLE_INS));
2955
+ #if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1
2956
+ FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
2957
+ #endif /* MIPS III */
2958
+
2959
+ FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | 1 | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS));
2960
+
2961
+ #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 1)
2962
+ FAIL_IF(push_inst(compiler, BGEZ | S(src) | 5, UNMOVABLE_INS));
2963
+ #else /* SLJIT_MIPS_REV >= 1 */
2964
+ FAIL_IF(push_inst(compiler, BGEZ | S(src) | 4, UNMOVABLE_INS));
2965
+ #endif /* SLJIT_MIPS_REV < 1 */
2966
+
2967
+ FAIL_IF(push_inst(compiler, LUI | T(TMP_REG2) | IMM(0x41e0), UNMOVABLE_INS));
2968
+ FAIL_IF(push_inst(compiler, MTC1 | TA(0) | FS(TMP_FREG2), UNMOVABLE_INS));
2969
+ switch (cpu_feature_list & CPU_FEATURE_FR) {
2970
+ #if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
2971
+ case CPU_FEATURE_FR:
2972
+ FAIL_IF(push_inst(compiler, MTHC1 | T(TMP_REG2) | FS(TMP_FREG2), UNMOVABLE_INS));
2973
+ break;
2974
+ #endif /* SLJIT_MIPS_REV >= 2 */
2975
+ default:
2976
+ FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | FS(TMP_FREG2) | (1 << 11), UNMOVABLE_INS));
2977
+ #if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1
2978
+ FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
2979
+ #endif /* MIPS III */
2980
+ break;
2981
+ }
2982
+ FAIL_IF(push_inst(compiler, ADD_S | FMT(op) | FT(TMP_FREG2) | FS(dst_r) | FD(dst_r), UNMOVABLE_INS));
2983
+
2984
+ if (dst & SLJIT_MEM)
2985
+ return emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0);
2986
+ return SLJIT_SUCCESS;
2987
+ }
2988
+ #endif /* SLJIT_CONFIG_MIPS_64 */
2989
+
2990
+ #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 1)
2991
+ FAIL_IF(push_inst(compiler, BLTZ | S(src) | 5, UNMOVABLE_INS));
2992
+ #else /* SLJIT_MIPS_REV >= 1 */
2993
+ FAIL_IF(push_inst(compiler, BLTZ | S(src) | 4, UNMOVABLE_INS));
2994
+ #endif /* SLJIT_MIPS_REV < 1 */
2995
+ FAIL_IF(push_inst(compiler, ANDI | S(src) | T(TMP_REG2) | IMM(1), DR(TMP_REG2)));
2996
+
2997
+ FAIL_IF(push_inst(compiler, MTC1 | flags | T(src) | FS(TMP_FREG1), MOVABLE_INS));
2998
+ #if !defined(SLJIT_MIPS_REV)
2999
+ FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
3000
+ #endif /* !SLJIT_MIPS_REV */
3001
+
3002
+ FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | ((~(sljit_ins)op & SLJIT_32) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS));
3003
+
3004
+ #if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 1)
3005
+ FAIL_IF(push_inst(compiler, BEQ | 6, UNMOVABLE_INS));
3006
+ #else /* SLJIT_MIPS_REV >= 1 */
3007
+ FAIL_IF(push_inst(compiler, BEQ | 5, UNMOVABLE_INS));
3008
+ #endif /* SLJIT_MIPS_REV < 1 */
3009
+
3010
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
3011
+ FAIL_IF(push_inst(compiler, DSRL | T(src) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1)));
3012
+ #else /* !SLJIT_CONFIG_MIPS_64 */
3013
+ FAIL_IF(push_inst(compiler, SRL | T(src) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1)));
3014
+ #endif /* SLJIT_CONFIG_MIPS_64 */
3015
+
3016
+ FAIL_IF(push_inst(compiler, OR | S(TMP_REG1) | T(TMP_REG2) | D(TMP_REG1), DR(TMP_REG1)));
3017
+
3018
+ FAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG1) | FS(TMP_FREG1), MOVABLE_INS));
3019
+ #if !defined(SLJIT_MIPS_REV)
3020
+ FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
3021
+ #endif /* !SLJIT_MIPS_REV */
3022
+
3023
+ FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | ((~(sljit_ins)op & SLJIT_32) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS));
3024
+ FAIL_IF(push_inst(compiler, ADD_S | FMT(op) | FT(dst_r) | FS(dst_r) | FD(dst_r), UNMOVABLE_INS));
3025
+
3026
+ if (dst & SLJIT_MEM)
3027
+ return emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0);
3028
+ return SLJIT_SUCCESS;
3029
+ }
3030
+
3031
+ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
3032
+ sljit_s32 src1, sljit_sw src1w,
3033
+ sljit_s32 src2, sljit_sw src2w)
3034
+ {
3035
+ sljit_ins inst;
3036
+
3037
+ if (src1 & SLJIT_MEM) {
3038
+ FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, src2, src2w));
3039
+ src1 = TMP_FREG1;
3040
+ }
3041
+
3042
+ if (src2 & SLJIT_MEM) {
3043
+ FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, 0, 0));
3044
+ src2 = TMP_FREG2;
3045
+ }
3046
+
3047
+ switch (GET_FLAG_TYPE(op)) {
3048
+ case SLJIT_F_EQUAL:
3049
+ case SLJIT_ORDERED_EQUAL:
3050
+ inst = C_EQ_S;
3051
+ break;
3052
+ case SLJIT_F_NOT_EQUAL:
3053
+ case SLJIT_UNORDERED_OR_EQUAL:
3054
+ inst = C_UEQ_S;
3055
+ break;
3056
+ case SLJIT_F_LESS:
3057
+ case SLJIT_ORDERED_LESS:
3058
+ inst = C_OLT_S;
3059
+ break;
3060
+ case SLJIT_F_GREATER_EQUAL:
3061
+ case SLJIT_UNORDERED_OR_LESS:
3062
+ inst = C_ULT_S;
3063
+ break;
3064
+ case SLJIT_F_GREATER:
3065
+ case SLJIT_ORDERED_GREATER:
3066
+ inst = C_ULE_S;
3067
+ break;
3068
+ case SLJIT_F_LESS_EQUAL:
3069
+ case SLJIT_UNORDERED_OR_GREATER:
3070
+ inst = C_OLE_S;
3071
+ break;
3072
+ default:
3073
+ SLJIT_ASSERT(GET_FLAG_TYPE(op) == SLJIT_UNORDERED);
3074
+ inst = C_UN_S;
3075
+ break;
3076
+ }
3077
+ return push_inst(compiler, inst | FMT(op) | FT(src2) | FS(src1) | C_FD, UNMOVABLE_INS);
3078
+ }
3079
+
3080
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
3081
+ sljit_s32 dst, sljit_sw dstw,
3082
+ sljit_s32 src, sljit_sw srcw)
3083
+ {
3084
+ sljit_s32 dst_r;
3085
+
3086
+ CHECK_ERROR();
3087
+ compiler->cache_arg = 0;
3088
+ compiler->cache_argw = 0;
3089
+
3090
+ SLJIT_COMPILE_ASSERT((SLJIT_32 == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error);
3091
+ SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw);
3092
+
3093
+ if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
3094
+ op ^= SLJIT_32;
3095
+
3096
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
3097
+
3098
+ if (src & SLJIT_MEM) {
3099
+ FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(dst_r), src, srcw, dst, dstw));
3100
+ src = dst_r;
3101
+ }
3102
+
3103
+ switch (GET_OPCODE(op)) {
3104
+ case SLJIT_MOV_F64:
3105
+ if (src != dst_r) {
3106
+ if (!(dst & SLJIT_MEM))
3107
+ FAIL_IF(push_inst(compiler, MOV_fmt(FMT(op)) | FS(src) | FD(dst_r), MOVABLE_INS));
3108
+ else
3109
+ dst_r = src;
3110
+ }
3111
+ break;
3112
+ case SLJIT_NEG_F64:
3113
+ FAIL_IF(push_inst(compiler, NEG_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS));
3114
+ break;
3115
+ case SLJIT_ABS_F64:
3116
+ FAIL_IF(push_inst(compiler, ABS_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS));
3117
+ break;
3118
+ case SLJIT_CONV_F64_FROM_F32:
3119
+ /* The SLJIT_32 bit is inverted because sljit_f32 needs to be loaded from the memory. */
3120
+ FAIL_IF(push_inst(compiler, CVT_S_S | (sljit_ins)((op & SLJIT_32) ? 1 : (1 << 21)) | FS(src) | FD(dst_r), MOVABLE_INS));
3121
+ op ^= SLJIT_32;
3122
+ break;
3123
+ }
3124
+
3125
+ if (dst & SLJIT_MEM)
3126
+ return emit_op_mem2(compiler, FLOAT_DATA(op), FR(dst_r), dst, dstw, 0, 0);
3127
+ return SLJIT_SUCCESS;
3128
+ }
3129
+
3130
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
3131
+ sljit_s32 dst, sljit_sw dstw,
3132
+ sljit_s32 src1, sljit_sw src1w,
3133
+ sljit_s32 src2, sljit_sw src2w)
3134
+ {
3135
+ sljit_s32 dst_r, flags = 0;
3136
+
3137
+ CHECK_ERROR();
3138
+ CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
3139
+ ADJUST_LOCAL_OFFSET(dst, dstw);
3140
+ ADJUST_LOCAL_OFFSET(src1, src1w);
3141
+ ADJUST_LOCAL_OFFSET(src2, src2w);
3142
+
3143
+ compiler->cache_arg = 0;
3144
+ compiler->cache_argw = 0;
3145
+
3146
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;
3147
+
3148
+ if (src1 & SLJIT_MEM) {
3149
+ if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w)) {
3150
+ FAIL_IF(compiler->error);
3151
+ src1 = TMP_FREG1;
3152
+ } else
3153
+ flags |= SLOW_SRC1;
3154
+ }
3155
+
3156
+ if (src2 & SLJIT_MEM) {
3157
+ if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w)) {
3158
+ FAIL_IF(compiler->error);
3159
+ src2 = TMP_FREG2;
3160
+ } else
3161
+ flags |= SLOW_SRC2;
3162
+ }
3163
+
3164
+ if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
3165
+ if ((dst & SLJIT_MEM) && !can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
3166
+ FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, src1, src1w));
3167
+ FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, dst, dstw));
3168
+ } else {
3169
+ FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, src2, src2w));
3170
+ FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, dst, dstw));
3171
+ }
3172
+ }
3173
+ else if (flags & SLOW_SRC1)
3174
+ FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, dst, dstw));
3175
+ else if (flags & SLOW_SRC2)
3176
+ FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, dst, dstw));
3177
+
3178
+ if (flags & SLOW_SRC1)
3179
+ src1 = TMP_FREG1;
3180
+ if (flags & SLOW_SRC2)
3181
+ src2 = TMP_FREG2;
3182
+
3183
+ switch (GET_OPCODE(op)) {
3184
+ case SLJIT_ADD_F64:
3185
+ FAIL_IF(push_inst(compiler, ADD_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
3186
+ break;
3187
+ case SLJIT_SUB_F64:
3188
+ FAIL_IF(push_inst(compiler, SUB_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
3189
+ break;
3190
+ case SLJIT_MUL_F64:
3191
+ FAIL_IF(push_inst(compiler, MUL_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
3192
+ break;
3193
+ case SLJIT_DIV_F64:
3194
+ FAIL_IF(push_inst(compiler, DIV_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS));
3195
+ break;
3196
+ case SLJIT_COPYSIGN_F64:
3197
+ return emit_copysign(compiler, op, src1, src2, dst_r);
3198
+ }
3199
+
3200
+ if (dst_r == TMP_FREG2)
3201
+ FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG2), dst, dstw, 0, 0));
3202
+
3203
+ return SLJIT_SUCCESS;
3204
+ }
3205
+
3206
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler,
3207
+ sljit_s32 freg, sljit_f32 value)
3208
+ {
3209
+ union {
3210
+ sljit_s32 imm;
3211
+ sljit_f32 value;
3212
+ } u;
3213
+
3214
+ CHECK_ERROR();
3215
+ CHECK(check_sljit_emit_fset32(compiler, freg, value));
3216
+
3217
+ u.value = value;
3218
+
3219
+ if (u.imm == 0)
3220
+ return push_inst(compiler, MTC1 | TA(0) | FS(freg), MOVABLE_INS);
3221
+
3222
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG1), u.imm));
3223
+ return push_inst(compiler, MTC1 | T(TMP_REG1) | FS(freg), MOVABLE_INS);
3224
+ }
3225
+
3226
+ /* --------------------------------------------------------------------- */
3227
+ /* Conditional instructions */
3228
+ /* --------------------------------------------------------------------- */
3229
+
3230
+ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
3231
+ {
3232
+ struct sljit_label *label;
3233
+
3234
+ CHECK_ERROR_PTR();
3235
+ CHECK_PTR(check_sljit_emit_label(compiler));
3236
+
3237
+ if (compiler->last_label && compiler->last_label->size == compiler->size)
3238
+ return compiler->last_label;
3239
+
3240
+ label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
3241
+ PTR_FAIL_IF(!label);
3242
+ set_label(label, compiler);
3243
+ compiler->delay_slot = UNMOVABLE_INS;
3244
+ return label;
3245
+ }
3246
+
3247
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3248
+ #define BRANCH_LENGTH 4
3249
+ #else
3250
+ #define BRANCH_LENGTH 8
3251
+ #endif
3252
+
3253
+ #define BR_Z(src) \
3254
+ inst = BEQ | SA(src) | TA(0) | BRANCH_LENGTH; \
3255
+ flags = IS_BIT26_COND; \
3256
+ delay_check = src;
3257
+
3258
+ #define BR_NZ(src) \
3259
+ inst = BNE | SA(src) | TA(0) | BRANCH_LENGTH; \
3260
+ flags = IS_BIT26_COND; \
3261
+ delay_check = src;
3262
+
3263
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
3264
+
3265
+ #define BR_T() \
3266
+ inst = BC1NEZ; \
3267
+ flags = IS_BIT23_COND; \
3268
+ delay_check = FCSR_FCC;
3269
+ #define BR_F() \
3270
+ inst = BC1EQZ; \
3271
+ flags = IS_BIT23_COND; \
3272
+ delay_check = FCSR_FCC;
3273
+
3274
+ #else /* SLJIT_MIPS_REV < 6 */
3275
+
3276
+ #define BR_T() \
3277
+ inst = BC1T | BRANCH_LENGTH; \
3278
+ flags = IS_BIT16_COND; \
3279
+ delay_check = FCSR_FCC;
3280
+ #define BR_F() \
3281
+ inst = BC1F | BRANCH_LENGTH; \
3282
+ flags = IS_BIT16_COND; \
3283
+ delay_check = FCSR_FCC;
3284
+
3285
+ #endif /* SLJIT_MIPS_REV >= 6 */
3286
+
3287
+ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
3288
+ {
3289
+ struct sljit_jump *jump;
3290
+ sljit_ins inst;
3291
+ sljit_u32 flags = 0;
3292
+ sljit_s32 delay_check = UNMOVABLE_INS;
3293
+
3294
+ CHECK_ERROR_PTR();
3295
+ CHECK_PTR(check_sljit_emit_jump(compiler, type));
3296
+
3297
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
3298
+ PTR_FAIL_IF(!jump);
3299
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
3300
+ type &= 0xff;
3301
+
3302
+ switch (type) {
3303
+ case SLJIT_EQUAL:
3304
+ BR_NZ(EQUAL_FLAG);
3305
+ break;
3306
+ case SLJIT_NOT_EQUAL:
3307
+ BR_Z(EQUAL_FLAG);
3308
+ break;
3309
+ case SLJIT_LESS:
3310
+ case SLJIT_GREATER:
3311
+ case SLJIT_SIG_LESS:
3312
+ case SLJIT_SIG_GREATER:
3313
+ case SLJIT_OVERFLOW:
3314
+ case SLJIT_CARRY:
3315
+ BR_Z(OTHER_FLAG);
3316
+ break;
3317
+ case SLJIT_GREATER_EQUAL:
3318
+ case SLJIT_LESS_EQUAL:
3319
+ case SLJIT_SIG_GREATER_EQUAL:
3320
+ case SLJIT_SIG_LESS_EQUAL:
3321
+ case SLJIT_NOT_OVERFLOW:
3322
+ case SLJIT_NOT_CARRY:
3323
+ BR_NZ(OTHER_FLAG);
3324
+ break;
3325
+ case SLJIT_F_NOT_EQUAL:
3326
+ case SLJIT_F_GREATER_EQUAL:
3327
+ case SLJIT_F_GREATER:
3328
+ case SLJIT_UNORDERED_OR_NOT_EQUAL:
3329
+ case SLJIT_ORDERED_NOT_EQUAL:
3330
+ case SLJIT_UNORDERED_OR_GREATER_EQUAL:
3331
+ case SLJIT_ORDERED_GREATER_EQUAL:
3332
+ case SLJIT_ORDERED_GREATER:
3333
+ case SLJIT_UNORDERED_OR_GREATER:
3334
+ case SLJIT_ORDERED:
3335
+ BR_T();
3336
+ break;
3337
+ case SLJIT_F_EQUAL:
3338
+ case SLJIT_F_LESS:
3339
+ case SLJIT_F_LESS_EQUAL:
3340
+ case SLJIT_ORDERED_EQUAL:
3341
+ case SLJIT_UNORDERED_OR_EQUAL:
3342
+ case SLJIT_ORDERED_LESS:
3343
+ case SLJIT_UNORDERED_OR_LESS:
3344
+ case SLJIT_UNORDERED_OR_LESS_EQUAL:
3345
+ case SLJIT_ORDERED_LESS_EQUAL:
3346
+ case SLJIT_UNORDERED:
3347
+ BR_F();
3348
+ break;
3349
+ default:
3350
+ /* Not conditional branch. */
3351
+ inst = 0;
3352
+ break;
3353
+ }
3354
+
3355
+ jump->flags |= flags;
3356
+ if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != delay_check))
3357
+ jump->flags |= IS_MOVABLE;
3358
+
3359
+ if (inst)
3360
+ PTR_FAIL_IF(push_inst(compiler, inst, UNMOVABLE_INS));
3361
+
3362
+ if (type <= SLJIT_JUMP)
3363
+ PTR_FAIL_IF(push_inst(compiler, JR | S(PIC_ADDR_REG), UNMOVABLE_INS));
3364
+ else {
3365
+ jump->flags |= IS_JAL;
3366
+ PTR_FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
3367
+ }
3368
+
3369
+ jump->addr = compiler->size;
3370
+ PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
3371
+
3372
+ /* Maximum number of instructions required for generating a constant. */
3373
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3374
+ compiler->size += 2;
3375
+ #else
3376
+ compiler->size += 6;
3377
+ #endif
3378
+ return jump;
3379
+ }
3380
+
3381
+ #define RESOLVE_IMM1() \
3382
+ if (src1 == SLJIT_IMM) { \
3383
+ if (src1w) { \
3384
+ PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); \
3385
+ src1 = TMP_REG1; \
3386
+ } \
3387
+ else \
3388
+ src1 = 0; \
3389
+ }
3390
+
3391
+ #define RESOLVE_IMM2() \
3392
+ if (src2 == SLJIT_IMM) { \
3393
+ if (src2w) { \
3394
+ PTR_FAIL_IF(load_immediate(compiler, DR(src2_tmp_reg), src2w)); \
3395
+ src2 = src2_tmp_reg; \
3396
+ } \
3397
+ else \
3398
+ src2 = 0; \
3399
+ }
3400
+
3401
+ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
3402
+ sljit_s32 src1, sljit_sw src1w,
3403
+ sljit_s32 src2, sljit_sw src2w)
3404
+ {
3405
+ struct sljit_jump *jump;
3406
+ sljit_s32 flags;
3407
+ sljit_ins inst;
3408
+ sljit_s32 src2_tmp_reg = FAST_IS_REG(src1) ? TMP_REG1 : TMP_REG2;
3409
+
3410
+ CHECK_ERROR_PTR();
3411
+ CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));
3412
+ ADJUST_LOCAL_OFFSET(src1, src1w);
3413
+ ADJUST_LOCAL_OFFSET(src2, src2w);
3414
+
3415
+ compiler->cache_arg = 0;
3416
+ compiler->cache_argw = 0;
3417
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3418
+ flags = WORD_DATA | LOAD_DATA;
3419
+ #else /* !SLJIT_CONFIG_MIPS_32 */
3420
+ flags = ((type & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;
3421
+ #endif /* SLJIT_CONFIG_MIPS_32 */
3422
+
3423
+ if (src1 & SLJIT_MEM) {
3424
+ PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG1), src1, src1w, src2, src2w));
3425
+ src1 = TMP_REG1;
3426
+ }
3427
+
3428
+ if (src2 & SLJIT_MEM) {
3429
+ PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(src2_tmp_reg), src2, src2w, 0, 0));
3430
+ src2 = src2_tmp_reg;
3431
+ }
3432
+
3433
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
3434
+ PTR_FAIL_IF(!jump);
3435
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
3436
+ type &= 0xff;
3437
+
3438
+ if (type <= SLJIT_NOT_EQUAL) {
3439
+ RESOLVE_IMM1();
3440
+ RESOLVE_IMM2();
3441
+ jump->flags |= IS_BIT26_COND;
3442
+ if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != DR(src1) && compiler->delay_slot != DR(src2)))
3443
+ jump->flags |= IS_MOVABLE;
3444
+ PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_EQUAL ? BNE : BEQ) | S(src1) | T(src2) | BRANCH_LENGTH, UNMOVABLE_INS));
3445
+ } else if (type >= SLJIT_SIG_LESS && ((src1 == SLJIT_IMM && src1w == 0) || (src2 == SLJIT_IMM && src2w == 0))) {
3446
+ inst = NOP;
3447
+ if (src1 == SLJIT_IMM && src1w == 0) {
3448
+ RESOLVE_IMM2();
3449
+ switch (type) {
3450
+ case SLJIT_SIG_LESS:
3451
+ inst = BLEZ;
3452
+ jump->flags |= IS_BIT26_COND;
3453
+ break;
3454
+ case SLJIT_SIG_GREATER_EQUAL:
3455
+ inst = BGTZ;
3456
+ jump->flags |= IS_BIT26_COND;
3457
+ break;
3458
+ case SLJIT_SIG_GREATER:
3459
+ inst = BGEZ;
3460
+ jump->flags |= IS_BIT16_COND;
3461
+ break;
3462
+ case SLJIT_SIG_LESS_EQUAL:
3463
+ inst = BLTZ;
3464
+ jump->flags |= IS_BIT16_COND;
3465
+ break;
3466
+ }
3467
+ src1 = src2;
3468
+ }
3469
+ else {
3470
+ RESOLVE_IMM1();
3471
+ switch (type) {
3472
+ case SLJIT_SIG_LESS:
3473
+ inst = BGEZ;
3474
+ jump->flags |= IS_BIT16_COND;
3475
+ break;
3476
+ case SLJIT_SIG_GREATER_EQUAL:
3477
+ inst = BLTZ;
3478
+ jump->flags |= IS_BIT16_COND;
3479
+ break;
3480
+ case SLJIT_SIG_GREATER:
3481
+ inst = BLEZ;
3482
+ jump->flags |= IS_BIT26_COND;
3483
+ break;
3484
+ case SLJIT_SIG_LESS_EQUAL:
3485
+ inst = BGTZ;
3486
+ jump->flags |= IS_BIT26_COND;
3487
+ break;
3488
+ }
3489
+ }
3490
+ PTR_FAIL_IF(push_inst(compiler, inst | S(src1) | BRANCH_LENGTH, UNMOVABLE_INS));
3491
+ }
3492
+ else {
3493
+ if (type == SLJIT_LESS || type == SLJIT_GREATER_EQUAL || type == SLJIT_SIG_LESS || type == SLJIT_SIG_GREATER_EQUAL) {
3494
+ RESOLVE_IMM1();
3495
+ if (src2 == SLJIT_IMM && src2w <= SIMM_MAX && src2w >= SIMM_MIN)
3496
+ PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTIU : SLTI) | S(src1) | T(TMP_REG1) | IMM(src2w), DR(TMP_REG1)));
3497
+ else {
3498
+ RESOLVE_IMM2();
3499
+ PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTU : SLT) | S(src1) | T(src2) | D(TMP_REG1), DR(TMP_REG1)));
3500
+ }
3501
+ type = (type == SLJIT_LESS || type == SLJIT_SIG_LESS) ? SLJIT_NOT_EQUAL : SLJIT_EQUAL;
3502
+ }
3503
+ else {
3504
+ RESOLVE_IMM2();
3505
+ if (src1 == SLJIT_IMM && src1w <= SIMM_MAX && src1w >= SIMM_MIN)
3506
+ PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTIU : SLTI) | S(src2) | T(TMP_REG1) | IMM(src1w), DR(TMP_REG1)));
3507
+ else {
3508
+ RESOLVE_IMM1();
3509
+ PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTU : SLT) | S(src2) | T(src1) | D(TMP_REG1), DR(TMP_REG1)));
3510
+ }
3511
+ type = (type == SLJIT_GREATER || type == SLJIT_SIG_GREATER) ? SLJIT_NOT_EQUAL : SLJIT_EQUAL;
3512
+ }
3513
+
3514
+ jump->flags |= IS_BIT26_COND;
3515
+ PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_EQUAL ? BNE : BEQ) | S(TMP_REG1) | TA(0) | BRANCH_LENGTH, UNMOVABLE_INS));
3516
+ }
3517
+
3518
+ PTR_FAIL_IF(push_inst(compiler, JR | S(PIC_ADDR_REG), UNMOVABLE_INS));
3519
+ jump->addr = compiler->size;
3520
+ PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
3521
+
3522
+ /* Maximum number of instructions required for generating a constant. */
3523
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3524
+ compiler->size += 2;
3525
+ #else
3526
+ compiler->size += 6;
3527
+ #endif
3528
+ return jump;
3529
+ }
3530
+
3531
+ #undef RESOLVE_IMM1
3532
+ #undef RESOLVE_IMM2
3533
+
3534
+ #undef BRANCH_LENGTH
3535
+ #undef BR_Z
3536
+ #undef BR_NZ
3537
+ #undef BR_T
3538
+ #undef BR_F
3539
+
3540
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
3541
+ {
3542
+ struct sljit_jump *jump = NULL;
3543
+
3544
+ CHECK_ERROR();
3545
+ CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
3546
+
3547
+ if (src == SLJIT_IMM) {
3548
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
3549
+ FAIL_IF(!jump);
3550
+ set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_JAL : 0));
3551
+ jump->u.target = (sljit_uw)srcw;
3552
+
3553
+ if (compiler->delay_slot != UNMOVABLE_INS)
3554
+ jump->flags |= IS_MOVABLE;
3555
+
3556
+ src = PIC_ADDR_REG;
3557
+ } else if (src & SLJIT_MEM) {
3558
+ ADJUST_LOCAL_OFFSET(src, srcw);
3559
+ FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(PIC_ADDR_REG), src, srcw));
3560
+ src = PIC_ADDR_REG;
3561
+ }
3562
+
3563
+ if (type <= SLJIT_JUMP)
3564
+ FAIL_IF(push_inst(compiler, JR | S(src), UNMOVABLE_INS));
3565
+ else
3566
+ FAIL_IF(push_inst(compiler, JALR | S(src) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
3567
+
3568
+ if (jump != NULL) {
3569
+ jump->addr = compiler->size;
3570
+
3571
+ /* Maximum number of instructions required for generating a constant. */
3572
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3573
+ compiler->size += 2;
3574
+ #else
3575
+ compiler->size += 6;
3576
+ #endif
3577
+ }
3578
+
3579
+ return push_inst(compiler, NOP, UNMOVABLE_INS);
3580
+ }
3581
+
3582
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
3583
+ sljit_s32 dst, sljit_sw dstw,
3584
+ sljit_s32 type)
3585
+ {
3586
+ sljit_s32 src_ar, dst_ar, invert;
3587
+ sljit_s32 saved_op = op;
3588
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3589
+ sljit_s32 mem_type = WORD_DATA;
3590
+ #else
3591
+ sljit_s32 mem_type = ((op & SLJIT_32) || op == SLJIT_MOV32) ? (INT_DATA | SIGNED_DATA) : WORD_DATA;
3592
+ #endif
3593
+
3594
+ CHECK_ERROR();
3595
+ CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
3596
+ ADJUST_LOCAL_OFFSET(dst, dstw);
3597
+
3598
+ op = GET_OPCODE(op);
3599
+ dst_ar = DR((op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2);
3600
+
3601
+ compiler->cache_arg = 0;
3602
+ compiler->cache_argw = 0;
3603
+
3604
+ if (op >= SLJIT_ADD && (dst & SLJIT_MEM))
3605
+ FAIL_IF(emit_op_mem2(compiler, mem_type | LOAD_DATA, DR(TMP_REG1), dst, dstw, dst, dstw));
3606
+
3607
+ if (type < SLJIT_F_EQUAL) {
3608
+ src_ar = OTHER_FLAG;
3609
+ invert = type & 0x1;
3610
+
3611
+ switch (type) {
3612
+ case SLJIT_EQUAL:
3613
+ case SLJIT_NOT_EQUAL:
3614
+ FAIL_IF(push_inst(compiler, SLTIU | SA(EQUAL_FLAG) | TA(dst_ar) | IMM(1), dst_ar));
3615
+ src_ar = dst_ar;
3616
+ break;
3617
+ case SLJIT_OVERFLOW:
3618
+ case SLJIT_NOT_OVERFLOW:
3619
+ if (compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)) {
3620
+ src_ar = OTHER_FLAG;
3621
+ break;
3622
+ }
3623
+ FAIL_IF(push_inst(compiler, SLTIU | SA(OTHER_FLAG) | TA(dst_ar) | IMM(1), dst_ar));
3624
+ src_ar = dst_ar;
3625
+ invert ^= 0x1;
3626
+ break;
3627
+ }
3628
+ } else {
3629
+ invert = 0;
3630
+
3631
+ switch (type) {
3632
+ case SLJIT_F_NOT_EQUAL:
3633
+ case SLJIT_F_GREATER_EQUAL:
3634
+ case SLJIT_F_GREATER:
3635
+ case SLJIT_UNORDERED_OR_NOT_EQUAL:
3636
+ case SLJIT_ORDERED_NOT_EQUAL:
3637
+ case SLJIT_UNORDERED_OR_GREATER_EQUAL:
3638
+ case SLJIT_ORDERED_GREATER_EQUAL:
3639
+ case SLJIT_ORDERED_GREATER:
3640
+ case SLJIT_UNORDERED_OR_GREATER:
3641
+ case SLJIT_ORDERED:
3642
+ invert = 1;
3643
+ break;
3644
+ }
3645
+
3646
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
3647
+ FAIL_IF(push_inst(compiler, MFC1 | TA(dst_ar) | FS(TMP_FREG3), dst_ar));
3648
+ #else /* SLJIT_MIPS_REV < 6 */
3649
+ FAIL_IF(push_inst(compiler, CFC1 | TA(dst_ar) | DA(FCSR_REG), dst_ar));
3650
+ #endif /* SLJIT_MIPS_REV >= 6 */
3651
+ FAIL_IF(push_inst(compiler, SRL | TA(dst_ar) | DA(dst_ar) | SH_IMM(23), dst_ar));
3652
+ FAIL_IF(push_inst(compiler, ANDI | SA(dst_ar) | TA(dst_ar) | IMM(1), dst_ar));
3653
+ src_ar = dst_ar;
3654
+ }
3655
+
3656
+ if (invert) {
3657
+ FAIL_IF(push_inst(compiler, XORI | SA(src_ar) | TA(dst_ar) | IMM(1), dst_ar));
3658
+ src_ar = dst_ar;
3659
+ }
3660
+
3661
+ if (op < SLJIT_ADD) {
3662
+ if (dst & SLJIT_MEM)
3663
+ return emit_op_mem(compiler, mem_type, src_ar, dst, dstw);
3664
+
3665
+ if (src_ar != dst_ar)
3666
+ return push_inst(compiler, ADDU_W | SA(src_ar) | TA(0) | DA(dst_ar), dst_ar);
3667
+ return SLJIT_SUCCESS;
3668
+ }
3669
+
3670
+ /* OTHER_FLAG cannot be specified as src2 argument at the moment. */
3671
+ if (DR(TMP_REG2) != src_ar)
3672
+ FAIL_IF(push_inst(compiler, ADDU_W | SA(src_ar) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
3673
+
3674
+ mem_type |= CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE;
3675
+
3676
+ if (dst & SLJIT_MEM)
3677
+ return emit_op(compiler, saved_op, mem_type, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
3678
+ return emit_op(compiler, saved_op, mem_type, dst, dstw, dst, dstw, TMP_REG2, 0);
3679
+ }
3680
+
3681
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
3682
+
3683
+ static sljit_ins get_select_cc(sljit_s32 type, sljit_s32 is_float)
3684
+ {
3685
+ switch (type & ~SLJIT_32) {
3686
+ case SLJIT_EQUAL:
3687
+ return (is_float ? MOVZ_S : MOVZ) | TA(EQUAL_FLAG);
3688
+ case SLJIT_NOT_EQUAL:
3689
+ return (is_float ? MOVN_S : MOVN) | TA(EQUAL_FLAG);
3690
+ case SLJIT_LESS:
3691
+ case SLJIT_GREATER:
3692
+ case SLJIT_SIG_LESS:
3693
+ case SLJIT_SIG_GREATER:
3694
+ case SLJIT_OVERFLOW:
3695
+ case SLJIT_CARRY:
3696
+ return (is_float ? MOVN_S : MOVN) | TA(OTHER_FLAG);
3697
+ case SLJIT_GREATER_EQUAL:
3698
+ case SLJIT_LESS_EQUAL:
3699
+ case SLJIT_SIG_GREATER_EQUAL:
3700
+ case SLJIT_SIG_LESS_EQUAL:
3701
+ case SLJIT_NOT_OVERFLOW:
3702
+ case SLJIT_NOT_CARRY:
3703
+ return (is_float ? MOVZ_S : MOVZ) | TA(OTHER_FLAG);
3704
+ case SLJIT_F_EQUAL:
3705
+ case SLJIT_F_LESS:
3706
+ case SLJIT_F_LESS_EQUAL:
3707
+ case SLJIT_ORDERED_EQUAL:
3708
+ case SLJIT_UNORDERED_OR_EQUAL:
3709
+ case SLJIT_ORDERED_LESS:
3710
+ case SLJIT_UNORDERED_OR_LESS:
3711
+ case SLJIT_UNORDERED_OR_LESS_EQUAL:
3712
+ case SLJIT_ORDERED_LESS_EQUAL:
3713
+ case SLJIT_UNORDERED:
3714
+ return is_float ? MOVT_S : MOVT;
3715
+ case SLJIT_F_NOT_EQUAL:
3716
+ case SLJIT_F_GREATER_EQUAL:
3717
+ case SLJIT_F_GREATER:
3718
+ case SLJIT_UNORDERED_OR_NOT_EQUAL:
3719
+ case SLJIT_ORDERED_NOT_EQUAL:
3720
+ case SLJIT_UNORDERED_OR_GREATER_EQUAL:
3721
+ case SLJIT_ORDERED_GREATER_EQUAL:
3722
+ case SLJIT_ORDERED_GREATER:
3723
+ case SLJIT_UNORDERED_OR_GREATER:
3724
+ case SLJIT_ORDERED:
3725
+ return is_float ? MOVF_S : MOVF;
3726
+ default:
3727
+ SLJIT_UNREACHABLE();
3728
+ return (is_float ? MOVZ_S : MOVZ) | TA(OTHER_FLAG);
3729
+ }
3730
+ }
3731
+
3732
+ #endif /* SLJIT_MIPS_REV >= 1 */
3733
+
3734
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type,
3735
+ sljit_s32 dst_reg,
3736
+ sljit_s32 src1, sljit_sw src1w,
3737
+ sljit_s32 src2_reg)
3738
+ {
3739
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
3740
+ sljit_s32 inp_flags = ((type & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;
3741
+ sljit_ins mov_ins = (type & SLJIT_32) ? ADDU : DADDU;
3742
+ #else /* !SLJIT_CONFIG_MIPS_64 */
3743
+ sljit_s32 inp_flags = WORD_DATA | LOAD_DATA;
3744
+ sljit_ins mov_ins = ADDU;
3745
+ #endif /* SLJIT_CONFIG_MIPS_64 */
3746
+
3747
+ #if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
3748
+ struct sljit_label *label;
3749
+ struct sljit_jump *jump;
3750
+ #endif /* !(SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) */
3751
+
3752
+ CHECK_ERROR();
3753
+ CHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg));
3754
+ ADJUST_LOCAL_OFFSET(src1, src1w);
3755
+
3756
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
3757
+ if (src1 & SLJIT_MEM) {
3758
+ FAIL_IF(emit_op_mem(compiler, inp_flags, DR(TMP_REG1), src1, src1w));
3759
+ src1 = TMP_REG1;
3760
+ } else if (src1 == SLJIT_IMM) {
3761
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
3762
+ if (type & SLJIT_32)
3763
+ src1w = (sljit_s32)src1w;
3764
+ #endif
3765
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w));
3766
+ src1 = TMP_REG1;
3767
+ }
3768
+
3769
+ if (dst_reg != src2_reg) {
3770
+ if (dst_reg == src1) {
3771
+ src1 = src2_reg;
3772
+ type ^= 0x1;
3773
+ } else
3774
+ FAIL_IF(push_inst(compiler, mov_ins | S(src2_reg) | TA(0) | D(dst_reg), DR(dst_reg)));
3775
+ }
3776
+
3777
+ return push_inst(compiler, get_select_cc(type, 0) | S(src1) | D(dst_reg), DR(dst_reg));
3778
+
3779
+ #else /* SLJIT_MIPS_REV < 1 || SLJIT_MIPS_REV >= 6 */
3780
+ if (dst_reg != src2_reg) {
3781
+ if (dst_reg == src1) {
3782
+ src1 = src2_reg;
3783
+ src1w = 0;
3784
+ type ^= 0x1;
3785
+ } else {
3786
+ if (ADDRESSING_DEPENDS_ON(src1, dst_reg)) {
3787
+ FAIL_IF(push_inst(compiler, ADDU_W | S(dst_reg) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
3788
+
3789
+ if ((src1 & REG_MASK) == dst_reg)
3790
+ src1 = (src1 & ~REG_MASK) | TMP_REG1;
3791
+
3792
+ if (OFFS_REG(src1) == dst_reg)
3793
+ src1 = (src1 & ~OFFS_REG_MASK) | TO_OFFS_REG(TMP_REG1);
3794
+ }
3795
+
3796
+ FAIL_IF(push_inst(compiler, mov_ins | S(src2_reg) | TA(0) | D(dst_reg), DR(dst_reg)));
3797
+ }
3798
+ }
3799
+
3800
+ SLJIT_SKIP_CHECKS(compiler);
3801
+ jump = sljit_emit_jump(compiler, (type & ~SLJIT_32) ^ 0x1);
3802
+ FAIL_IF(!jump);
3803
+
3804
+ if (src1 & SLJIT_MEM) {
3805
+ FAIL_IF(emit_op_mem(compiler, inp_flags, DR(dst_reg), src1, src1w));
3806
+ } else if (src1 == SLJIT_IMM) {
3807
+ #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
3808
+ if (type & SLJIT_32)
3809
+ src1w = (sljit_s32)src1w;
3810
+ #endif /* SLJIT_CONFIG_MIPS_64 */
3811
+ FAIL_IF(load_immediate(compiler, DR(dst_reg), src1w));
3812
+ } else
3813
+ FAIL_IF(push_inst(compiler, mov_ins | S(src1) | TA(0) | D(dst_reg), DR(dst_reg)));
3814
+
3815
+ SLJIT_SKIP_CHECKS(compiler);
3816
+ label = sljit_emit_label(compiler);
3817
+ FAIL_IF(!label);
3818
+
3819
+ sljit_set_label(jump, label);
3820
+ return SLJIT_SUCCESS;
3821
+ #endif /* SLJIT_MIPS_REV >= 1 */
3822
+ }
3823
+
3824
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type,
3825
+ sljit_s32 dst_freg,
3826
+ sljit_s32 src1, sljit_sw src1w,
3827
+ sljit_s32 src2_freg)
3828
+ {
3829
+ #if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
3830
+ struct sljit_label *label;
3831
+ struct sljit_jump *jump;
3832
+ #endif /* !(SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) */
3833
+
3834
+ CHECK_ERROR();
3835
+ CHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg));
3836
+
3837
+ ADJUST_LOCAL_OFFSET(src1, src1w);
3838
+
3839
+ if (dst_freg != src2_freg) {
3840
+ if (dst_freg == src1) {
3841
+ src1 = src2_freg;
3842
+ src1w = 0;
3843
+ type ^= 0x1;
3844
+ } else
3845
+ FAIL_IF(push_inst(compiler, MOV_fmt(FMT(type)) | FS(src2_freg) | FD(dst_freg), MOVABLE_INS));
3846
+ }
3847
+
3848
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
3849
+ if (src1 & SLJIT_MEM) {
3850
+ FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(type) | LOAD_DATA, FR(TMP_FREG2), src1, src1w));
3851
+ src1 = TMP_FREG2;
3852
+ }
3853
+
3854
+ return push_inst(compiler, get_select_cc(type, 1) | FMT(type) | FS(src1) | FD(dst_freg), MOVABLE_INS);
3855
+
3856
+ #else /* SLJIT_MIPS_REV < 1 || SLJIT_MIPS_REV >= 6 */
3857
+ SLJIT_SKIP_CHECKS(compiler);
3858
+ jump = sljit_emit_jump(compiler, (type & ~SLJIT_32) ^ 0x1);
3859
+ FAIL_IF(!jump);
3860
+
3861
+ if (src1 & SLJIT_MEM)
3862
+ FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(type) | LOAD_DATA, FR(dst_freg), src1, src1w));
3863
+ else
3864
+ FAIL_IF(push_inst(compiler, MOV_fmt(FMT(type)) | FS(src1) | FD(dst_freg), MOVABLE_INS));
3865
+
3866
+ SLJIT_SKIP_CHECKS(compiler);
3867
+ label = sljit_emit_label(compiler);
3868
+ FAIL_IF(!label);
3869
+
3870
+ sljit_set_label(jump, label);
3871
+ return SLJIT_SUCCESS;
3872
+ #endif /* SLJIT_MIPS_REV >= 1 */
3873
+ }
3874
+
3875
+ #undef FLOAT_DATA
3876
+ #undef FMT
3877
+
3878
+ static sljit_s32 update_mem_addr(struct sljit_compiler *compiler, sljit_s32 *mem, sljit_sw *memw, sljit_s16 max_offset)
3879
+ {
3880
+ sljit_s32 arg = *mem;
3881
+ sljit_sw argw = *memw;
3882
+
3883
+ if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
3884
+ argw &= 0x3;
3885
+
3886
+ if (SLJIT_UNLIKELY(argw)) {
3887
+ FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | D(TMP_REG1) | SH_IMM(argw), DR(TMP_REG1)));
3888
+ FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG1) | T(arg & REG_MASK) | D(TMP_REG1), DR(TMP_REG1)));
3889
+ } else
3890
+ FAIL_IF(push_inst(compiler, ADDU_W | S(arg & REG_MASK) | T(OFFS_REG(arg)) | D(TMP_REG1), DR(TMP_REG1)));
3891
+
3892
+ *mem = TMP_REG1;
3893
+ *memw = 0;
3894
+
3895
+ return SLJIT_SUCCESS;
3896
+ }
3897
+
3898
+ if (argw <= max_offset && argw >= SIMM_MIN) {
3899
+ *mem = arg & REG_MASK;
3900
+ return SLJIT_SUCCESS;
3901
+ }
3902
+
3903
+ *mem = TMP_REG1;
3904
+
3905
+ if ((sljit_s16)argw > max_offset) {
3906
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG1), argw));
3907
+ *memw = 0;
3908
+ } else {
3909
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG1), TO_ARGW_HI(argw)));
3910
+ *memw = (sljit_s16)argw;
3911
+ }
3912
+
3913
+ if ((arg & REG_MASK) == 0)
3914
+ return SLJIT_SUCCESS;
3915
+
3916
+ return push_inst(compiler, ADDU_W | S(TMP_REG1) | T(arg & REG_MASK) | D(TMP_REG1), DR(TMP_REG1));
3917
+ }
3918
+
3919
+ #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
3920
+ #define IMM_LEFT(memw) IMM((memw) + SSIZE_OF(sw) - 1)
3921
+ #define IMM_RIGHT(memw) IMM(memw)
3922
+ #define IMM_32_LEFT(memw) IMM((memw) + SSIZE_OF(s32) - 1)
3923
+ #define IMM_32_RIGHT(memw) IMM(memw)
3924
+ #define IMM_F64_FIRST_LEFT(memw) IMM((memw) + SSIZE_OF(s32) - 1)
3925
+ #define IMM_F64_FIRST_RIGHT(memw) IMM(memw)
3926
+ #define IMM_F64_SECOND_LEFT(memw) IMM((memw) + SSIZE_OF(f64) - 1)
3927
+ #define IMM_F64_SECOND_RIGHT(memw) IMM((memw) + SSIZE_OF(s32))
3928
+ #define IMM_16_FIRST(memw) IMM((memw) + 1)
3929
+ #define IMM_16_SECOND(memw) IMM(memw)
3930
+ #else /* !SLJIT_LITTLE_ENDIAN */
3931
+ #define IMM_LEFT(memw) IMM(memw)
3932
+ #define IMM_RIGHT(memw) IMM((memw) + SSIZE_OF(sw) - 1)
3933
+ #define IMM_32_LEFT(memw) IMM(memw)
3934
+ #define IMM_32_RIGHT(memw) IMM((memw) + SSIZE_OF(s32) - 1)
3935
+ #define IMM_F64_FIRST_LEFT(memw) IMM((memw) + SSIZE_OF(s32))
3936
+ #define IMM_F64_FIRST_RIGHT(memw) IMM((memw) + SSIZE_OF(f64) - 1)
3937
+ #define IMM_F64_SECOND_LEFT(memw) IMM(memw)
3938
+ #define IMM_F64_SECOND_RIGHT(memw) IMM((memw) + SSIZE_OF(s32) - 1)
3939
+ #define IMM_16_FIRST(memw) IMM(memw)
3940
+ #define IMM_16_SECOND(memw) IMM((memw) + 1)
3941
+ #endif /* SLJIT_LITTLE_ENDIAN */
3942
+
3943
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3944
+ #define MEM_CHECK_UNALIGNED(type) ((type) & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_ALIGNED_16))
3945
+ #else /* !SLJIT_CONFIG_MIPS_32 */
3946
+ #define MEM_CHECK_UNALIGNED(type) ((type) & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_ALIGNED_16 | SLJIT_MEM_ALIGNED_32))
3947
+ #endif /* SLJIT_CONFIG_MIPS_32 */
3948
+
3949
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
3950
+ sljit_s32 reg,
3951
+ sljit_s32 mem, sljit_sw memw)
3952
+ {
3953
+ sljit_s32 op = type & 0xff;
3954
+ sljit_s32 flags = 0;
3955
+ sljit_ins ins;
3956
+ #if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
3957
+ sljit_ins ins_right;
3958
+ #endif /* !(SLJIT_MIPS_REV >= 6) */
3959
+
3960
+ CHECK_ERROR();
3961
+ CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
3962
+
3963
+ if (reg & REG_PAIR_MASK) {
3964
+ ADJUST_LOCAL_OFFSET(mem, memw);
3965
+
3966
+ #if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
3967
+ if (MEM_CHECK_UNALIGNED(type)) {
3968
+ FAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - (2 * SSIZE_OF(sw) - 1)));
3969
+
3970
+ if (!(type & SLJIT_MEM_STORE) && (mem == REG_PAIR_FIRST(reg) || mem == REG_PAIR_SECOND(reg))) {
3971
+ FAIL_IF(push_inst(compiler, ADDU_W | S(mem) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
3972
+ mem = TMP_REG1;
3973
+ }
3974
+
3975
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
3976
+ ins = ((type & SLJIT_MEM_STORE) ? SWL : LWL) | S(mem);
3977
+ ins_right = ((type & SLJIT_MEM_STORE) ? SWR : LWR) | S(mem);
3978
+ #else /* !SLJIT_CONFIG_MIPS_32 */
3979
+ ins = ((type & SLJIT_MEM_STORE) ? SDL : LDL) | S(mem);
3980
+ ins_right = ((type & SLJIT_MEM_STORE) ? SDR : LDR) | S(mem);
3981
+ #endif /* SLJIT_CONFIG_MIPS_32 */
3982
+
3983
+ FAIL_IF(push_inst(compiler, ins | T(REG_PAIR_FIRST(reg)) | IMM_LEFT(memw), DR(REG_PAIR_FIRST(reg))));
3984
+ FAIL_IF(push_inst(compiler, ins_right | T(REG_PAIR_FIRST(reg)) | IMM_RIGHT(memw), DR(REG_PAIR_FIRST(reg))));
3985
+ FAIL_IF(push_inst(compiler, ins | T(REG_PAIR_SECOND(reg)) | IMM_LEFT(memw + SSIZE_OF(sw)), DR(REG_PAIR_SECOND(reg))));
3986
+ return push_inst(compiler, ins_right | T(REG_PAIR_SECOND(reg)) | IMM_RIGHT(memw + SSIZE_OF(sw)), DR(REG_PAIR_SECOND(reg)));
3987
+ }
3988
+ #endif /* !(SLJIT_MIPS_REV >= 6) */
3989
+
3990
+ FAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - SSIZE_OF(sw)));
3991
+
3992
+ ins = ((type & SLJIT_MEM_STORE) ? STORE_W : LOAD_W) | S(mem);
3993
+
3994
+ if (!(type & SLJIT_MEM_STORE) && mem == REG_PAIR_FIRST(reg)) {
3995
+ FAIL_IF(push_inst(compiler, ins | T(REG_PAIR_SECOND(reg)) | IMM(memw + SSIZE_OF(sw)), DR(REG_PAIR_SECOND(reg))));
3996
+ return push_inst(compiler, ins | T(REG_PAIR_FIRST(reg)) | IMM(memw), DR(REG_PAIR_FIRST(reg)));
3997
+ }
3998
+
3999
+ FAIL_IF(push_inst(compiler, ins | T(REG_PAIR_FIRST(reg)) | IMM(memw), DR(REG_PAIR_FIRST(reg))));
4000
+ return push_inst(compiler, ins | T(REG_PAIR_SECOND(reg)) | IMM(memw + SSIZE_OF(sw)), DR(REG_PAIR_SECOND(reg)));
4001
+ }
4002
+
4003
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
4004
+ return sljit_emit_mem_unaligned(compiler, type, reg, mem, memw);
4005
+ #else /* !(SLJIT_MIPS_REV >= 6) */
4006
+ ADJUST_LOCAL_OFFSET(mem, memw);
4007
+
4008
+ switch (op) {
4009
+ case SLJIT_MOV_U8:
4010
+ case SLJIT_MOV_S8:
4011
+ flags = BYTE_DATA;
4012
+ if (!(type & SLJIT_MEM_STORE))
4013
+ flags |= LOAD_DATA;
4014
+
4015
+ if (op == SLJIT_MOV_S8)
4016
+ flags |= SIGNED_DATA;
4017
+
4018
+ return emit_op_mem(compiler, flags, DR(reg), mem, memw);
4019
+
4020
+ case SLJIT_MOV_U16:
4021
+ case SLJIT_MOV_S16:
4022
+ FAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - 1));
4023
+ SLJIT_ASSERT(FAST_IS_REG(mem) && mem != TMP_REG2);
4024
+
4025
+ if (type & SLJIT_MEM_STORE) {
4026
+ FAIL_IF(push_inst(compiler, SRA_W | T(reg) | D(TMP_REG2) | SH_IMM(8), DR(TMP_REG2)));
4027
+ FAIL_IF(push_inst(compiler, data_transfer_insts[BYTE_DATA] | S(mem) | T(TMP_REG2) | IMM_16_FIRST(memw), MOVABLE_INS));
4028
+ return push_inst(compiler, data_transfer_insts[BYTE_DATA] | S(mem) | T(reg) | IMM_16_SECOND(memw), MOVABLE_INS);
4029
+ }
4030
+
4031
+ flags = BYTE_DATA | LOAD_DATA;
4032
+
4033
+ if (op == SLJIT_MOV_S16)
4034
+ flags |= SIGNED_DATA;
4035
+
4036
+ FAIL_IF(push_inst(compiler, data_transfer_insts[flags] | S(mem) | T(TMP_REG2) | IMM_16_FIRST(memw), DR(TMP_REG2)));
4037
+ FAIL_IF(push_inst(compiler, data_transfer_insts[BYTE_DATA | LOAD_DATA] | S(mem) | T(reg) | IMM_16_SECOND(memw), DR(reg)));
4038
+ FAIL_IF(push_inst(compiler, SLL_W | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(8), DR(TMP_REG2)));
4039
+ return push_inst(compiler, OR | S(reg) | T(TMP_REG2) | D(reg), DR(reg));
4040
+
4041
+ case SLJIT_MOV:
4042
+ case SLJIT_MOV_P:
4043
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
4044
+ if (type & SLJIT_MEM_ALIGNED_32) {
4045
+ flags = WORD_DATA;
4046
+ if (!(type & SLJIT_MEM_STORE))
4047
+ flags |= LOAD_DATA;
4048
+
4049
+ return emit_op_mem(compiler, flags, DR(reg), mem, memw);
4050
+ }
4051
+ #else /* !SLJIT_CONFIG_MIPS_32 */
4052
+ FAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - 7));
4053
+ SLJIT_ASSERT(FAST_IS_REG(mem) && mem != TMP_REG2);
4054
+
4055
+ if (type & SLJIT_MEM_STORE) {
4056
+ FAIL_IF(push_inst(compiler, SDL | S(mem) | T(reg) | IMM_LEFT(memw), MOVABLE_INS));
4057
+ return push_inst(compiler, SDR | S(mem) | T(reg) | IMM_RIGHT(memw), MOVABLE_INS);
4058
+ }
4059
+
4060
+ if (mem == reg) {
4061
+ FAIL_IF(push_inst(compiler, ADDU_W | S(mem) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
4062
+ mem = TMP_REG1;
4063
+ }
4064
+
4065
+ FAIL_IF(push_inst(compiler, LDL | S(mem) | T(reg) | IMM_LEFT(memw), DR(reg)));
4066
+ return push_inst(compiler, LDR | S(mem) | T(reg) | IMM_RIGHT(memw), DR(reg));
4067
+ #endif /* SLJIT_CONFIG_MIPS_32 */
4068
+ }
4069
+
4070
+ FAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - 3));
4071
+ SLJIT_ASSERT(FAST_IS_REG(mem) && mem != TMP_REG2);
4072
+
4073
+ if (type & SLJIT_MEM_STORE) {
4074
+ FAIL_IF(push_inst(compiler, SWL | S(mem) | T(reg) | IMM_32_LEFT(memw), MOVABLE_INS));
4075
+ return push_inst(compiler, SWR | S(mem) | T(reg) | IMM_32_RIGHT(memw), MOVABLE_INS);
4076
+ }
4077
+
4078
+ if (mem == reg) {
4079
+ FAIL_IF(push_inst(compiler, ADDU_W | S(mem) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
4080
+ mem = TMP_REG1;
4081
+ }
4082
+
4083
+ FAIL_IF(push_inst(compiler, LWL | S(mem) | T(reg) | IMM_32_LEFT(memw), DR(reg)));
4084
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
4085
+ return push_inst(compiler, LWR | S(mem) | T(reg) | IMM_32_RIGHT(memw), DR(reg));
4086
+ #else /* !SLJIT_CONFIG_MIPS_32 */
4087
+ FAIL_IF(push_inst(compiler, LWR | S(mem) | T(reg) | IMM_32_RIGHT(memw), DR(reg)));
4088
+
4089
+ if (op != SLJIT_MOV_U32)
4090
+ return SLJIT_SUCCESS;
4091
+
4092
+ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2)
4093
+ return push_inst(compiler, DINSU | T(reg) | SA(0) | (31 << 11), DR(reg));
4094
+ #else /* SLJIT_MIPS_REV < 2 */
4095
+ FAIL_IF(push_inst(compiler, DSLL32 | T(reg) | D(reg) | SH_IMM(0), DR(reg)));
4096
+ return push_inst(compiler, DSRL32 | T(reg) | D(reg) | SH_IMM(0), DR(reg));
4097
+ #endif /* SLJIT_MIPS_REV >= 2 */
4098
+ #endif /* SLJIT_CONFIG_MIPS_32 */
4099
+ #endif /* SLJIT_MIPS_REV >= 6 */
4100
+ }
4101
+
4102
+ #if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
4103
+
4104
+ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
4105
+ sljit_s32 freg,
4106
+ sljit_s32 mem, sljit_sw memw)
4107
+ {
4108
+ CHECK_ERROR();
4109
+ CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));
4110
+
4111
+ FAIL_IF(update_mem_addr(compiler, &mem, &memw, SIMM_MAX - (type & SLJIT_32) ? 3 : 7));
4112
+ SLJIT_ASSERT(FAST_IS_REG(mem) && mem != TMP_REG2);
4113
+
4114
+ if (type & SLJIT_MEM_STORE) {
4115
+ if (type & SLJIT_32) {
4116
+ FAIL_IF(push_inst(compiler, MFC1 | T(TMP_REG2) | FS(freg), DR(TMP_REG2)));
4117
+ #if !defined(SLJIT_MIPS_REV) || (SLJIT_CONFIG_MIPS_32 && SLJIT_MIPS_REV <= 1)
4118
+ FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
4119
+ #endif /* MIPS III */
4120
+ FAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM_32_LEFT(memw), MOVABLE_INS));
4121
+ return push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM_32_RIGHT(memw), MOVABLE_INS);
4122
+ }
4123
+
4124
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
4125
+ FAIL_IF(push_inst(compiler, MFC1 | T(TMP_REG2) | FS(freg), DR(TMP_REG2)));
4126
+ #if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1
4127
+ FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
4128
+ #endif /* MIPS III */
4129
+ FAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM_F64_FIRST_LEFT(memw), MOVABLE_INS));
4130
+ FAIL_IF(push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM_F64_FIRST_RIGHT(memw), MOVABLE_INS));
4131
+ switch (cpu_feature_list & CPU_FEATURE_FR) {
4132
+ #if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
4133
+ case CPU_FEATURE_FR:
4134
+ FAIL_IF(push_inst(compiler, MFHC1 | T(TMP_REG2) | FS(freg), DR(TMP_REG2)));
4135
+ break;
4136
+ #endif /* SLJIT_MIPS_REV >= 2 */
4137
+ default:
4138
+ FAIL_IF(push_inst(compiler, MFC1 | T(TMP_REG2) | FS(freg) | (1 << 11), DR(TMP_REG2)));
4139
+ #if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1
4140
+ FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
4141
+ #endif
4142
+ break;
4143
+ }
4144
+
4145
+ FAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM_F64_SECOND_LEFT(memw), MOVABLE_INS));
4146
+ return push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM_F64_SECOND_RIGHT(memw), MOVABLE_INS);
4147
+ #else /* !SLJIT_CONFIG_MIPS_32 */
4148
+ FAIL_IF(push_inst(compiler, DMFC1 | T(TMP_REG2) | FS(freg), DR(TMP_REG2)));
4149
+ #if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1
4150
+ FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
4151
+ #endif /* MIPS III */
4152
+ FAIL_IF(push_inst(compiler, SDL | S(mem) | T(TMP_REG2) | IMM_LEFT(memw), MOVABLE_INS));
4153
+ return push_inst(compiler, SDR | S(mem) | T(TMP_REG2) | IMM_RIGHT(memw), MOVABLE_INS);
4154
+ #endif /* SLJIT_CONFIG_MIPS_32 */
4155
+ }
4156
+
4157
+ if (type & SLJIT_32) {
4158
+ FAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM_32_LEFT(memw), DR(TMP_REG2)));
4159
+ FAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM_32_RIGHT(memw), DR(TMP_REG2)));
4160
+
4161
+ FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | FS(freg), MOVABLE_INS));
4162
+ #if !defined(SLJIT_MIPS_REV) || (SLJIT_CONFIG_MIPS_32 && SLJIT_MIPS_REV <= 1)
4163
+ FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
4164
+ #endif /* MIPS III */
4165
+ return SLJIT_SUCCESS;
4166
+ }
4167
+
4168
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
4169
+ FAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM_F64_FIRST_LEFT(memw), DR(TMP_REG2)));
4170
+ FAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM_F64_FIRST_RIGHT(memw), DR(TMP_REG2)));
4171
+ FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | FS(freg), MOVABLE_INS));
4172
+
4173
+ FAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM_F64_SECOND_LEFT(memw), DR(TMP_REG2)));
4174
+ FAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM_F64_SECOND_RIGHT(memw), DR(TMP_REG2)));
4175
+ switch (cpu_feature_list & CPU_FEATURE_FR) {
4176
+ #if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
4177
+ case CPU_FEATURE_FR:
4178
+ return push_inst(compiler, MTHC1 | T(TMP_REG2) | FS(freg), MOVABLE_INS);
4179
+ #endif /* SLJIT_MIPS_REV >= 2 */
4180
+ default:
4181
+ FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | FS(freg) | (1 << 11), MOVABLE_INS));
4182
+ break;
4183
+ }
4184
+ #else /* !SLJIT_CONFIG_MIPS_32 */
4185
+ FAIL_IF(push_inst(compiler, LDL | S(mem) | T(TMP_REG2) | IMM_LEFT(memw), DR(TMP_REG2)));
4186
+ FAIL_IF(push_inst(compiler, LDR | S(mem) | T(TMP_REG2) | IMM_RIGHT(memw), DR(TMP_REG2)));
4187
+
4188
+ FAIL_IF(push_inst(compiler, DMTC1 | T(TMP_REG2) | FS(freg), MOVABLE_INS));
4189
+ #endif /* SLJIT_CONFIG_MIPS_32 */
4190
+ #if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1
4191
+ FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
4192
+ #endif /* MIPS III */
4193
+ return SLJIT_SUCCESS;
4194
+ }
4195
+
4196
+ #endif /* !SLJIT_MIPS_REV || SLJIT_MIPS_REV < 6 */
4197
+
4198
+ #undef IMM_16_SECOND
4199
+ #undef IMM_16_FIRST
4200
+ #undef IMM_F64_SECOND_RIGHT
4201
+ #undef IMM_F64_SECOND_LEFT
4202
+ #undef IMM_F64_FIRST_RIGHT
4203
+ #undef IMM_F64_FIRST_LEFT
4204
+ #undef IMM_32_RIGHT
4205
+ #undef IMM_32_LEFT
4206
+ #undef IMM_RIGHT
4207
+ #undef IMM_LEFT
4208
+ #undef MEM_CHECK_UNALIGNED
4209
+
4210
+ #undef TO_ARGW_HI
4211
+
4212
+ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
4213
+ {
4214
+ struct sljit_const *const_;
4215
+ sljit_s32 dst_r;
4216
+
4217
+ CHECK_ERROR_PTR();
4218
+ CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
4219
+ ADJUST_LOCAL_OFFSET(dst, dstw);
4220
+
4221
+ const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
4222
+ PTR_FAIL_IF(!const_);
4223
+ set_const(const_, compiler);
4224
+
4225
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
4226
+ PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));
4227
+
4228
+ if (dst & SLJIT_MEM)
4229
+ PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, DR(TMP_REG2), dst, dstw));
4230
+
4231
+ return const_;
4232
+ }
4233
+
4234
+ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
4235
+ {
4236
+ struct sljit_jump *jump;
4237
+ sljit_s32 dst_r;
4238
+
4239
+ CHECK_ERROR_PTR();
4240
+ CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw));
4241
+ ADJUST_LOCAL_OFFSET(dst, dstw);
4242
+
4243
+ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
4244
+ PTR_FAIL_IF(!jump);
4245
+ set_mov_addr(jump, compiler, 0);
4246
+
4247
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
4248
+ PTR_FAIL_IF(push_inst(compiler, (sljit_ins)dst_r, UNMOVABLE_INS));
4249
+ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
4250
+ compiler->size += 1;
4251
+ #else
4252
+ compiler->size += 5;
4253
+ #endif
4254
+
4255
+ if (dst & SLJIT_MEM)
4256
+ PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, DR(TMP_REG2), dst, dstw));
4257
+
4258
+ return jump;
4259
+ }