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.
- tpy_lang-0.3.0.dev0.dist-info/METADATA +151 -0
- tpy_lang-0.3.0.dev0.dist-info/RECORD +333 -0
- tpy_lang-0.3.0.dev0.dist-info/WHEEL +4 -0
- tpy_lang-0.3.0.dev0.dist-info/entry_points.txt +3 -0
- tpyc/__init__.py +104 -0
- tpyc/__main__.py +6 -0
- tpyc/_buildinfo.py +1 -0
- tpyc/_data/docs/LANGUAGE_FEATURES.md +6278 -0
- tpyc/_data/docs/STDLIB_ROADMAP.md +1258 -0
- tpyc/_data/docs/TPY_FOR_AGENTS.md +556 -0
- tpyc/_data/lib/tpy/_bindings/__init__.py +6 -0
- tpyc/_data/lib/tpy/_bindings/pcre2.py +173 -0
- tpyc/_data/lib/tpy/_bindings/posix_socket.py +161 -0
- tpyc/_data/lib/tpy/_functools_macros.py +80 -0
- tpyc/_data/lib/tpy/_macro_helpers.py +161 -0
- tpyc/_data/lib/tpy/argparse.py +2062 -0
- tpyc/_data/lib/tpy/asyncio/__init__.py +744 -0
- tpyc/_data/lib/tpy/asyncio/_executor.py +515 -0
- tpyc/_data/lib/tpy/base64.py +410 -0
- tpyc/_data/lib/tpy/bisect.py +39 -0
- tpyc/_data/lib/tpy/builtins.py +38 -0
- tpyc/_data/lib/tpy/dataclasses.py +354 -0
- tpyc/_data/lib/tpy/enum.py +23 -0
- tpyc/_data/lib/tpy/functools.py +33 -0
- tpyc/_data/lib/tpy/hashlib.py +206 -0
- tpyc/_data/lib/tpy/heapq.py +118 -0
- tpyc/_data/lib/tpy/io.py +395 -0
- tpyc/_data/lib/tpy/json.py +221 -0
- tpyc/_data/lib/tpy/math.py +406 -0
- tpyc/_data/lib/tpy/random.py +597 -0
- tpyc/_data/lib/tpy/re.py +467 -0
- tpyc/_data/lib/tpy/socket.py +379 -0
- tpyc/_data/lib/tpy/struct.py +178 -0
- tpyc/_data/lib/tpy/sys.py +40 -0
- tpyc/_data/lib/tpy/time.py +39 -0
- tpyc/_data/lib/tpy/tpy/__init__.py +78 -0
- tpyc/_data/lib/tpy/tpy/_bootstrap/__init__.py +10 -0
- tpyc/_data/lib/tpy/tpy/_bootstrap/_decorators.py +37 -0
- tpyc/_data/lib/tpy/tpy/_bootstrap/_extern.py +64 -0
- tpyc/_data/lib/tpy/tpy/_builtins/__init__.py +11 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_bytes.py +378 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_dict.py +151 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_exceptions.py +125 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_funcs.py +681 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_io.py +97 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_list.py +127 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_range.py +52 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_set.py +139 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_super.py +11 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_types.py +661 -0
- tpyc/_data/lib/tpy/tpy/_core/__init__.py +23 -0
- tpyc/_data/lib/tpy/tpy/_core/_bytes_view.py +129 -0
- tpyc/_data/lib/tpy/tpy/_core/_containers.py +137 -0
- tpyc/_data/lib/tpy/tpy/_core/_functions.py +40 -0
- tpyc/_data/lib/tpy/tpy/_core/_types.py +2061 -0
- tpyc/_data/lib/tpy/tpy/_typing/__init__.py +77 -0
- tpyc/_data/lib/tpy/tpy/_version.py +29 -0
- tpyc/_data/lib/tpy/tpy/bits.py +28 -0
- tpyc/_data/lib/tpy/tpy/coro/__init__.py +127 -0
- tpyc/_data/lib/tpy/tpy/extern.py +8 -0
- tpyc/_data/lib/tpy/tpy/mem.py +49 -0
- tpyc/_data/lib/tpy/tpy/unsafe.py +195 -0
- tpyc/_data/lib/tpy/tpy/version.py +21 -0
- tpyc/_data/lib/tpy/typing.py +13 -0
- tpyc/_data/runtime/cpp/include/tpy/any.hpp +461 -0
- tpyc/_data/runtime/cpp/include/tpy/as_ostream.hpp +117 -0
- tpyc/_data/runtime/cpp/include/tpy/async.hpp +76 -0
- tpyc/_data/runtime/cpp/include/tpy/bigint.hpp +1343 -0
- tpyc/_data/runtime/cpp/include/tpy/builtins.hpp +400 -0
- tpyc/_data/runtime/cpp/include/tpy/bytes_ops.hpp +469 -0
- tpyc/_data/runtime/cpp/include/tpy/container_ops.hpp +487 -0
- tpyc/_data/runtime/cpp/include/tpy/copy_iter.hpp +82 -0
- tpyc/_data/runtime/cpp/include/tpy/core.hpp +558 -0
- tpyc/_data/runtime/cpp/include/tpy/dict_ops.hpp +289 -0
- tpyc/_data/runtime/cpp/include/tpy/dunder.hpp +750 -0
- tpyc/_data/runtime/cpp/include/tpy/dynamic.hpp +44 -0
- tpyc/_data/runtime/cpp/include/tpy/enum.hpp +40 -0
- tpyc/_data/runtime/cpp/include/tpy/file.hpp +245 -0
- tpyc/_data/runtime/cpp/include/tpy/fixed_int.hpp +317 -0
- tpyc/_data/runtime/cpp/include/tpy/format.hpp +954 -0
- tpyc/_data/runtime/cpp/include/tpy/frame_slot.hpp +120 -0
- tpyc/_data/runtime/cpp/include/tpy/generator.hpp +47 -0
- tpyc/_data/runtime/cpp/include/tpy/iterable_ops.hpp +122 -0
- tpyc/_data/runtime/cpp/include/tpy/itertools.hpp +749 -0
- tpyc/_data/runtime/cpp/include/tpy/next_iter.hpp +82 -0
- tpyc/_data/runtime/cpp/include/tpy/ordered_map.hpp +518 -0
- tpyc/_data/runtime/cpp/include/tpy/ordered_set.hpp +337 -0
- tpyc/_data/runtime/cpp/include/tpy/own_iter.hpp +54 -0
- tpyc/_data/runtime/cpp/include/tpy/pascal_graph_sdl.hpp +192 -0
- tpyc/_data/runtime/cpp/include/tpy/printing.hpp +302 -0
- tpyc/_data/runtime/cpp/include/tpy/protocols.hpp +61 -0
- tpyc/_data/runtime/cpp/include/tpy/range.hpp +115 -0
- tpyc/_data/runtime/cpp/include/tpy/ranges.hpp +212 -0
- tpyc/_data/runtime/cpp/include/tpy/set_ops.hpp +265 -0
- tpyc/_data/runtime/cpp/include/tpy/slice.hpp +47 -0
- tpyc/_data/runtime/cpp/include/tpy/span_iter.hpp +42 -0
- tpyc/_data/runtime/cpp/include/tpy/stdlib/math.hpp +41 -0
- tpyc/_data/runtime/cpp/include/tpy/stdlib/pcre2_h.hpp +96 -0
- tpyc/_data/runtime/cpp/include/tpy/stdlib/random.hpp +25 -0
- tpyc/_data/runtime/cpp/include/tpy/stdlib/socket_h.hpp +145 -0
- tpyc/_data/runtime/cpp/include/tpy/stdlib/time.hpp +62 -0
- tpyc/_data/runtime/cpp/include/tpy/system.hpp +121 -0
- tpyc/_data/runtime/cpp/include/tpy/throwable.hpp +55 -0
- tpyc/_data/runtime/cpp/include/tpy/tpy.hpp +156 -0
- tpyc/_data/runtime/cpp/include/tpy/type_name.hpp +77 -0
- tpyc/_data/runtime/cpp/include/tpy/type_traits.hpp +240 -0
- tpyc/_data/runtime/cpp/include/tpy/uninit_array_storage.hpp +250 -0
- tpyc/_data/runtime/cpp/include/tpy/uninit_heap_storage.hpp +277 -0
- tpyc/_data/runtime/cpp/include/tpy/varargs.hpp +174 -0
- tpyc/_data/runtime/cpp/include/tpy/variant_ref.hpp +118 -0
- tpyc/_data/runtime/cpp/src/stdlib/socket_impl.cpp +104 -0
- tpyc/_data/runtime/cpp/third_party/README.md +58 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/AUTHORS +36 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/CMakeLists.txt +1233 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/COPYING +5 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/ChangeLog +3097 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/HACKING +853 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/INSTALL +368 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/LICENCE +94 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/NEWS +492 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/NON-AUTOTOOLS-BUILD +430 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/README +956 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/cmake/COPYING-CMAKE-SCRIPTS +22 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/cmake/FindEditline.cmake +16 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/cmake/FindPackageHandleStandardArgs.cmake +58 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/cmake/FindReadline.cmake +29 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/cmake/pcre2-config-version.cmake.in +15 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/cmake/pcre2-config.cmake.in +148 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/config-cmake.h.in +56 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-16.pc.in +13 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-32.pc.in +13 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-8.pc.in +13 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-posix.pc.in +13 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/pcre2-config.in +121 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/config.h +483 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/config.h.generic +483 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/config.h.in +460 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2.h +1010 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2.h.generic +1010 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2.h.in +1010 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_auto_possess.c +1371 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_chartables.c +196 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_chartables.c.dist +196 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_chkdint.c +96 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_compile.c +11001 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_config.c +252 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_context.c +510 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_convert.c +1189 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_dfa_match.c +4119 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_dftables.c +297 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_error.c +345 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_extuni.c +162 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_find_bracket.c +219 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_fuzzsupport.c +792 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_internal.h +2084 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_intmodedep.h +940 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_compile.c +14972 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_match.c +200 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_misc.c +234 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_neon_inc.h +354 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_simd_inc.h +2355 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_test.c +2528 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_maketables.c +165 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_match.c +7777 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_match_data.c +185 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_newline.c +243 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ord2utf.c +120 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_pattern_info.c +432 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_printint.c +886 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_script_run.c +344 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_serialize.c +286 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_string_utils.c +237 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_study.c +1915 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_substitute.c +1009 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_substring.c +550 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_tables.c +234 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ucd.c +5460 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ucp.h +396 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ucptables.c +1533 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_valid_utf.c +398 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_xclass.c +308 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2demo.c +497 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2grep.c +4606 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2posix.c +425 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2posix.h +187 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2posix_test.c +209 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2test.c +9708 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorApple.c +137 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorCore.c +327 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorFreeBSD.c +89 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorPosix.c +62 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorWindows.c +40 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorNetBSD.c +72 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorPosix.c +172 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorPosix.c +141 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorWindows.c +102 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitConfig.h +142 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitConfigCPU.h +188 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitConfigInternal.h +907 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitLir.c +3561 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitLir.h +2466 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeARM_32.c +4636 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeARM_64.c +3491 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeARM_T2_32.c +4302 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeLOONGARCH_64.c +3765 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeMIPS_32.c +472 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeMIPS_64.c +387 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeMIPS_common.c +4259 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativePPC_32.c +485 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativePPC_64.c +719 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativePPC_common.c +3161 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeRISCV_32.c +142 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeRISCV_64.c +222 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeRISCV_common.c +3121 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeS390X.c +4526 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeX86_32.c +1685 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeX86_64.c +1398 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeX86_common.c +5001 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitSerialize.c +516 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitUtils.c +344 -0
- tpyc/_data/runtime/cpp/third_party/pcre2.sources.txt +54 -0
- tpyc/_data/runtime/cpp/third_party/pcre2.vendor.json +7 -0
- tpyc/build/__init__.py +7 -0
- tpyc/build/pcre2.py +122 -0
- tpyc/build/third_party.py +413 -0
- tpyc/cli.py +822 -0
- tpyc/codegen_cpp/__init__.py +18 -0
- tpyc/codegen_cpp/builtins.py +484 -0
- tpyc/codegen_cpp/context.py +2064 -0
- tpyc/codegen_cpp/expressions.py +5940 -0
- tpyc/codegen_cpp/functions.py +1913 -0
- tpyc/codegen_cpp/gen_async.py +3258 -0
- tpyc/codegen_cpp/gen_generators.py +657 -0
- tpyc/codegen_cpp/generator.py +2258 -0
- tpyc/codegen_cpp/match.py +1997 -0
- tpyc/codegen_cpp/param_const.py +172 -0
- tpyc/codegen_cpp/protocols.py +907 -0
- tpyc/codegen_cpp/records.py +1654 -0
- tpyc/codegen_cpp/resumable_cfg.py +1651 -0
- tpyc/codegen_cpp/statements.py +4963 -0
- tpyc/codegen_cpp/string_dispatch.py +76 -0
- tpyc/codegen_cpp/test_context.py +46 -0
- tpyc/codegen_cpp/test_param_const.py +113 -0
- tpyc/codegen_cpp/test_resumable_cfg.py +182 -0
- tpyc/codegen_cpp/type_resolution.py +53 -0
- tpyc/codegen_cpp/types.py +436 -0
- tpyc/codegen_cpp/variant_access.py +135 -0
- tpyc/coercions.py +749 -0
- tpyc/compilation_context.py +57 -0
- tpyc/compiler.py +3945 -0
- tpyc/cycle_detection.py +358 -0
- tpyc/diagnostics.py +135 -0
- tpyc/dump_types.py +353 -0
- tpyc/frontend_diagnostics.py +47 -0
- tpyc/frontend_ir/__init__.py +140 -0
- tpyc/frontend_ir/lower.py +1098 -0
- tpyc/frontend_ir/nodes.py +718 -0
- tpyc/frontend_ir/resolver_adapter.py +151 -0
- tpyc/frontend_plugin.py +209 -0
- tpyc/install_docs.py +81 -0
- tpyc/liveness.py +756 -0
- tpyc/macro_api.py +1724 -0
- tpyc/macro_loader.py +497 -0
- tpyc/module_names.py +64 -0
- tpyc/modules/__init__.py +31 -0
- tpyc/modules/defs.py +89 -0
- tpyc/modules/registry.py +36 -0
- tpyc/modules/resolver.py +192 -0
- tpyc/modules/type_resolution.py +629 -0
- tpyc/namespace.py +172 -0
- tpyc/parse/__init__.py +84 -0
- tpyc/parse/imports.py +490 -0
- tpyc/parse/nodes.py +1732 -0
- tpyc/parse/parser.py +4043 -0
- tpyc/parse/resolve_refs.py +466 -0
- tpyc/parse/type_resolver.py +1060 -0
- tpyc/prescan.py +254 -0
- tpyc/qnames.py +149 -0
- tpyc/repl.py +529 -0
- tpyc/repl_backends.py +848 -0
- tpyc/sema/__init__.py +21 -0
- tpyc/sema/analyzer.py +3625 -0
- tpyc/sema/bound_check.py +72 -0
- tpyc/sema/builder_trace.py +684 -0
- tpyc/sema/calls.py +5406 -0
- tpyc/sema/compatibility.py +2107 -0
- tpyc/sema/context.py +1243 -0
- tpyc/sema/expressions.py +3737 -0
- tpyc/sema/flow_facts.py +199 -0
- tpyc/sema/init_tracker.py +150 -0
- tpyc/sema/list_literals.py +69 -0
- tpyc/sema/literal_utils.py +27 -0
- tpyc/sema/local_deduction.py +1088 -0
- tpyc/sema/macros.py +179 -0
- tpyc/sema/match.py +1177 -0
- tpyc/sema/method_expansion.py +347 -0
- tpyc/sema/methods.py +2197 -0
- tpyc/sema/mutation_propagation.py +268 -0
- tpyc/sema/narrowing.py +857 -0
- tpyc/sema/numeric_lattice.py +160 -0
- tpyc/sema/operators.py +402 -0
- tpyc/sema/overloads.py +841 -0
- tpyc/sema/protocols.py +1209 -0
- tpyc/sema/reach_analysis.py +202 -0
- tpyc/sema/registration.py +3156 -0
- tpyc/sema/scope_tracker.py +193 -0
- tpyc/sema/statements.py +4426 -0
- tpyc/sema/type_ops.py +1879 -0
- tpyc/sema/value_range.py +181 -0
- tpyc/symbol_binding.py +259 -0
- tpyc/test_c3_mro.py +208 -0
- tpyc/test_cli_argv.py +52 -0
- tpyc/test_compiler.py +559 -0
- tpyc/test_contains_type_param.py +101 -0
- tpyc/test_cycle_detection.py +221 -0
- tpyc/test_dump_types.py +225 -0
- tpyc/test_install_docs.py +65 -0
- tpyc/test_local_cpp_form.py +135 -0
- tpyc/test_macro_loader.py +76 -0
- tpyc/test_method_expansion.py +254 -0
- tpyc/test_nominal_identity.py +182 -0
- tpyc/test_overloads.py +410 -0
- tpyc/test_parse.py +303 -0
- tpyc/test_parse_type_ref.py +506 -0
- tpyc/test_parse_version_info.py +58 -0
- tpyc/test_reach_analysis.py +72 -0
- tpyc/test_ref_type.py +216 -0
- tpyc/test_send_sync_substitution.py +276 -0
- tpyc/test_tuple_mutation_propagation.py +206 -0
- tpyc/test_type_def_registry.py +1729 -0
- tpyc/test_union_types.py +195 -0
- tpyc/type_def_registry.py +975 -0
- tpyc/typesys.py +5104 -0
|
@@ -0,0 +1,3561 @@
|
|
|
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
|
+
#include "sljitLir.h"
|
|
28
|
+
|
|
29
|
+
#ifdef _WIN32
|
|
30
|
+
|
|
31
|
+
#include <windows.h>
|
|
32
|
+
|
|
33
|
+
#endif /* _WIN32 */
|
|
34
|
+
|
|
35
|
+
#if !(defined SLJIT_STD_MACROS_DEFINED && SLJIT_STD_MACROS_DEFINED)
|
|
36
|
+
|
|
37
|
+
/* These libraries are needed for the macros below. */
|
|
38
|
+
#include <stdlib.h>
|
|
39
|
+
#include <string.h>
|
|
40
|
+
|
|
41
|
+
#endif /* SLJIT_STD_MACROS_DEFINED */
|
|
42
|
+
|
|
43
|
+
#define CHECK_ERROR() \
|
|
44
|
+
do { \
|
|
45
|
+
if (SLJIT_UNLIKELY(compiler->error)) \
|
|
46
|
+
return compiler->error; \
|
|
47
|
+
} while (0)
|
|
48
|
+
|
|
49
|
+
#define CHECK_ERROR_PTR() \
|
|
50
|
+
do { \
|
|
51
|
+
if (SLJIT_UNLIKELY(compiler->error)) \
|
|
52
|
+
return NULL; \
|
|
53
|
+
} while (0)
|
|
54
|
+
|
|
55
|
+
#define FAIL_IF(expr) \
|
|
56
|
+
do { \
|
|
57
|
+
if (SLJIT_UNLIKELY(expr)) \
|
|
58
|
+
return compiler->error; \
|
|
59
|
+
} while (0)
|
|
60
|
+
|
|
61
|
+
#define PTR_FAIL_IF(expr) \
|
|
62
|
+
do { \
|
|
63
|
+
if (SLJIT_UNLIKELY(expr)) \
|
|
64
|
+
return NULL; \
|
|
65
|
+
} while (0)
|
|
66
|
+
|
|
67
|
+
#define FAIL_IF_NULL(ptr) \
|
|
68
|
+
do { \
|
|
69
|
+
if (SLJIT_UNLIKELY(!(ptr))) { \
|
|
70
|
+
compiler->error = SLJIT_ERR_ALLOC_FAILED; \
|
|
71
|
+
return SLJIT_ERR_ALLOC_FAILED; \
|
|
72
|
+
} \
|
|
73
|
+
} while (0)
|
|
74
|
+
|
|
75
|
+
#define PTR_FAIL_IF_NULL(ptr) \
|
|
76
|
+
do { \
|
|
77
|
+
if (SLJIT_UNLIKELY(!(ptr))) { \
|
|
78
|
+
compiler->error = SLJIT_ERR_ALLOC_FAILED; \
|
|
79
|
+
return NULL; \
|
|
80
|
+
} \
|
|
81
|
+
} while (0)
|
|
82
|
+
|
|
83
|
+
#define PTR_FAIL_WITH_EXEC_IF(ptr) \
|
|
84
|
+
do { \
|
|
85
|
+
if (SLJIT_UNLIKELY(!(ptr))) { \
|
|
86
|
+
compiler->error = SLJIT_ERR_EX_ALLOC_FAILED; \
|
|
87
|
+
return NULL; \
|
|
88
|
+
} \
|
|
89
|
+
} while (0)
|
|
90
|
+
|
|
91
|
+
#if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
|
|
92
|
+
|
|
93
|
+
#define SSIZE_OF(type) ((sljit_s32)sizeof(sljit_ ## type))
|
|
94
|
+
|
|
95
|
+
#define VARIABLE_FLAG_SHIFT (10)
|
|
96
|
+
/* All variable flags are even. */
|
|
97
|
+
#define VARIABLE_FLAG_MASK (0x3e << VARIABLE_FLAG_SHIFT)
|
|
98
|
+
#define GET_FLAG_TYPE(op) ((op) >> VARIABLE_FLAG_SHIFT)
|
|
99
|
+
|
|
100
|
+
#define GET_OPCODE(op) \
|
|
101
|
+
((op) & ~(SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK))
|
|
102
|
+
|
|
103
|
+
#define HAS_FLAGS(op) \
|
|
104
|
+
((op) & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))
|
|
105
|
+
|
|
106
|
+
#define GET_ALL_FLAGS(op) \
|
|
107
|
+
((op) & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK))
|
|
108
|
+
|
|
109
|
+
#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
|
|
110
|
+
#define TYPE_CAST_NEEDED(op) \
|
|
111
|
+
((op) >= SLJIT_MOV_U8 && (op) <= SLJIT_MOV_S32)
|
|
112
|
+
#else /* !SLJIT_64BIT_ARCHITECTURE */
|
|
113
|
+
#define TYPE_CAST_NEEDED(op) \
|
|
114
|
+
((op) >= SLJIT_MOV_U8 && (op) <= SLJIT_MOV_S16)
|
|
115
|
+
#endif /* SLJIT_64BIT_ARCHITECTURE */
|
|
116
|
+
|
|
117
|
+
#define BUF_SIZE 4096
|
|
118
|
+
|
|
119
|
+
#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)
|
|
120
|
+
#define ABUF_SIZE 2048
|
|
121
|
+
#else
|
|
122
|
+
#define ABUF_SIZE 4096
|
|
123
|
+
#endif
|
|
124
|
+
|
|
125
|
+
/* Parameter parsing. */
|
|
126
|
+
#define REG_MASK 0x7f
|
|
127
|
+
#define OFFS_REG(reg) (((reg) >> 8) & REG_MASK)
|
|
128
|
+
#define OFFS_REG_MASK (REG_MASK << 8)
|
|
129
|
+
#define TO_OFFS_REG(reg) ((reg) << 8)
|
|
130
|
+
#define FAST_IS_REG(reg) ((reg) < REG_MASK)
|
|
131
|
+
|
|
132
|
+
/* Mask for argument types. */
|
|
133
|
+
#define SLJIT_ARG_MASK 0x7
|
|
134
|
+
#define SLJIT_ARG_FULL_MASK (SLJIT_ARG_MASK | SLJIT_ARG_TYPE_SCRATCH_REG)
|
|
135
|
+
|
|
136
|
+
/* Mask for register pairs. */
|
|
137
|
+
#define REG_PAIR_MASK 0x7f00
|
|
138
|
+
#define REG_PAIR_FIRST(reg) ((reg) & 0x7f)
|
|
139
|
+
#define REG_PAIR_SECOND(reg) ((reg) >> 8)
|
|
140
|
+
|
|
141
|
+
/* Mask for sljit_emit_enter. */
|
|
142
|
+
#define SLJIT_KEPT_SAVEDS_COUNT(options) ((options) & 0x3)
|
|
143
|
+
|
|
144
|
+
/* Getters for simd operations, which returns with log2(size). */
|
|
145
|
+
#define SLJIT_SIMD_GET_OPCODE(type) ((type) & 0xff)
|
|
146
|
+
#define SLJIT_SIMD_GET_REG_SIZE(type) (((type) >> 12) & 0x3f)
|
|
147
|
+
#define SLJIT_SIMD_GET_ELEM_SIZE(type) (((type) >> 18) & 0x3f)
|
|
148
|
+
#define SLJIT_SIMD_GET_ELEM2_SIZE(type) (((type) >> 24) & 0x3f)
|
|
149
|
+
|
|
150
|
+
#define SLJIT_SIMD_CHECK_REG(type) (((type) & 0x3f000) >= SLJIT_SIMD_REG_64 && ((type) & 0x3f000) <= SLJIT_SIMD_REG_512)
|
|
151
|
+
#define SLJIT_SIMD_TYPE_MASK(m) ((sljit_s32)0xff000fff & ~(SLJIT_SIMD_FLOAT | SLJIT_SIMD_TEST | (m)))
|
|
152
|
+
#define SLJIT_SIMD_TYPE_MASK2(m) ((sljit_s32)0xc0000fff & ~(SLJIT_SIMD_FLOAT | SLJIT_SIMD_TEST | (m)))
|
|
153
|
+
|
|
154
|
+
/* Jump flags. */
|
|
155
|
+
#define JUMP_ADDR 0x1
|
|
156
|
+
#define JUMP_MOV_ADDR 0x2
|
|
157
|
+
/* SLJIT_REWRITABLE_JUMP is 0x1000. */
|
|
158
|
+
|
|
159
|
+
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
|
|
160
|
+
# define PATCH_MB 0x04
|
|
161
|
+
# define PATCH_MW 0x08
|
|
162
|
+
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
|
163
|
+
# define PATCH_MD 0x10
|
|
164
|
+
# define MOV_ADDR_HI 0x20
|
|
165
|
+
# define JUMP_MAX_SIZE ((sljit_uw)(10 + 3))
|
|
166
|
+
# define CJUMP_MAX_SIZE ((sljit_uw)(2 + 10 + 3))
|
|
167
|
+
#else /* !SLJIT_CONFIG_X86_64 */
|
|
168
|
+
# define JUMP_MAX_SIZE ((sljit_uw)5)
|
|
169
|
+
# define CJUMP_MAX_SIZE ((sljit_uw)6)
|
|
170
|
+
#endif /* SLJIT_CONFIG_X86_64 */
|
|
171
|
+
# define TYPE_SHIFT 13
|
|
172
|
+
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
|
173
|
+
/* Bits 7..12 is for debug jump size, SLJIT_REWRITABLE_JUMP is 0x1000 */
|
|
174
|
+
# define JUMP_SIZE_SHIFT 7
|
|
175
|
+
#endif /* SLJIT_DEBUG */
|
|
176
|
+
#endif /* SLJIT_CONFIG_X86 */
|
|
177
|
+
|
|
178
|
+
#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
|
|
179
|
+
# define IS_BL 0x04
|
|
180
|
+
# define PATCH_B 0x08
|
|
181
|
+
#endif /* SLJIT_CONFIG_ARM_V6 || SLJIT_CONFIG_ARM_V7 */
|
|
182
|
+
|
|
183
|
+
#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
|
|
184
|
+
# define CPOOL_SIZE 512
|
|
185
|
+
#endif /* SLJIT_CONFIG_ARM_V6 */
|
|
186
|
+
|
|
187
|
+
#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
|
|
188
|
+
# define JUMP_SIZE_SHIFT 26
|
|
189
|
+
# define JUMP_MAX_SIZE ((sljit_uw)3)
|
|
190
|
+
#endif /* SLJIT_CONFIG_ARM_V7 */
|
|
191
|
+
|
|
192
|
+
#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
|
|
193
|
+
# define IS_COND 0x04
|
|
194
|
+
# define IS_BL 0x08
|
|
195
|
+
/* conditional + imm8 */
|
|
196
|
+
# define PATCH_TYPE1 0x10
|
|
197
|
+
/* conditional + imm20 */
|
|
198
|
+
# define PATCH_TYPE2 0x20
|
|
199
|
+
/* imm11 */
|
|
200
|
+
# define PATCH_TYPE3 0x30
|
|
201
|
+
/* imm24 */
|
|
202
|
+
# define PATCH_TYPE4 0x40
|
|
203
|
+
/* BL + imm24 */
|
|
204
|
+
# define PATCH_TYPE5 0x50
|
|
205
|
+
/* addwi/subwi */
|
|
206
|
+
# define PATCH_TYPE6 0x60
|
|
207
|
+
/* 0xf00 cc code for branches */
|
|
208
|
+
# define JUMP_SIZE_SHIFT 26
|
|
209
|
+
# define JUMP_MAX_SIZE ((sljit_uw)5)
|
|
210
|
+
#endif /* SLJIT_CONFIG_ARM_THUMB2 */
|
|
211
|
+
|
|
212
|
+
#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
|
|
213
|
+
# define IS_COND 0x004
|
|
214
|
+
# define IS_CBZ 0x008
|
|
215
|
+
# define IS_BL 0x010
|
|
216
|
+
# define PATCH_COND 0x020
|
|
217
|
+
# define PATCH_B 0x040
|
|
218
|
+
# define PATCH_B32 0x080
|
|
219
|
+
# define PATCH_ABS48 0x100
|
|
220
|
+
# define PATCH_ABS64 0x200
|
|
221
|
+
# define JUMP_SIZE_SHIFT 58
|
|
222
|
+
# define JUMP_MAX_SIZE ((sljit_uw)5)
|
|
223
|
+
#endif /* SLJIT_CONFIG_ARM_64 */
|
|
224
|
+
|
|
225
|
+
#if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
|
|
226
|
+
# define IS_COND 0x004
|
|
227
|
+
# define IS_CALL 0x008
|
|
228
|
+
# define PATCH_B 0x010
|
|
229
|
+
# define PATCH_ABS_B 0x020
|
|
230
|
+
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
|
231
|
+
# define PATCH_ABS32 0x040
|
|
232
|
+
# define PATCH_ABS48 0x080
|
|
233
|
+
# define JUMP_SIZE_SHIFT 58
|
|
234
|
+
# define JUMP_MAX_SIZE ((sljit_uw)7)
|
|
235
|
+
#else /* !SLJIT_CONFIG_PPC_64 */
|
|
236
|
+
# define JUMP_SIZE_SHIFT 26
|
|
237
|
+
# define JUMP_MAX_SIZE ((sljit_uw)4)
|
|
238
|
+
#endif /* SLJIT_CONFIG_PPC_64 */
|
|
239
|
+
#endif /* SLJIT_CONFIG_PPC */
|
|
240
|
+
|
|
241
|
+
#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
|
|
242
|
+
# define IS_MOVABLE 0x004
|
|
243
|
+
# define IS_JAL 0x008
|
|
244
|
+
# define IS_CALL 0x010
|
|
245
|
+
# define IS_BIT26_COND 0x020
|
|
246
|
+
# define IS_BIT16_COND 0x040
|
|
247
|
+
# define IS_BIT23_COND 0x080
|
|
248
|
+
|
|
249
|
+
# define IS_COND (IS_BIT26_COND | IS_BIT16_COND | IS_BIT23_COND)
|
|
250
|
+
|
|
251
|
+
# define PATCH_B 0x100
|
|
252
|
+
# define PATCH_J 0x200
|
|
253
|
+
|
|
254
|
+
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
|
255
|
+
# define PATCH_ABS32 0x400
|
|
256
|
+
# define PATCH_ABS48 0x800
|
|
257
|
+
#endif /* SLJIT_CONFIG_MIPS_64 */
|
|
258
|
+
|
|
259
|
+
/* instruction types */
|
|
260
|
+
# define MOVABLE_INS 0
|
|
261
|
+
/* 1 - 31 last destination register */
|
|
262
|
+
/* no destination (i.e: store) */
|
|
263
|
+
# define UNMOVABLE_INS 32
|
|
264
|
+
/* FPU status register */
|
|
265
|
+
# define FCSR_FCC 33
|
|
266
|
+
#endif /* SLJIT_CONFIG_MIPS */
|
|
267
|
+
|
|
268
|
+
#if (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)
|
|
269
|
+
# define IS_COND 0x004
|
|
270
|
+
# define IS_CALL 0x008
|
|
271
|
+
|
|
272
|
+
# define PATCH_B 0x010
|
|
273
|
+
# define PATCH_J 0x020
|
|
274
|
+
|
|
275
|
+
#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
|
|
276
|
+
# define PATCH_REL32 0x040
|
|
277
|
+
# define PATCH_ABS32 0x080
|
|
278
|
+
# define PATCH_ABS44 0x100
|
|
279
|
+
# define PATCH_ABS52 0x200
|
|
280
|
+
# define JUMP_SIZE_SHIFT 58
|
|
281
|
+
# define JUMP_MAX_SIZE ((sljit_uw)6)
|
|
282
|
+
#else /* !SLJIT_CONFIG_RISCV_64 */
|
|
283
|
+
# define JUMP_SIZE_SHIFT 26
|
|
284
|
+
# define JUMP_MAX_SIZE ((sljit_uw)2)
|
|
285
|
+
#endif /* SLJIT_CONFIG_RISCV_64 */
|
|
286
|
+
#endif /* SLJIT_CONFIG_RISCV */
|
|
287
|
+
|
|
288
|
+
#if (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)
|
|
289
|
+
# define IS_COND 0x004
|
|
290
|
+
# define IS_CALL 0x008
|
|
291
|
+
|
|
292
|
+
# define PATCH_B 0x010
|
|
293
|
+
# define PATCH_J 0x020
|
|
294
|
+
|
|
295
|
+
# define PATCH_REL32 0x040
|
|
296
|
+
# define PATCH_ABS32 0x080
|
|
297
|
+
# define PATCH_ABS52 0x100
|
|
298
|
+
# define JUMP_SIZE_SHIFT 58
|
|
299
|
+
# define JUMP_MAX_SIZE ((sljit_uw)4)
|
|
300
|
+
|
|
301
|
+
#endif /* SLJIT_CONFIG_LOONGARCH */
|
|
302
|
+
/* Stack management. */
|
|
303
|
+
|
|
304
|
+
#define GET_SAVED_REGISTERS_SIZE(scratches, saveds, extra) \
|
|
305
|
+
(((scratches < SLJIT_NUMBER_OF_SCRATCH_REGISTERS ? 0 : (scratches - SLJIT_NUMBER_OF_SCRATCH_REGISTERS)) + \
|
|
306
|
+
(saveds) + (sljit_s32)(extra)) * (sljit_s32)sizeof(sljit_sw))
|
|
307
|
+
|
|
308
|
+
#define GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, type) \
|
|
309
|
+
(((fscratches < SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS ? 0 : (fscratches - SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS)) + \
|
|
310
|
+
(fsaveds)) * SSIZE_OF(type))
|
|
311
|
+
|
|
312
|
+
#define ADJUST_LOCAL_OFFSET(p, i) \
|
|
313
|
+
if ((p) == (SLJIT_MEM1(SLJIT_SP))) \
|
|
314
|
+
(i) += SLJIT_LOCALS_OFFSET;
|
|
315
|
+
|
|
316
|
+
#endif /* !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) */
|
|
317
|
+
|
|
318
|
+
/* Utils can still be used even if SLJIT_CONFIG_UNSUPPORTED is set. */
|
|
319
|
+
#include "sljitUtils.c"
|
|
320
|
+
|
|
321
|
+
#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
|
|
322
|
+
#define SLJIT_CODE_TO_PTR(code) ((void*)((sljit_up)(code) & ~(sljit_up)0x1))
|
|
323
|
+
#elif (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
|
|
324
|
+
#define SLJIT_CODE_TO_PTR(code) ((void*)(*(sljit_up*)code))
|
|
325
|
+
#else /* !SLJIT_CONFIG_ARM_THUMB2 && !SLJIT_INDIRECT_CALL */
|
|
326
|
+
#define SLJIT_CODE_TO_PTR(code) ((void*)(code))
|
|
327
|
+
#endif /* SLJIT_CONFIG_ARM_THUMB2 || SLJIT_INDIRECT_CALL */
|
|
328
|
+
|
|
329
|
+
#if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
|
|
330
|
+
|
|
331
|
+
#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
|
|
332
|
+
|
|
333
|
+
#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
|
|
334
|
+
|
|
335
|
+
#if defined(__NetBSD__)
|
|
336
|
+
#include "allocator_src/sljitProtExecAllocatorNetBSD.c"
|
|
337
|
+
#else
|
|
338
|
+
#include "allocator_src/sljitProtExecAllocatorPosix.c"
|
|
339
|
+
#endif
|
|
340
|
+
|
|
341
|
+
#elif (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)
|
|
342
|
+
|
|
343
|
+
#if defined(_WIN32)
|
|
344
|
+
#include "allocator_src/sljitWXExecAllocatorWindows.c"
|
|
345
|
+
#else
|
|
346
|
+
#include "allocator_src/sljitWXExecAllocatorPosix.c"
|
|
347
|
+
#endif
|
|
348
|
+
|
|
349
|
+
#else
|
|
350
|
+
|
|
351
|
+
#if defined(_WIN32)
|
|
352
|
+
#include "allocator_src/sljitExecAllocatorWindows.c"
|
|
353
|
+
#elif defined(__APPLE__)
|
|
354
|
+
#include "allocator_src/sljitExecAllocatorApple.c"
|
|
355
|
+
#elif defined(__FreeBSD__)
|
|
356
|
+
#include "allocator_src/sljitExecAllocatorFreeBSD.c"
|
|
357
|
+
#else
|
|
358
|
+
#include "allocator_src/sljitExecAllocatorPosix.c"
|
|
359
|
+
#endif
|
|
360
|
+
|
|
361
|
+
#endif
|
|
362
|
+
|
|
363
|
+
#else /* !SLJIT_EXECUTABLE_ALLOCATOR */
|
|
364
|
+
|
|
365
|
+
#ifndef SLJIT_UPDATE_WX_FLAGS
|
|
366
|
+
#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)
|
|
367
|
+
#endif
|
|
368
|
+
|
|
369
|
+
#endif /* SLJIT_EXECUTABLE_ALLOCATOR */
|
|
370
|
+
|
|
371
|
+
#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
|
|
372
|
+
#define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr) + (exec_offset))
|
|
373
|
+
#else
|
|
374
|
+
#define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr))
|
|
375
|
+
#endif
|
|
376
|
+
|
|
377
|
+
/* Argument checking features. */
|
|
378
|
+
|
|
379
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
380
|
+
|
|
381
|
+
/* Returns with error when an invalid argument is passed. */
|
|
382
|
+
|
|
383
|
+
#define CHECK_ARGUMENT(x) \
|
|
384
|
+
do { \
|
|
385
|
+
if (SLJIT_UNLIKELY(!(x))) \
|
|
386
|
+
return 1; \
|
|
387
|
+
} while (0)
|
|
388
|
+
|
|
389
|
+
#define CHECK_RETURN_TYPE sljit_s32
|
|
390
|
+
#define CHECK_RETURN_OK return 0
|
|
391
|
+
|
|
392
|
+
#define CHECK(x) \
|
|
393
|
+
do { \
|
|
394
|
+
if (SLJIT_UNLIKELY(x)) { \
|
|
395
|
+
compiler->error = SLJIT_ERR_BAD_ARGUMENT; \
|
|
396
|
+
return SLJIT_ERR_BAD_ARGUMENT; \
|
|
397
|
+
} \
|
|
398
|
+
} while (0)
|
|
399
|
+
|
|
400
|
+
#define CHECK_PTR(x) \
|
|
401
|
+
do { \
|
|
402
|
+
if (SLJIT_UNLIKELY(x)) { \
|
|
403
|
+
compiler->error = SLJIT_ERR_BAD_ARGUMENT; \
|
|
404
|
+
return NULL; \
|
|
405
|
+
} \
|
|
406
|
+
} while (0)
|
|
407
|
+
|
|
408
|
+
#define CHECK_REG_INDEX(x) \
|
|
409
|
+
do { \
|
|
410
|
+
if (SLJIT_UNLIKELY(x)) { \
|
|
411
|
+
return -2; \
|
|
412
|
+
} \
|
|
413
|
+
} while (0)
|
|
414
|
+
|
|
415
|
+
#elif (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
|
416
|
+
|
|
417
|
+
/* Assertion failure occures if an invalid argument is passed. */
|
|
418
|
+
#undef SLJIT_ARGUMENT_CHECKS
|
|
419
|
+
#define SLJIT_ARGUMENT_CHECKS 1
|
|
420
|
+
|
|
421
|
+
#define CHECK_ARGUMENT(x) SLJIT_ASSERT(x)
|
|
422
|
+
#define CHECK_RETURN_TYPE void
|
|
423
|
+
#define CHECK_RETURN_OK return
|
|
424
|
+
#define CHECK(x) x
|
|
425
|
+
#define CHECK_PTR(x) x
|
|
426
|
+
#define CHECK_REG_INDEX(x) x
|
|
427
|
+
|
|
428
|
+
#elif (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
429
|
+
|
|
430
|
+
/* Arguments are not checked. */
|
|
431
|
+
#define CHECK_RETURN_TYPE void
|
|
432
|
+
#define CHECK_RETURN_OK return
|
|
433
|
+
#define CHECK(x) x
|
|
434
|
+
#define CHECK_PTR(x) x
|
|
435
|
+
#define CHECK_REG_INDEX(x) x
|
|
436
|
+
|
|
437
|
+
#else
|
|
438
|
+
|
|
439
|
+
/* Arguments are not checked. */
|
|
440
|
+
#define CHECK(x)
|
|
441
|
+
#define CHECK_PTR(x)
|
|
442
|
+
#define CHECK_REG_INDEX(x)
|
|
443
|
+
|
|
444
|
+
#endif /* SLJIT_ARGUMENT_CHECKS */
|
|
445
|
+
|
|
446
|
+
/* --------------------------------------------------------------------- */
|
|
447
|
+
/* Public functions */
|
|
448
|
+
/* --------------------------------------------------------------------- */
|
|
449
|
+
|
|
450
|
+
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
|
|
451
|
+
#define SLJIT_NEEDS_COMPILER_INIT 1
|
|
452
|
+
static sljit_s32 compiler_initialized = 0;
|
|
453
|
+
/* A thread safe initialization. */
|
|
454
|
+
static void init_compiler(void);
|
|
455
|
+
#endif
|
|
456
|
+
|
|
457
|
+
SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data)
|
|
458
|
+
{
|
|
459
|
+
struct sljit_compiler *compiler = (struct sljit_compiler*)SLJIT_MALLOC(sizeof(struct sljit_compiler), allocator_data);
|
|
460
|
+
if (!compiler)
|
|
461
|
+
return NULL;
|
|
462
|
+
SLJIT_ZEROMEM(compiler, sizeof(struct sljit_compiler));
|
|
463
|
+
|
|
464
|
+
SLJIT_COMPILE_ASSERT(
|
|
465
|
+
sizeof(sljit_s8) == 1 && sizeof(sljit_u8) == 1
|
|
466
|
+
&& sizeof(sljit_s16) == 2 && sizeof(sljit_u16) == 2
|
|
467
|
+
&& sizeof(sljit_s32) == 4 && sizeof(sljit_u32) == 4
|
|
468
|
+
&& (sizeof(sljit_up) == 4 || sizeof(sljit_up) == 8)
|
|
469
|
+
&& sizeof(sljit_up) <= sizeof(sljit_sw)
|
|
470
|
+
&& sizeof(sljit_up) == sizeof(sljit_sp)
|
|
471
|
+
&& (sizeof(sljit_sw) == 4 || sizeof(sljit_sw) == 8)
|
|
472
|
+
&& (sizeof(sljit_uw) == sizeof(sljit_sw)),
|
|
473
|
+
invalid_integer_types);
|
|
474
|
+
SLJIT_COMPILE_ASSERT(SLJIT_REWRITABLE_JUMP != SLJIT_32,
|
|
475
|
+
rewritable_jump_and_single_op_must_not_be_the_same);
|
|
476
|
+
SLJIT_COMPILE_ASSERT(!(SLJIT_EQUAL & 0x1) && !(SLJIT_LESS & 0x1) && !(SLJIT_F_EQUAL & 0x1) && !(SLJIT_JUMP & 0x1),
|
|
477
|
+
conditional_flags_must_be_even_numbers);
|
|
478
|
+
|
|
479
|
+
/* Only the non-zero members must be set. */
|
|
480
|
+
compiler->error = SLJIT_SUCCESS;
|
|
481
|
+
|
|
482
|
+
compiler->allocator_data = allocator_data;
|
|
483
|
+
compiler->buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, allocator_data);
|
|
484
|
+
compiler->abuf = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, allocator_data);
|
|
485
|
+
|
|
486
|
+
if (!compiler->buf || !compiler->abuf) {
|
|
487
|
+
if (compiler->buf)
|
|
488
|
+
SLJIT_FREE(compiler->buf, allocator_data);
|
|
489
|
+
if (compiler->abuf)
|
|
490
|
+
SLJIT_FREE(compiler->abuf, allocator_data);
|
|
491
|
+
SLJIT_FREE(compiler, allocator_data);
|
|
492
|
+
return NULL;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
compiler->buf->next = NULL;
|
|
496
|
+
compiler->buf->used_size = 0;
|
|
497
|
+
compiler->abuf->next = NULL;
|
|
498
|
+
compiler->abuf->used_size = 0;
|
|
499
|
+
|
|
500
|
+
compiler->scratches = -1;
|
|
501
|
+
compiler->saveds = -1;
|
|
502
|
+
compiler->fscratches = -1;
|
|
503
|
+
compiler->fsaveds = -1;
|
|
504
|
+
compiler->local_size = -1;
|
|
505
|
+
|
|
506
|
+
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
|
507
|
+
compiler->args_size = -1;
|
|
508
|
+
#endif /* SLJIT_CONFIG_X86_32 */
|
|
509
|
+
|
|
510
|
+
#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
|
|
511
|
+
compiler->cpool = (sljit_uw*)SLJIT_MALLOC(CPOOL_SIZE * sizeof(sljit_uw)
|
|
512
|
+
+ CPOOL_SIZE * sizeof(sljit_u8), allocator_data);
|
|
513
|
+
if (!compiler->cpool) {
|
|
514
|
+
SLJIT_FREE(compiler->buf, allocator_data);
|
|
515
|
+
SLJIT_FREE(compiler->abuf, allocator_data);
|
|
516
|
+
SLJIT_FREE(compiler, allocator_data);
|
|
517
|
+
return NULL;
|
|
518
|
+
}
|
|
519
|
+
compiler->cpool_unique = (sljit_u8*)(compiler->cpool + CPOOL_SIZE);
|
|
520
|
+
compiler->cpool_diff = 0xffffffff;
|
|
521
|
+
#endif /* SLJIT_CONFIG_ARM_V6 */
|
|
522
|
+
|
|
523
|
+
#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
|
|
524
|
+
compiler->delay_slot = UNMOVABLE_INS;
|
|
525
|
+
#endif /* SLJIT_CONFIG_MIPS */
|
|
526
|
+
|
|
527
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
|
|
528
|
+
|| (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
|
529
|
+
compiler->last_flags = 0;
|
|
530
|
+
compiler->last_return = -1;
|
|
531
|
+
compiler->logical_local_size = 0;
|
|
532
|
+
#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */
|
|
533
|
+
|
|
534
|
+
#if (defined SLJIT_NEEDS_COMPILER_INIT && SLJIT_NEEDS_COMPILER_INIT)
|
|
535
|
+
if (!compiler_initialized) {
|
|
536
|
+
init_compiler();
|
|
537
|
+
compiler_initialized = 1;
|
|
538
|
+
}
|
|
539
|
+
#endif
|
|
540
|
+
|
|
541
|
+
return compiler;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler)
|
|
545
|
+
{
|
|
546
|
+
struct sljit_memory_fragment *buf;
|
|
547
|
+
struct sljit_memory_fragment *curr;
|
|
548
|
+
void *allocator_data = compiler->allocator_data;
|
|
549
|
+
SLJIT_UNUSED_ARG(allocator_data);
|
|
550
|
+
|
|
551
|
+
buf = compiler->buf;
|
|
552
|
+
while (buf) {
|
|
553
|
+
curr = buf;
|
|
554
|
+
buf = buf->next;
|
|
555
|
+
SLJIT_FREE(curr, allocator_data);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
buf = compiler->abuf;
|
|
559
|
+
while (buf) {
|
|
560
|
+
curr = buf;
|
|
561
|
+
buf = buf->next;
|
|
562
|
+
SLJIT_FREE(curr, allocator_data);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
|
|
566
|
+
SLJIT_FREE(compiler->cpool, allocator_data);
|
|
567
|
+
#endif
|
|
568
|
+
SLJIT_FREE(compiler, allocator_data);
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler)
|
|
572
|
+
{
|
|
573
|
+
if (compiler->error == SLJIT_SUCCESS)
|
|
574
|
+
compiler->error = SLJIT_ERR_ALLOC_FAILED;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
|
|
578
|
+
{
|
|
579
|
+
SLJIT_UNUSED_ARG(exec_allocator_data);
|
|
580
|
+
|
|
581
|
+
SLJIT_FREE_EXEC(SLJIT_CODE_TO_PTR(code), exec_allocator_data);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label)
|
|
585
|
+
{
|
|
586
|
+
if (SLJIT_LIKELY(!!jump) && SLJIT_LIKELY(!!label)) {
|
|
587
|
+
jump->flags &= (sljit_uw)~JUMP_ADDR;
|
|
588
|
+
jump->u.label = label;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target)
|
|
593
|
+
{
|
|
594
|
+
if (SLJIT_LIKELY(!!jump)) {
|
|
595
|
+
jump->flags |= JUMP_ADDR;
|
|
596
|
+
jump->u.target = target;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
#define SLJIT_CURRENT_FLAGS_ALL \
|
|
601
|
+
(SLJIT_CURRENT_FLAGS_32 | SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB | SLJIT_CURRENT_FLAGS_COMPARE)
|
|
602
|
+
|
|
603
|
+
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler, sljit_s32 current_flags)
|
|
604
|
+
{
|
|
605
|
+
SLJIT_UNUSED_ARG(compiler);
|
|
606
|
+
SLJIT_UNUSED_ARG(current_flags);
|
|
607
|
+
|
|
608
|
+
#if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE)
|
|
609
|
+
compiler->status_flags_state = current_flags;
|
|
610
|
+
#endif
|
|
611
|
+
|
|
612
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
613
|
+
compiler->last_flags = 0;
|
|
614
|
+
if ((current_flags & ~(VARIABLE_FLAG_MASK | SLJIT_SET_Z | SLJIT_CURRENT_FLAGS_ALL)) == 0) {
|
|
615
|
+
compiler->last_flags = GET_FLAG_TYPE(current_flags) | (current_flags & (SLJIT_32 | SLJIT_SET_Z));
|
|
616
|
+
}
|
|
617
|
+
#endif
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/* --------------------------------------------------------------------- */
|
|
621
|
+
/* Private functions */
|
|
622
|
+
/* --------------------------------------------------------------------- */
|
|
623
|
+
|
|
624
|
+
static void* ensure_buf(struct sljit_compiler *compiler, sljit_uw size)
|
|
625
|
+
{
|
|
626
|
+
sljit_u8 *ret;
|
|
627
|
+
struct sljit_memory_fragment *new_frag;
|
|
628
|
+
|
|
629
|
+
SLJIT_ASSERT(size <= 256);
|
|
630
|
+
if (compiler->buf->used_size + size <= (BUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) {
|
|
631
|
+
ret = compiler->buf->memory + compiler->buf->used_size;
|
|
632
|
+
compiler->buf->used_size += size;
|
|
633
|
+
return ret;
|
|
634
|
+
}
|
|
635
|
+
new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, compiler->allocator_data);
|
|
636
|
+
PTR_FAIL_IF_NULL(new_frag);
|
|
637
|
+
new_frag->next = compiler->buf;
|
|
638
|
+
compiler->buf = new_frag;
|
|
639
|
+
new_frag->used_size = size;
|
|
640
|
+
return new_frag->memory;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
static void* ensure_abuf(struct sljit_compiler *compiler, sljit_uw size)
|
|
644
|
+
{
|
|
645
|
+
sljit_u8 *ret;
|
|
646
|
+
struct sljit_memory_fragment *new_frag;
|
|
647
|
+
|
|
648
|
+
SLJIT_ASSERT(size <= 256);
|
|
649
|
+
if (compiler->abuf->used_size + size <= (ABUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) {
|
|
650
|
+
ret = compiler->abuf->memory + compiler->abuf->used_size;
|
|
651
|
+
compiler->abuf->used_size += size;
|
|
652
|
+
return ret;
|
|
653
|
+
}
|
|
654
|
+
new_frag = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, compiler->allocator_data);
|
|
655
|
+
PTR_FAIL_IF_NULL(new_frag);
|
|
656
|
+
new_frag->next = compiler->abuf;
|
|
657
|
+
compiler->abuf = new_frag;
|
|
658
|
+
new_frag->used_size = size;
|
|
659
|
+
return new_frag->memory;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size)
|
|
663
|
+
{
|
|
664
|
+
CHECK_ERROR_PTR();
|
|
665
|
+
|
|
666
|
+
#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
|
|
667
|
+
if (size <= 0 || size > 128)
|
|
668
|
+
return NULL;
|
|
669
|
+
size = (size + 7) & ~7;
|
|
670
|
+
#else
|
|
671
|
+
if (size <= 0 || size > 64)
|
|
672
|
+
return NULL;
|
|
673
|
+
size = (size + 3) & ~3;
|
|
674
|
+
#endif
|
|
675
|
+
return ensure_abuf(compiler, (sljit_uw)size);
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
static SLJIT_INLINE void reverse_buf(struct sljit_compiler *compiler)
|
|
679
|
+
{
|
|
680
|
+
struct sljit_memory_fragment *buf = compiler->buf;
|
|
681
|
+
struct sljit_memory_fragment *prev = NULL;
|
|
682
|
+
struct sljit_memory_fragment *tmp;
|
|
683
|
+
|
|
684
|
+
do {
|
|
685
|
+
tmp = buf->next;
|
|
686
|
+
buf->next = prev;
|
|
687
|
+
prev = buf;
|
|
688
|
+
buf = tmp;
|
|
689
|
+
} while (buf != NULL);
|
|
690
|
+
|
|
691
|
+
compiler->buf = prev;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
static SLJIT_INLINE void* allocate_executable_memory(sljit_uw size, sljit_s32 options,
|
|
695
|
+
void *exec_allocator_data, sljit_sw *executable_offset)
|
|
696
|
+
{
|
|
697
|
+
void *code;
|
|
698
|
+
struct sljit_generate_code_buffer *buffer;
|
|
699
|
+
|
|
700
|
+
if (SLJIT_LIKELY(!(options & SLJIT_GENERATE_CODE_BUFFER))) {
|
|
701
|
+
code = SLJIT_MALLOC_EXEC(size, exec_allocator_data);
|
|
702
|
+
*executable_offset = SLJIT_EXEC_OFFSET(code);
|
|
703
|
+
return code;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
buffer = (struct sljit_generate_code_buffer*)exec_allocator_data;
|
|
707
|
+
|
|
708
|
+
if (size <= buffer->size) {
|
|
709
|
+
*executable_offset = buffer->executable_offset;
|
|
710
|
+
return buffer->buffer;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
return NULL;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
#define SLJIT_MAX_ADDRESS ~(sljit_uw)0
|
|
717
|
+
|
|
718
|
+
#define SLJIT_GET_NEXT_SIZE(ptr) (ptr != NULL) ? ((ptr)->size) : SLJIT_MAX_ADDRESS
|
|
719
|
+
#define SLJIT_GET_NEXT_ADDRESS(ptr) (ptr != NULL) ? ((ptr)->addr) : SLJIT_MAX_ADDRESS
|
|
720
|
+
|
|
721
|
+
#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
|
|
722
|
+
|
|
723
|
+
#define SLJIT_NEXT_DEFINE_TYPES \
|
|
724
|
+
sljit_uw next_label_size; \
|
|
725
|
+
sljit_uw next_jump_addr; \
|
|
726
|
+
sljit_uw next_const_addr; \
|
|
727
|
+
sljit_uw next_min_addr
|
|
728
|
+
|
|
729
|
+
#define SLJIT_NEXT_INIT_TYPES() \
|
|
730
|
+
next_label_size = SLJIT_GET_NEXT_SIZE(label); \
|
|
731
|
+
next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); \
|
|
732
|
+
next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);
|
|
733
|
+
|
|
734
|
+
#define SLJIT_GET_NEXT_MIN() \
|
|
735
|
+
next_min_addr = sljit_get_next_min(next_label_size, next_jump_addr, next_const_addr);
|
|
736
|
+
|
|
737
|
+
static SLJIT_INLINE sljit_uw sljit_get_next_min(sljit_uw next_label_size,
|
|
738
|
+
sljit_uw next_jump_addr, sljit_uw next_const_addr)
|
|
739
|
+
{
|
|
740
|
+
sljit_uw result = next_jump_addr;
|
|
741
|
+
|
|
742
|
+
SLJIT_ASSERT(result == SLJIT_MAX_ADDRESS || result != next_const_addr);
|
|
743
|
+
|
|
744
|
+
if (next_const_addr < result)
|
|
745
|
+
result = next_const_addr;
|
|
746
|
+
|
|
747
|
+
if (next_label_size < result)
|
|
748
|
+
result = next_label_size;
|
|
749
|
+
|
|
750
|
+
return result;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
#endif /* !SLJIT_CONFIG_X86 */
|
|
754
|
+
|
|
755
|
+
static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler,
|
|
756
|
+
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
|
757
|
+
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
|
758
|
+
{
|
|
759
|
+
SLJIT_UNUSED_ARG(args);
|
|
760
|
+
SLJIT_UNUSED_ARG(local_size);
|
|
761
|
+
|
|
762
|
+
compiler->options = options;
|
|
763
|
+
compiler->scratches = scratches;
|
|
764
|
+
compiler->saveds = saveds;
|
|
765
|
+
compiler->fscratches = fscratches;
|
|
766
|
+
compiler->fsaveds = fsaveds;
|
|
767
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
768
|
+
compiler->last_return = args & SLJIT_ARG_MASK;
|
|
769
|
+
compiler->logical_local_size = local_size;
|
|
770
|
+
#endif
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
static SLJIT_INLINE void set_set_context(struct sljit_compiler *compiler,
|
|
774
|
+
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
|
775
|
+
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
|
776
|
+
{
|
|
777
|
+
SLJIT_UNUSED_ARG(args);
|
|
778
|
+
SLJIT_UNUSED_ARG(local_size);
|
|
779
|
+
|
|
780
|
+
compiler->options = options;
|
|
781
|
+
compiler->scratches = scratches;
|
|
782
|
+
compiler->saveds = saveds;
|
|
783
|
+
compiler->fscratches = fscratches;
|
|
784
|
+
compiler->fsaveds = fsaveds;
|
|
785
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
786
|
+
compiler->last_return = args & SLJIT_ARG_MASK;
|
|
787
|
+
compiler->logical_local_size = local_size;
|
|
788
|
+
#endif
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
static SLJIT_INLINE void set_label(struct sljit_label *label, struct sljit_compiler *compiler)
|
|
792
|
+
{
|
|
793
|
+
label->next = NULL;
|
|
794
|
+
label->u.index = compiler->label_count++;
|
|
795
|
+
label->size = compiler->size;
|
|
796
|
+
if (compiler->last_label != NULL)
|
|
797
|
+
compiler->last_label->next = label;
|
|
798
|
+
else
|
|
799
|
+
compiler->labels = label;
|
|
800
|
+
compiler->last_label = label;
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, sljit_u32 flags)
|
|
804
|
+
{
|
|
805
|
+
jump->next = NULL;
|
|
806
|
+
jump->flags = flags;
|
|
807
|
+
jump->u.label = NULL;
|
|
808
|
+
if (compiler->last_jump != NULL)
|
|
809
|
+
compiler->last_jump->next = jump;
|
|
810
|
+
else
|
|
811
|
+
compiler->jumps = jump;
|
|
812
|
+
compiler->last_jump = jump;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
static SLJIT_INLINE void set_mov_addr(struct sljit_jump *jump, struct sljit_compiler *compiler, sljit_uw offset)
|
|
816
|
+
{
|
|
817
|
+
jump->next = NULL;
|
|
818
|
+
jump->addr = compiler->size - offset;
|
|
819
|
+
jump->flags = JUMP_MOV_ADDR;
|
|
820
|
+
jump->u.label = NULL;
|
|
821
|
+
if (compiler->last_jump != NULL)
|
|
822
|
+
compiler->last_jump->next = jump;
|
|
823
|
+
else
|
|
824
|
+
compiler->jumps = jump;
|
|
825
|
+
compiler->last_jump = jump;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_compiler *compiler)
|
|
829
|
+
{
|
|
830
|
+
const_->next = NULL;
|
|
831
|
+
const_->addr = compiler->size;
|
|
832
|
+
if (compiler->last_const != NULL)
|
|
833
|
+
compiler->last_const->next = const_;
|
|
834
|
+
else
|
|
835
|
+
compiler->consts = const_;
|
|
836
|
+
compiler->last_const = const_;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
#define ADDRESSING_DEPENDS_ON(exp, reg) \
|
|
840
|
+
(((exp) & SLJIT_MEM) && (((exp) & REG_MASK) == reg || OFFS_REG(exp) == reg))
|
|
841
|
+
|
|
842
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
843
|
+
|
|
844
|
+
static sljit_s32 function_check_arguments(sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, sljit_s32 fscratches)
|
|
845
|
+
{
|
|
846
|
+
sljit_s32 word_arg_count, scratch_arg_end, saved_arg_count, float_arg_count, curr_type;
|
|
847
|
+
|
|
848
|
+
curr_type = (arg_types & SLJIT_ARG_FULL_MASK);
|
|
849
|
+
|
|
850
|
+
if (curr_type >= SLJIT_ARG_TYPE_F64) {
|
|
851
|
+
if (curr_type > SLJIT_ARG_TYPE_F32 || fscratches == 0)
|
|
852
|
+
return 0;
|
|
853
|
+
} else if (curr_type >= SLJIT_ARG_TYPE_W) {
|
|
854
|
+
if (scratches == 0)
|
|
855
|
+
return 0;
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
arg_types >>= SLJIT_ARG_SHIFT;
|
|
859
|
+
|
|
860
|
+
word_arg_count = 0;
|
|
861
|
+
scratch_arg_end = 0;
|
|
862
|
+
saved_arg_count = 0;
|
|
863
|
+
float_arg_count = 0;
|
|
864
|
+
while (arg_types != 0) {
|
|
865
|
+
if (word_arg_count + float_arg_count >= 4)
|
|
866
|
+
return 0;
|
|
867
|
+
|
|
868
|
+
curr_type = (arg_types & SLJIT_ARG_MASK);
|
|
869
|
+
|
|
870
|
+
if (arg_types & SLJIT_ARG_TYPE_SCRATCH_REG) {
|
|
871
|
+
if (saveds == -1 || curr_type < SLJIT_ARG_TYPE_W || curr_type > SLJIT_ARG_TYPE_P)
|
|
872
|
+
return 0;
|
|
873
|
+
|
|
874
|
+
word_arg_count++;
|
|
875
|
+
scratch_arg_end = word_arg_count;
|
|
876
|
+
} else {
|
|
877
|
+
if (curr_type < SLJIT_ARG_TYPE_W || curr_type > SLJIT_ARG_TYPE_F32)
|
|
878
|
+
return 0;
|
|
879
|
+
|
|
880
|
+
if (curr_type < SLJIT_ARG_TYPE_F64) {
|
|
881
|
+
word_arg_count++;
|
|
882
|
+
saved_arg_count++;
|
|
883
|
+
} else
|
|
884
|
+
float_arg_count++;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
arg_types >>= SLJIT_ARG_SHIFT;
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
if (saveds == -1)
|
|
891
|
+
return (word_arg_count <= scratches && float_arg_count <= fscratches);
|
|
892
|
+
|
|
893
|
+
return (saved_arg_count <= saveds && scratch_arg_end <= scratches && float_arg_count <= fscratches);
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
#define FUNCTION_CHECK_IS_REG(r) \
|
|
897
|
+
(((r) >= SLJIT_R0 && (r) < (SLJIT_R0 + compiler->scratches)) \
|
|
898
|
+
|| ((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0) \
|
|
899
|
+
|| ((r) >= SLJIT_TMP_REGISTER_BASE && (r) < (SLJIT_TMP_REGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_REGISTERS)))
|
|
900
|
+
|
|
901
|
+
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
|
902
|
+
#define CHECK_IF_VIRTUAL_REGISTER(p) ((p) <= SLJIT_S3 && (p) >= SLJIT_S8)
|
|
903
|
+
#else
|
|
904
|
+
#define CHECK_IF_VIRTUAL_REGISTER(p) 0
|
|
905
|
+
#endif
|
|
906
|
+
|
|
907
|
+
static sljit_s32 function_check_src_mem(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
|
|
908
|
+
{
|
|
909
|
+
if (compiler->scratches == -1)
|
|
910
|
+
return 0;
|
|
911
|
+
|
|
912
|
+
if (!(p & SLJIT_MEM))
|
|
913
|
+
return 0;
|
|
914
|
+
|
|
915
|
+
if (p == SLJIT_MEM1(SLJIT_SP))
|
|
916
|
+
return (i >= 0 && i < compiler->logical_local_size);
|
|
917
|
+
|
|
918
|
+
if (!(!(p & REG_MASK) || FUNCTION_CHECK_IS_REG(p & REG_MASK)))
|
|
919
|
+
return 0;
|
|
920
|
+
|
|
921
|
+
if (CHECK_IF_VIRTUAL_REGISTER(p & REG_MASK))
|
|
922
|
+
return 0;
|
|
923
|
+
|
|
924
|
+
if (p & OFFS_REG_MASK) {
|
|
925
|
+
if (!(p & REG_MASK))
|
|
926
|
+
return 0;
|
|
927
|
+
|
|
928
|
+
if (!(FUNCTION_CHECK_IS_REG(OFFS_REG(p))))
|
|
929
|
+
return 0;
|
|
930
|
+
|
|
931
|
+
if (CHECK_IF_VIRTUAL_REGISTER(OFFS_REG(p)))
|
|
932
|
+
return 0;
|
|
933
|
+
|
|
934
|
+
if ((i & ~0x3) != 0)
|
|
935
|
+
return 0;
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
return (p & ~(SLJIT_MEM | REG_MASK | OFFS_REG_MASK)) == 0;
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
#define FUNCTION_CHECK_SRC_MEM(p, i) \
|
|
942
|
+
CHECK_ARGUMENT(function_check_src_mem(compiler, p, i));
|
|
943
|
+
|
|
944
|
+
static sljit_s32 function_check_src(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
|
|
945
|
+
{
|
|
946
|
+
if (compiler->scratches == -1)
|
|
947
|
+
return 0;
|
|
948
|
+
|
|
949
|
+
if (FUNCTION_CHECK_IS_REG(p))
|
|
950
|
+
return (i == 0);
|
|
951
|
+
|
|
952
|
+
if (p == SLJIT_IMM)
|
|
953
|
+
return 1;
|
|
954
|
+
|
|
955
|
+
return function_check_src_mem(compiler, p, i);
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
#define FUNCTION_CHECK_SRC(p, i) \
|
|
959
|
+
CHECK_ARGUMENT(function_check_src(compiler, p, i));
|
|
960
|
+
|
|
961
|
+
static sljit_s32 function_check_dst(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
|
|
962
|
+
{
|
|
963
|
+
if (compiler->scratches == -1)
|
|
964
|
+
return 0;
|
|
965
|
+
|
|
966
|
+
if (FUNCTION_CHECK_IS_REG(p))
|
|
967
|
+
return (i == 0);
|
|
968
|
+
|
|
969
|
+
return function_check_src_mem(compiler, p, i);
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
#define FUNCTION_CHECK_DST(p, i) \
|
|
973
|
+
CHECK_ARGUMENT(function_check_dst(compiler, p, i));
|
|
974
|
+
|
|
975
|
+
#if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \
|
|
976
|
+
|| (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
|
977
|
+
|
|
978
|
+
#define FUNCTION_CHECK_IS_FREG(fr, is_32) \
|
|
979
|
+
function_check_is_freg(compiler, (fr), (is_32))
|
|
980
|
+
|
|
981
|
+
static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s32 fr, sljit_s32 is_32);
|
|
982
|
+
|
|
983
|
+
#define FUNCTION_FCHECK(p, i, is_32) \
|
|
984
|
+
CHECK_ARGUMENT(function_fcheck(compiler, (p), (i), (is_32)));
|
|
985
|
+
|
|
986
|
+
static sljit_s32 function_fcheck(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i, sljit_s32 is_32)
|
|
987
|
+
{
|
|
988
|
+
if (compiler->scratches == -1)
|
|
989
|
+
return 0;
|
|
990
|
+
|
|
991
|
+
if (FUNCTION_CHECK_IS_FREG(p, is_32))
|
|
992
|
+
return (i == 0);
|
|
993
|
+
|
|
994
|
+
return function_check_src_mem(compiler, p, i);
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
#else /* !SLJIT_CONFIG_ARM_32 && !SLJIT_CONFIG_MIPS_32 */
|
|
998
|
+
#define FUNCTION_CHECK_IS_FREG(fr, is_32) \
|
|
999
|
+
function_check_is_freg(compiler, (fr))
|
|
1000
|
+
|
|
1001
|
+
static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s32 fr)
|
|
1002
|
+
{
|
|
1003
|
+
if (compiler->scratches == -1)
|
|
1004
|
+
return 0;
|
|
1005
|
+
|
|
1006
|
+
return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->fscratches))
|
|
1007
|
+
|| (fr > (SLJIT_FS0 - compiler->fsaveds) && fr <= SLJIT_FS0)
|
|
1008
|
+
|| (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS));
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
#define FUNCTION_FCHECK(p, i, is_32) \
|
|
1012
|
+
CHECK_ARGUMENT(function_fcheck(compiler, (p), (i)));
|
|
1013
|
+
|
|
1014
|
+
static sljit_s32 function_fcheck(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
|
|
1015
|
+
{
|
|
1016
|
+
if (compiler->scratches == -1)
|
|
1017
|
+
return 0;
|
|
1018
|
+
|
|
1019
|
+
if ((p >= SLJIT_FR0 && p < (SLJIT_FR0 + compiler->fscratches))
|
|
1020
|
+
|| (p > (SLJIT_FS0 - compiler->fsaveds) && p <= SLJIT_FS0)
|
|
1021
|
+
|| (p >= SLJIT_TMP_FREGISTER_BASE && p < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)))
|
|
1022
|
+
return (i == 0);
|
|
1023
|
+
|
|
1024
|
+
return function_check_src_mem(compiler, p, i);
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
#endif /* SLJIT_CONFIG_ARM_32 || SLJIT_CONFIG_MIPS_32 */
|
|
1028
|
+
|
|
1029
|
+
#endif /* SLJIT_ARGUMENT_CHECKS */
|
|
1030
|
+
|
|
1031
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
1032
|
+
|
|
1033
|
+
SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose)
|
|
1034
|
+
{
|
|
1035
|
+
compiler->verbose = verbose;
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
|
|
1039
|
+
#ifdef _WIN64
|
|
1040
|
+
#ifdef __GNUC__
|
|
1041
|
+
# define SLJIT_PRINT_D "ll"
|
|
1042
|
+
#else
|
|
1043
|
+
# define SLJIT_PRINT_D "I64"
|
|
1044
|
+
#endif
|
|
1045
|
+
#else
|
|
1046
|
+
# define SLJIT_PRINT_D "l"
|
|
1047
|
+
#endif
|
|
1048
|
+
#else
|
|
1049
|
+
# define SLJIT_PRINT_D ""
|
|
1050
|
+
#endif
|
|
1051
|
+
|
|
1052
|
+
static void sljit_verbose_reg(struct sljit_compiler *compiler, sljit_s32 r)
|
|
1053
|
+
{
|
|
1054
|
+
if (r < (SLJIT_R0 + compiler->scratches))
|
|
1055
|
+
fprintf(compiler->verbose, "r%d", r - SLJIT_R0);
|
|
1056
|
+
else if (r < SLJIT_SP)
|
|
1057
|
+
fprintf(compiler->verbose, "s%d", SLJIT_NUMBER_OF_REGISTERS - r);
|
|
1058
|
+
else if (r == SLJIT_SP)
|
|
1059
|
+
fprintf(compiler->verbose, "sp");
|
|
1060
|
+
else
|
|
1061
|
+
fprintf(compiler->verbose, "t%d", r - SLJIT_TMP_REGISTER_BASE);
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
static void sljit_verbose_freg(struct sljit_compiler *compiler, sljit_s32 r)
|
|
1065
|
+
{
|
|
1066
|
+
#if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \
|
|
1067
|
+
|| (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
|
1068
|
+
if (r >= SLJIT_F64_SECOND(SLJIT_FR0)) {
|
|
1069
|
+
fprintf(compiler->verbose, "^");
|
|
1070
|
+
r -= SLJIT_F64_SECOND(0);
|
|
1071
|
+
}
|
|
1072
|
+
#endif /* SLJIT_CONFIG_ARM_32 || SLJIT_CONFIG_MIPS_32 */
|
|
1073
|
+
|
|
1074
|
+
if (r < (SLJIT_FR0 + compiler->fscratches))
|
|
1075
|
+
fprintf(compiler->verbose, "fr%d", r - SLJIT_FR0);
|
|
1076
|
+
else if (r < SLJIT_TMP_FREGISTER_BASE)
|
|
1077
|
+
fprintf(compiler->verbose, "fs%d", SLJIT_NUMBER_OF_FLOAT_REGISTERS - r);
|
|
1078
|
+
else
|
|
1079
|
+
fprintf(compiler->verbose, "ft%d", r - SLJIT_TMP_FREGISTER_BASE);
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
static void sljit_verbose_param(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
|
|
1083
|
+
{
|
|
1084
|
+
if ((p) == SLJIT_IMM)
|
|
1085
|
+
fprintf(compiler->verbose, "#%" SLJIT_PRINT_D "d", (i));
|
|
1086
|
+
else if ((p) & SLJIT_MEM) {
|
|
1087
|
+
if ((p) & REG_MASK) {
|
|
1088
|
+
fputc('[', compiler->verbose);
|
|
1089
|
+
sljit_verbose_reg(compiler, (p) & REG_MASK);
|
|
1090
|
+
if ((p) & OFFS_REG_MASK) {
|
|
1091
|
+
fprintf(compiler->verbose, " + ");
|
|
1092
|
+
sljit_verbose_reg(compiler, OFFS_REG(p));
|
|
1093
|
+
if (i)
|
|
1094
|
+
fprintf(compiler->verbose, " * %d", 1 << (i));
|
|
1095
|
+
}
|
|
1096
|
+
else if (i)
|
|
1097
|
+
fprintf(compiler->verbose, " + %" SLJIT_PRINT_D "d", (i));
|
|
1098
|
+
fputc(']', compiler->verbose);
|
|
1099
|
+
}
|
|
1100
|
+
else
|
|
1101
|
+
fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i));
|
|
1102
|
+
} else
|
|
1103
|
+
sljit_verbose_reg(compiler, p);
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
static void sljit_verbose_fparam(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
|
|
1107
|
+
{
|
|
1108
|
+
if ((p) & SLJIT_MEM) {
|
|
1109
|
+
if ((p) & REG_MASK) {
|
|
1110
|
+
fputc('[', compiler->verbose);
|
|
1111
|
+
sljit_verbose_reg(compiler, (p) & REG_MASK);
|
|
1112
|
+
if ((p) & OFFS_REG_MASK) {
|
|
1113
|
+
fprintf(compiler->verbose, " + ");
|
|
1114
|
+
sljit_verbose_reg(compiler, OFFS_REG(p));
|
|
1115
|
+
if (i)
|
|
1116
|
+
fprintf(compiler->verbose, "%d", 1 << (i));
|
|
1117
|
+
}
|
|
1118
|
+
else if (i)
|
|
1119
|
+
fprintf(compiler->verbose, " + %" SLJIT_PRINT_D "d", (i));
|
|
1120
|
+
fputc(']', compiler->verbose);
|
|
1121
|
+
}
|
|
1122
|
+
else
|
|
1123
|
+
fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i));
|
|
1124
|
+
}
|
|
1125
|
+
else
|
|
1126
|
+
sljit_verbose_freg(compiler, p);
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
static const char* op0_names[] = {
|
|
1130
|
+
"breakpoint", "nop", "lmul.uw", "lmul.sw",
|
|
1131
|
+
"divmod.u", "divmod.s", "div.u", "div.s",
|
|
1132
|
+
"endbr", "skip_frames_before_return"
|
|
1133
|
+
};
|
|
1134
|
+
|
|
1135
|
+
static const char* op1_names[] = {
|
|
1136
|
+
"mov", "mov", "mov", "mov",
|
|
1137
|
+
"mov", "mov", "mov", "mov",
|
|
1138
|
+
"mov", "clz", "ctz", "rev",
|
|
1139
|
+
"rev", "rev", "rev", "rev"
|
|
1140
|
+
};
|
|
1141
|
+
|
|
1142
|
+
static const char* op1_types[] = {
|
|
1143
|
+
"", ".u8", ".s8", ".u16",
|
|
1144
|
+
".s16", ".u32", ".s32", "32",
|
|
1145
|
+
".p", "", "", "",
|
|
1146
|
+
".u16", ".s16", ".u32", ".s32"
|
|
1147
|
+
};
|
|
1148
|
+
|
|
1149
|
+
static const char* op2_names[] = {
|
|
1150
|
+
"add", "addc", "sub", "subc",
|
|
1151
|
+
"mul", "and", "or", "xor",
|
|
1152
|
+
"shl", "mshl", "lshr", "mlshr",
|
|
1153
|
+
"ashr", "mashr", "rotl", "rotr"
|
|
1154
|
+
};
|
|
1155
|
+
|
|
1156
|
+
static const char* op2r_names[] = {
|
|
1157
|
+
"muladd"
|
|
1158
|
+
};
|
|
1159
|
+
|
|
1160
|
+
static const char* op_src_dst_names[] = {
|
|
1161
|
+
"fast_return", "skip_frames_before_fast_return",
|
|
1162
|
+
"prefetch_l1", "prefetch_l2",
|
|
1163
|
+
"prefetch_l3", "prefetch_once",
|
|
1164
|
+
"fast_enter", "get_return_address"
|
|
1165
|
+
};
|
|
1166
|
+
|
|
1167
|
+
static const char* fop1_names[] = {
|
|
1168
|
+
"mov", "conv", "conv", "conv",
|
|
1169
|
+
"conv", "conv", "conv", "conv",
|
|
1170
|
+
"cmp", "neg", "abs",
|
|
1171
|
+
};
|
|
1172
|
+
|
|
1173
|
+
static const char* fop1_conv_types[] = {
|
|
1174
|
+
"sw", "s32", "sw", "s32",
|
|
1175
|
+
"uw", "u32"
|
|
1176
|
+
};
|
|
1177
|
+
|
|
1178
|
+
static const char* fop2_names[] = {
|
|
1179
|
+
"add", "sub", "mul", "div"
|
|
1180
|
+
};
|
|
1181
|
+
|
|
1182
|
+
static const char* fop2r_names[] = {
|
|
1183
|
+
"copysign"
|
|
1184
|
+
};
|
|
1185
|
+
|
|
1186
|
+
static const char* simd_op2_names[] = {
|
|
1187
|
+
"and", "or", "xor"
|
|
1188
|
+
};
|
|
1189
|
+
|
|
1190
|
+
static const char* jump_names[] = {
|
|
1191
|
+
"equal", "not_equal",
|
|
1192
|
+
"less", "greater_equal",
|
|
1193
|
+
"greater", "less_equal",
|
|
1194
|
+
"sig_less", "sig_greater_equal",
|
|
1195
|
+
"sig_greater", "sig_less_equal",
|
|
1196
|
+
"overflow", "not_overflow",
|
|
1197
|
+
"carry", "not_carry",
|
|
1198
|
+
"atomic_stored", "atomic_not_stored",
|
|
1199
|
+
"f_equal", "f_not_equal",
|
|
1200
|
+
"f_less", "f_greater_equal",
|
|
1201
|
+
"f_greater", "f_less_equal",
|
|
1202
|
+
"unordered", "ordered",
|
|
1203
|
+
"ordered_equal", "unordered_or_not_equal",
|
|
1204
|
+
"ordered_less", "unordered_or_greater_equal",
|
|
1205
|
+
"ordered_greater", "unordered_or_less_equal",
|
|
1206
|
+
"unordered_or_equal", "ordered_not_equal",
|
|
1207
|
+
"unordered_or_less", "ordered_greater_equal",
|
|
1208
|
+
"unordered_or_greater", "ordered_less_equal",
|
|
1209
|
+
"jump", "fast_call",
|
|
1210
|
+
"call", "call_reg_arg"
|
|
1211
|
+
};
|
|
1212
|
+
|
|
1213
|
+
static const char* call_arg_names[] = {
|
|
1214
|
+
"void", "w", "32", "p", "f64", "f32"
|
|
1215
|
+
};
|
|
1216
|
+
|
|
1217
|
+
#endif /* SLJIT_VERBOSE */
|
|
1218
|
+
|
|
1219
|
+
/* --------------------------------------------------------------------- */
|
|
1220
|
+
/* Arch dependent */
|
|
1221
|
+
/* --------------------------------------------------------------------- */
|
|
1222
|
+
|
|
1223
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
|
|
1224
|
+
|| (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
1225
|
+
|
|
1226
|
+
#define SLJIT_SKIP_CHECKS(compiler) (compiler)->skip_checks = 1
|
|
1227
|
+
|
|
1228
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_generate_code(struct sljit_compiler *compiler)
|
|
1229
|
+
{
|
|
1230
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
1231
|
+
struct sljit_jump *jump;
|
|
1232
|
+
#endif
|
|
1233
|
+
|
|
1234
|
+
SLJIT_UNUSED_ARG(compiler);
|
|
1235
|
+
|
|
1236
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
1237
|
+
CHECK_ARGUMENT(compiler->size > 0);
|
|
1238
|
+
jump = compiler->jumps;
|
|
1239
|
+
while (jump) {
|
|
1240
|
+
/* All jumps have target. */
|
|
1241
|
+
CHECK_ARGUMENT((jump->flags & JUMP_ADDR) || jump->u.label != NULL);
|
|
1242
|
+
jump = jump->next;
|
|
1243
|
+
}
|
|
1244
|
+
#endif
|
|
1245
|
+
CHECK_RETURN_OK;
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
|
|
1249
|
+
#define SLJIT_ENTER_CPU_SPECIFIC_OPTIONS (SLJIT_ENTER_USE_VEX)
|
|
1250
|
+
#else /* !SLJIT_CONFIG_X86 */
|
|
1251
|
+
#define SLJIT_ENTER_CPU_SPECIFIC_OPTIONS (0)
|
|
1252
|
+
#endif /* !SLJIT_CONFIG_X86 */
|
|
1253
|
+
|
|
1254
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compiler *compiler,
|
|
1255
|
+
sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
|
|
1256
|
+
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
|
1257
|
+
{
|
|
1258
|
+
SLJIT_UNUSED_ARG(compiler);
|
|
1259
|
+
|
|
1260
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
1261
|
+
if (options & SLJIT_ENTER_REG_ARG) {
|
|
1262
|
+
CHECK_ARGUMENT(!(options & ~(0x3 | SLJIT_ENTER_REG_ARG | SLJIT_ENTER_CPU_SPECIFIC_OPTIONS)));
|
|
1263
|
+
} else {
|
|
1264
|
+
CHECK_ARGUMENT((options & ~SLJIT_ENTER_CPU_SPECIFIC_OPTIONS) == 0);
|
|
1265
|
+
}
|
|
1266
|
+
CHECK_ARGUMENT(SLJIT_KEPT_SAVEDS_COUNT(options) <= 3 && SLJIT_KEPT_SAVEDS_COUNT(options) <= saveds);
|
|
1267
|
+
CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS);
|
|
1268
|
+
CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS);
|
|
1269
|
+
CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS);
|
|
1270
|
+
CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
|
|
1271
|
+
CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS);
|
|
1272
|
+
CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
|
|
1273
|
+
CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
|
|
1274
|
+
CHECK_ARGUMENT((arg_types & SLJIT_ARG_FULL_MASK) <= SLJIT_ARG_TYPE_F32);
|
|
1275
|
+
CHECK_ARGUMENT(function_check_arguments(arg_types, scratches, (options & SLJIT_ENTER_REG_ARG) ? 0 : saveds, fscratches));
|
|
1276
|
+
|
|
1277
|
+
compiler->last_flags = 0;
|
|
1278
|
+
#endif
|
|
1279
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
1280
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
1281
|
+
fprintf(compiler->verbose, " enter ret[%s", call_arg_names[arg_types & SLJIT_ARG_MASK]);
|
|
1282
|
+
|
|
1283
|
+
arg_types >>= SLJIT_ARG_SHIFT;
|
|
1284
|
+
if (arg_types) {
|
|
1285
|
+
fprintf(compiler->verbose, "], args[");
|
|
1286
|
+
do {
|
|
1287
|
+
fprintf(compiler->verbose, "%s%s", call_arg_names[arg_types & SLJIT_ARG_MASK],
|
|
1288
|
+
(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG) ? "_r" : "");
|
|
1289
|
+
arg_types >>= SLJIT_ARG_SHIFT;
|
|
1290
|
+
if (arg_types)
|
|
1291
|
+
fprintf(compiler->verbose, ",");
|
|
1292
|
+
} while (arg_types);
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
fprintf(compiler->verbose, "],");
|
|
1296
|
+
|
|
1297
|
+
if (options & SLJIT_ENTER_REG_ARG) {
|
|
1298
|
+
if (SLJIT_KEPT_SAVEDS_COUNT(options) > 0)
|
|
1299
|
+
fprintf(compiler->verbose, " opt:reg_arg(%d),", SLJIT_KEPT_SAVEDS_COUNT(options));
|
|
1300
|
+
else
|
|
1301
|
+
fprintf(compiler->verbose, " opt:reg_arg,");
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
|
|
1305
|
+
if (options & SLJIT_ENTER_USE_VEX) {
|
|
1306
|
+
fprintf(compiler->verbose, " opt:use_vex,");
|
|
1307
|
+
}
|
|
1308
|
+
#endif /* !SLJIT_CONFIG_X86 */
|
|
1309
|
+
|
|
1310
|
+
fprintf(compiler->verbose, " scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, local_size:%d\n",
|
|
1311
|
+
scratches, saveds, fscratches, fsaveds, local_size);
|
|
1312
|
+
}
|
|
1313
|
+
#endif
|
|
1314
|
+
CHECK_RETURN_OK;
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1317
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compiler *compiler,
|
|
1318
|
+
sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
|
|
1319
|
+
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
|
1320
|
+
{
|
|
1321
|
+
SLJIT_UNUSED_ARG(compiler);
|
|
1322
|
+
|
|
1323
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
1324
|
+
if (options & SLJIT_ENTER_REG_ARG) {
|
|
1325
|
+
CHECK_ARGUMENT(!(options & ~(0x3 | SLJIT_ENTER_REG_ARG | SLJIT_ENTER_CPU_SPECIFIC_OPTIONS)));
|
|
1326
|
+
} else {
|
|
1327
|
+
CHECK_ARGUMENT((options & ~SLJIT_ENTER_CPU_SPECIFIC_OPTIONS) == 0);
|
|
1328
|
+
}
|
|
1329
|
+
CHECK_ARGUMENT(SLJIT_KEPT_SAVEDS_COUNT(options) <= 3 && SLJIT_KEPT_SAVEDS_COUNT(options) <= saveds);
|
|
1330
|
+
CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS);
|
|
1331
|
+
CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_SAVED_REGISTERS);
|
|
1332
|
+
CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS);
|
|
1333
|
+
CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
|
|
1334
|
+
CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS);
|
|
1335
|
+
CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
|
|
1336
|
+
CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
|
|
1337
|
+
CHECK_ARGUMENT((arg_types & SLJIT_ARG_FULL_MASK) < SLJIT_ARG_TYPE_F64);
|
|
1338
|
+
CHECK_ARGUMENT(function_check_arguments(arg_types, scratches, (options & SLJIT_ENTER_REG_ARG) ? 0 : saveds, fscratches));
|
|
1339
|
+
|
|
1340
|
+
compiler->last_flags = 0;
|
|
1341
|
+
#endif
|
|
1342
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
1343
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
1344
|
+
fprintf(compiler->verbose, " set_context ret[%s", call_arg_names[arg_types & SLJIT_ARG_MASK]);
|
|
1345
|
+
|
|
1346
|
+
arg_types >>= SLJIT_ARG_SHIFT;
|
|
1347
|
+
if (arg_types) {
|
|
1348
|
+
fprintf(compiler->verbose, "], args[");
|
|
1349
|
+
do {
|
|
1350
|
+
fprintf(compiler->verbose, "%s%s", call_arg_names[arg_types & SLJIT_ARG_MASK],
|
|
1351
|
+
(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG) ? "_r" : "");
|
|
1352
|
+
arg_types >>= SLJIT_ARG_SHIFT;
|
|
1353
|
+
if (arg_types)
|
|
1354
|
+
fprintf(compiler->verbose, ",");
|
|
1355
|
+
} while (arg_types);
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
fprintf(compiler->verbose, "],");
|
|
1359
|
+
|
|
1360
|
+
if (options & SLJIT_ENTER_REG_ARG) {
|
|
1361
|
+
if (SLJIT_KEPT_SAVEDS_COUNT(options) > 0)
|
|
1362
|
+
fprintf(compiler->verbose, " opt:reg_arg(%d),", SLJIT_KEPT_SAVEDS_COUNT(options));
|
|
1363
|
+
else
|
|
1364
|
+
fprintf(compiler->verbose, " opt:reg_arg,");
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
|
|
1368
|
+
if (options & SLJIT_ENTER_USE_VEX) {
|
|
1369
|
+
fprintf(compiler->verbose, " opt:use_vex,");
|
|
1370
|
+
}
|
|
1371
|
+
#endif /* !SLJIT_CONFIG_X86 */
|
|
1372
|
+
|
|
1373
|
+
fprintf(compiler->verbose, " scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, local_size:%d\n",
|
|
1374
|
+
scratches, saveds, fscratches, fsaveds, local_size);
|
|
1375
|
+
}
|
|
1376
|
+
#endif
|
|
1377
|
+
CHECK_RETURN_OK;
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
#undef SLJIT_ENTER_CPU_SPECIFIC_OPTIONS
|
|
1381
|
+
|
|
1382
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return_void(struct sljit_compiler *compiler)
|
|
1383
|
+
{
|
|
1384
|
+
if (SLJIT_UNLIKELY(compiler->skip_checks)) {
|
|
1385
|
+
compiler->skip_checks = 0;
|
|
1386
|
+
CHECK_RETURN_OK;
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
1390
|
+
CHECK_ARGUMENT(compiler->last_return == SLJIT_ARG_TYPE_RET_VOID);
|
|
1391
|
+
#endif
|
|
1392
|
+
|
|
1393
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
1394
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
1395
|
+
fprintf(compiler->verbose, " return_void\n");
|
|
1396
|
+
}
|
|
1397
|
+
#endif
|
|
1398
|
+
CHECK_RETURN_OK;
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
|
|
1402
|
+
{
|
|
1403
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
1404
|
+
CHECK_ARGUMENT(compiler->scratches >= 0);
|
|
1405
|
+
|
|
1406
|
+
switch (compiler->last_return) {
|
|
1407
|
+
case SLJIT_ARG_TYPE_W:
|
|
1408
|
+
CHECK_ARGUMENT(op >= SLJIT_MOV && op <= SLJIT_MOV_S32);
|
|
1409
|
+
break;
|
|
1410
|
+
case SLJIT_ARG_TYPE_32:
|
|
1411
|
+
CHECK_ARGUMENT(op == SLJIT_MOV32 || (op >= SLJIT_MOV32_U8 && op <= SLJIT_MOV32_S16));
|
|
1412
|
+
break;
|
|
1413
|
+
case SLJIT_ARG_TYPE_P:
|
|
1414
|
+
CHECK_ARGUMENT(op == SLJIT_MOV_P);
|
|
1415
|
+
break;
|
|
1416
|
+
case SLJIT_ARG_TYPE_F64:
|
|
1417
|
+
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
|
|
1418
|
+
CHECK_ARGUMENT(op == SLJIT_MOV_F64);
|
|
1419
|
+
break;
|
|
1420
|
+
case SLJIT_ARG_TYPE_F32:
|
|
1421
|
+
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
|
|
1422
|
+
CHECK_ARGUMENT(op == SLJIT_MOV_F32);
|
|
1423
|
+
break;
|
|
1424
|
+
default:
|
|
1425
|
+
/* Context not initialized, void, etc. */
|
|
1426
|
+
CHECK_ARGUMENT(0);
|
|
1427
|
+
break;
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
if (GET_OPCODE(op) < SLJIT_MOV_F64) {
|
|
1431
|
+
FUNCTION_CHECK_SRC(src, srcw);
|
|
1432
|
+
} else {
|
|
1433
|
+
FUNCTION_FCHECK(src, srcw, op & SLJIT_32);
|
|
1434
|
+
}
|
|
1435
|
+
compiler->last_flags = 0;
|
|
1436
|
+
#endif
|
|
1437
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
1438
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
1439
|
+
if (GET_OPCODE(op) < SLJIT_MOV_F64) {
|
|
1440
|
+
fprintf(compiler->verbose, " return%s%s ", !(op & SLJIT_32) ? "" : "32",
|
|
1441
|
+
op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE]);
|
|
1442
|
+
sljit_verbose_param(compiler, src, srcw);
|
|
1443
|
+
} else {
|
|
1444
|
+
fprintf(compiler->verbose, " return%s ", !(op & SLJIT_32) ? ".f64" : ".f32");
|
|
1445
|
+
sljit_verbose_fparam(compiler, src, srcw);
|
|
1446
|
+
}
|
|
1447
|
+
fprintf(compiler->verbose, "\n");
|
|
1448
|
+
}
|
|
1449
|
+
#endif
|
|
1450
|
+
CHECK_RETURN_OK;
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return_to(struct sljit_compiler *compiler,
|
|
1454
|
+
sljit_s32 src, sljit_sw srcw)
|
|
1455
|
+
{
|
|
1456
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
1457
|
+
FUNCTION_CHECK_SRC(src, srcw);
|
|
1458
|
+
#endif
|
|
1459
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
1460
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
1461
|
+
fprintf(compiler->verbose, " return_to ");
|
|
1462
|
+
sljit_verbose_param(compiler, src, srcw);
|
|
1463
|
+
fprintf(compiler->verbose, "\n");
|
|
1464
|
+
}
|
|
1465
|
+
#endif
|
|
1466
|
+
CHECK_RETURN_OK;
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1469
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
|
|
1470
|
+
{
|
|
1471
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
1472
|
+
CHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LMUL_SW)
|
|
1473
|
+
|| ((op & ~SLJIT_32) >= SLJIT_DIVMOD_UW && (op & ~SLJIT_32) <= SLJIT_DIV_SW)
|
|
1474
|
+
|| (op >= SLJIT_ENDBR && op <= SLJIT_SKIP_FRAMES_BEFORE_RETURN));
|
|
1475
|
+
CHECK_ARGUMENT(GET_OPCODE(op) < SLJIT_LMUL_UW || GET_OPCODE(op) >= SLJIT_ENDBR || compiler->scratches >= 2);
|
|
1476
|
+
if ((GET_OPCODE(op) >= SLJIT_LMUL_UW && GET_OPCODE(op) <= SLJIT_DIV_SW) || op == SLJIT_SKIP_FRAMES_BEFORE_RETURN)
|
|
1477
|
+
compiler->last_flags = 0;
|
|
1478
|
+
#endif
|
|
1479
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
1480
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose))
|
|
1481
|
+
{
|
|
1482
|
+
fprintf(compiler->verbose, " %s", op0_names[GET_OPCODE(op) - SLJIT_OP0_BASE]);
|
|
1483
|
+
if (GET_OPCODE(op) >= SLJIT_DIVMOD_UW && GET_OPCODE(op) <= SLJIT_DIV_SW) {
|
|
1484
|
+
fprintf(compiler->verbose, (op & SLJIT_32) ? "32" : "w");
|
|
1485
|
+
}
|
|
1486
|
+
fprintf(compiler->verbose, "\n");
|
|
1487
|
+
}
|
|
1488
|
+
#endif
|
|
1489
|
+
CHECK_RETURN_OK;
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1492
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
|
|
1493
|
+
sljit_s32 dst, sljit_sw dstw,
|
|
1494
|
+
sljit_s32 src, sljit_sw srcw)
|
|
1495
|
+
{
|
|
1496
|
+
if (SLJIT_UNLIKELY(compiler->skip_checks)) {
|
|
1497
|
+
compiler->skip_checks = 0;
|
|
1498
|
+
CHECK_RETURN_OK;
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
1502
|
+
CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_REV_S32);
|
|
1503
|
+
|
|
1504
|
+
switch (GET_OPCODE(op)) {
|
|
1505
|
+
case SLJIT_MOV:
|
|
1506
|
+
case SLJIT_MOV_U32:
|
|
1507
|
+
case SLJIT_MOV_S32:
|
|
1508
|
+
case SLJIT_MOV32:
|
|
1509
|
+
case SLJIT_MOV_P:
|
|
1510
|
+
case SLJIT_REV_U32:
|
|
1511
|
+
case SLJIT_REV_S32:
|
|
1512
|
+
/* Nothing allowed */
|
|
1513
|
+
CHECK_ARGUMENT(!(op & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
|
|
1514
|
+
break;
|
|
1515
|
+
default:
|
|
1516
|
+
/* Only SLJIT_32 is allowed. */
|
|
1517
|
+
CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
|
|
1518
|
+
break;
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
FUNCTION_CHECK_DST(dst, dstw);
|
|
1522
|
+
FUNCTION_CHECK_SRC(src, srcw);
|
|
1523
|
+
#endif
|
|
1524
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
1525
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
1526
|
+
fprintf(compiler->verbose, " %s%s%s ", op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE],
|
|
1527
|
+
!(op & SLJIT_32) ? "" : "32", op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE]);
|
|
1528
|
+
|
|
1529
|
+
sljit_verbose_param(compiler, dst, dstw);
|
|
1530
|
+
fprintf(compiler->verbose, ", ");
|
|
1531
|
+
sljit_verbose_param(compiler, src, srcw);
|
|
1532
|
+
fprintf(compiler->verbose, "\n");
|
|
1533
|
+
}
|
|
1534
|
+
#endif
|
|
1535
|
+
CHECK_RETURN_OK;
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op,
|
|
1539
|
+
sljit_s32 dst_reg,
|
|
1540
|
+
sljit_s32 mem_reg)
|
|
1541
|
+
{
|
|
1542
|
+
if (SLJIT_UNLIKELY(compiler->skip_checks)) {
|
|
1543
|
+
compiler->skip_checks = 0;
|
|
1544
|
+
CHECK_RETURN_OK;
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1547
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
1548
|
+
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_ATOMIC));
|
|
1549
|
+
CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOV_P);
|
|
1550
|
+
CHECK_ARGUMENT(GET_OPCODE(op) != SLJIT_MOV_S8 && GET_OPCODE(op) != SLJIT_MOV_S16 && GET_OPCODE(op) != SLJIT_MOV_S32);
|
|
1551
|
+
|
|
1552
|
+
/* All arguments must be valid registers. */
|
|
1553
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg));
|
|
1554
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(mem_reg) && !CHECK_IF_VIRTUAL_REGISTER(mem_reg));
|
|
1555
|
+
|
|
1556
|
+
if (op == SLJIT_MOV32_U8 || op == SLJIT_MOV32_U16) {
|
|
1557
|
+
/* Only SLJIT_32 is allowed. */
|
|
1558
|
+
CHECK_ARGUMENT(!(op & (VARIABLE_FLAG_MASK | SLJIT_SET_Z)));
|
|
1559
|
+
} else {
|
|
1560
|
+
/* Nothing allowed. */
|
|
1561
|
+
CHECK_ARGUMENT(!(op & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1564
|
+
compiler->last_flags = 0;
|
|
1565
|
+
#endif /* SLJIT_ARGUMENT_CHECKS */
|
|
1566
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
1567
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
1568
|
+
fprintf(compiler->verbose, " atomic_load%s%s ", !(op & SLJIT_32) ? "" : "32",
|
|
1569
|
+
op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE]);
|
|
1570
|
+
sljit_verbose_reg(compiler, dst_reg);
|
|
1571
|
+
fprintf(compiler->verbose, ", [");
|
|
1572
|
+
sljit_verbose_reg(compiler, mem_reg);
|
|
1573
|
+
fprintf(compiler->verbose, "]\n");
|
|
1574
|
+
}
|
|
1575
|
+
#endif /* SLJIT_VERBOSE */
|
|
1576
|
+
CHECK_RETURN_OK;
|
|
1577
|
+
}
|
|
1578
|
+
|
|
1579
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op,
|
|
1580
|
+
sljit_s32 src_reg,
|
|
1581
|
+
sljit_s32 mem_reg,
|
|
1582
|
+
sljit_s32 temp_reg)
|
|
1583
|
+
{
|
|
1584
|
+
if (SLJIT_UNLIKELY(compiler->skip_checks)) {
|
|
1585
|
+
compiler->skip_checks = 0;
|
|
1586
|
+
CHECK_RETURN_OK;
|
|
1587
|
+
}
|
|
1588
|
+
|
|
1589
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
1590
|
+
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_ATOMIC));
|
|
1591
|
+
CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOV_P);
|
|
1592
|
+
CHECK_ARGUMENT(GET_OPCODE(op) != SLJIT_MOV_S8 && GET_OPCODE(op) != SLJIT_MOV_S16 && GET_OPCODE(op) != SLJIT_MOV_S32);
|
|
1593
|
+
|
|
1594
|
+
/* All arguments must be valid registers. */
|
|
1595
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src_reg));
|
|
1596
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(mem_reg) && !CHECK_IF_VIRTUAL_REGISTER(mem_reg));
|
|
1597
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(temp_reg) && src_reg != temp_reg);
|
|
1598
|
+
|
|
1599
|
+
CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK) || GET_FLAG_TYPE(op) == SLJIT_ATOMIC_STORED);
|
|
1600
|
+
|
|
1601
|
+
if (GET_OPCODE(op) == SLJIT_MOV_U8 || GET_OPCODE(op) == SLJIT_MOV_U16) {
|
|
1602
|
+
/* Only SLJIT_32, SLJIT_ATOMIC_STORED are allowed. */
|
|
1603
|
+
CHECK_ARGUMENT(!(op & SLJIT_SET_Z));
|
|
1604
|
+
} else {
|
|
1605
|
+
/* Only SLJIT_ATOMIC_STORED is allowed. */
|
|
1606
|
+
CHECK_ARGUMENT(!(op & (SLJIT_32 | SLJIT_SET_Z)));
|
|
1607
|
+
}
|
|
1608
|
+
|
|
1609
|
+
compiler->last_flags = GET_FLAG_TYPE(op) | (op & SLJIT_32);
|
|
1610
|
+
#endif /* SLJIT_ARGUMENT_CHECKS */
|
|
1611
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
1612
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
1613
|
+
fprintf(compiler->verbose, " atomic_store%s%s%s ", !(op & SLJIT_32) ? "" : "32",
|
|
1614
|
+
op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE], !(op & VARIABLE_FLAG_MASK) ? "" : ".stored");
|
|
1615
|
+
sljit_verbose_reg(compiler, src_reg);
|
|
1616
|
+
fprintf(compiler->verbose, ", [");
|
|
1617
|
+
sljit_verbose_reg(compiler, mem_reg);
|
|
1618
|
+
fprintf(compiler->verbose, "], ");
|
|
1619
|
+
sljit_verbose_reg(compiler, temp_reg);
|
|
1620
|
+
fprintf(compiler->verbose, "\n");
|
|
1621
|
+
}
|
|
1622
|
+
#endif /* SLJIT_VERBOSE */
|
|
1623
|
+
CHECK_RETURN_OK;
|
|
1624
|
+
}
|
|
1625
|
+
|
|
1626
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 unset,
|
|
1627
|
+
sljit_s32 dst, sljit_sw dstw,
|
|
1628
|
+
sljit_s32 src1, sljit_sw src1w,
|
|
1629
|
+
sljit_s32 src2, sljit_sw src2w)
|
|
1630
|
+
{
|
|
1631
|
+
if (SLJIT_UNLIKELY(compiler->skip_checks)) {
|
|
1632
|
+
compiler->skip_checks = 0;
|
|
1633
|
+
CHECK_RETURN_OK;
|
|
1634
|
+
}
|
|
1635
|
+
|
|
1636
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
1637
|
+
CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD && GET_OPCODE(op) <= SLJIT_ROTR);
|
|
1638
|
+
|
|
1639
|
+
switch (GET_OPCODE(op)) {
|
|
1640
|
+
case SLJIT_AND:
|
|
1641
|
+
case SLJIT_OR:
|
|
1642
|
+
case SLJIT_XOR:
|
|
1643
|
+
case SLJIT_SHL:
|
|
1644
|
+
case SLJIT_MSHL:
|
|
1645
|
+
case SLJIT_LSHR:
|
|
1646
|
+
case SLJIT_MLSHR:
|
|
1647
|
+
case SLJIT_ASHR:
|
|
1648
|
+
case SLJIT_MASHR:
|
|
1649
|
+
CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK));
|
|
1650
|
+
break;
|
|
1651
|
+
case SLJIT_MUL:
|
|
1652
|
+
CHECK_ARGUMENT(!(op & SLJIT_SET_Z));
|
|
1653
|
+
CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
|
|
1654
|
+
|| GET_FLAG_TYPE(op) == SLJIT_OVERFLOW);
|
|
1655
|
+
break;
|
|
1656
|
+
case SLJIT_ADD:
|
|
1657
|
+
CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
|
|
1658
|
+
|| GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY)
|
|
1659
|
+
|| GET_FLAG_TYPE(op) == SLJIT_OVERFLOW);
|
|
1660
|
+
break;
|
|
1661
|
+
case SLJIT_SUB:
|
|
1662
|
+
CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
|
|
1663
|
+
|| (GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_OVERFLOW)
|
|
1664
|
+
|| GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY));
|
|
1665
|
+
break;
|
|
1666
|
+
case SLJIT_ADDC:
|
|
1667
|
+
case SLJIT_SUBC:
|
|
1668
|
+
CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
|
|
1669
|
+
|| GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY));
|
|
1670
|
+
CHECK_ARGUMENT((compiler->last_flags & 0xff) == GET_FLAG_TYPE(SLJIT_SET_CARRY));
|
|
1671
|
+
CHECK_ARGUMENT((op & SLJIT_32) == (compiler->last_flags & SLJIT_32));
|
|
1672
|
+
break;
|
|
1673
|
+
case SLJIT_ROTL:
|
|
1674
|
+
case SLJIT_ROTR:
|
|
1675
|
+
CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
|
|
1676
|
+
break;
|
|
1677
|
+
default:
|
|
1678
|
+
SLJIT_UNREACHABLE();
|
|
1679
|
+
break;
|
|
1680
|
+
}
|
|
1681
|
+
|
|
1682
|
+
if (unset) {
|
|
1683
|
+
CHECK_ARGUMENT(HAS_FLAGS(op));
|
|
1684
|
+
} else {
|
|
1685
|
+
FUNCTION_CHECK_DST(dst, dstw);
|
|
1686
|
+
}
|
|
1687
|
+
FUNCTION_CHECK_SRC(src1, src1w);
|
|
1688
|
+
FUNCTION_CHECK_SRC(src2, src2w);
|
|
1689
|
+
compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_32 | SLJIT_SET_Z));
|
|
1690
|
+
#endif
|
|
1691
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
1692
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
1693
|
+
fprintf(compiler->verbose, " %s%s%s%s%s ", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_32) ? "" : "32",
|
|
1694
|
+
!(op & SLJIT_SET_Z) ? "" : ".z", !(op & VARIABLE_FLAG_MASK) ? "" : ".",
|
|
1695
|
+
!(op & VARIABLE_FLAG_MASK) ? "" : jump_names[GET_FLAG_TYPE(op)]);
|
|
1696
|
+
if (unset)
|
|
1697
|
+
fprintf(compiler->verbose, "unset");
|
|
1698
|
+
else
|
|
1699
|
+
sljit_verbose_param(compiler, dst, dstw);
|
|
1700
|
+
fprintf(compiler->verbose, ", ");
|
|
1701
|
+
sljit_verbose_param(compiler, src1, src1w);
|
|
1702
|
+
fprintf(compiler->verbose, ", ");
|
|
1703
|
+
sljit_verbose_param(compiler, src2, src2w);
|
|
1704
|
+
fprintf(compiler->verbose, "\n");
|
|
1705
|
+
}
|
|
1706
|
+
#endif
|
|
1707
|
+
CHECK_RETURN_OK;
|
|
1708
|
+
}
|
|
1709
|
+
|
|
1710
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,
|
|
1711
|
+
sljit_s32 dst_reg,
|
|
1712
|
+
sljit_s32 src1, sljit_sw src1w,
|
|
1713
|
+
sljit_s32 src2, sljit_sw src2w)
|
|
1714
|
+
{
|
|
1715
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
1716
|
+
CHECK_ARGUMENT((op | SLJIT_32) == SLJIT_MULADD32);
|
|
1717
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg));
|
|
1718
|
+
FUNCTION_CHECK_SRC(src1, src1w);
|
|
1719
|
+
FUNCTION_CHECK_SRC(src2, src2w);
|
|
1720
|
+
compiler->last_flags = 0;
|
|
1721
|
+
#endif
|
|
1722
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
1723
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
1724
|
+
fprintf(compiler->verbose, " %s%s ", op2r_names[GET_OPCODE(op) - SLJIT_OP2R_BASE], !(op & SLJIT_32) ? "" : "32");
|
|
1725
|
+
|
|
1726
|
+
sljit_verbose_reg(compiler, dst_reg);
|
|
1727
|
+
fprintf(compiler->verbose, ", ");
|
|
1728
|
+
sljit_verbose_param(compiler, src1, src1w);
|
|
1729
|
+
fprintf(compiler->verbose, ", ");
|
|
1730
|
+
sljit_verbose_param(compiler, src2, src2w);
|
|
1731
|
+
fprintf(compiler->verbose, "\n");
|
|
1732
|
+
}
|
|
1733
|
+
#endif
|
|
1734
|
+
CHECK_RETURN_OK;
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
|
|
1738
|
+
sljit_s32 dst_reg,
|
|
1739
|
+
sljit_s32 src1_reg,
|
|
1740
|
+
sljit_s32 src2_reg,
|
|
1741
|
+
sljit_s32 src3, sljit_sw src3w)
|
|
1742
|
+
{
|
|
1743
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
1744
|
+
CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_LSHR
|
|
1745
|
+
|| GET_OPCODE(op) == SLJIT_MSHL || GET_OPCODE(op) == SLJIT_MLSHR);
|
|
1746
|
+
CHECK_ARGUMENT((op & ~(0xff | SLJIT_32 | SLJIT_SHIFT_INTO_NON_ZERO)) == 0);
|
|
1747
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg));
|
|
1748
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src1_reg));
|
|
1749
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src2_reg));
|
|
1750
|
+
FUNCTION_CHECK_SRC(src3, src3w);
|
|
1751
|
+
CHECK_ARGUMENT(dst_reg != src2_reg);
|
|
1752
|
+
#endif
|
|
1753
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
1754
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
1755
|
+
fprintf(compiler->verbose, " %s%s.into%s ", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_32) ? "" : "32",
|
|
1756
|
+
(op & SLJIT_SHIFT_INTO_NON_ZERO) ? ".nz" : "");
|
|
1757
|
+
|
|
1758
|
+
sljit_verbose_reg(compiler, dst_reg);
|
|
1759
|
+
fprintf(compiler->verbose, ", ");
|
|
1760
|
+
sljit_verbose_reg(compiler, src1_reg);
|
|
1761
|
+
fprintf(compiler->verbose, ", ");
|
|
1762
|
+
sljit_verbose_reg(compiler, src2_reg);
|
|
1763
|
+
fprintf(compiler->verbose, ", ");
|
|
1764
|
+
sljit_verbose_param(compiler, src3, src3w);
|
|
1765
|
+
fprintf(compiler->verbose, "\n");
|
|
1766
|
+
}
|
|
1767
|
+
#endif
|
|
1768
|
+
CHECK_RETURN_OK;
|
|
1769
|
+
}
|
|
1770
|
+
|
|
1771
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
|
|
1772
|
+
sljit_s32 src, sljit_sw srcw)
|
|
1773
|
+
{
|
|
1774
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
1775
|
+
CHECK_ARGUMENT(op >= SLJIT_FAST_RETURN && op <= SLJIT_PREFETCH_ONCE);
|
|
1776
|
+
FUNCTION_CHECK_SRC(src, srcw);
|
|
1777
|
+
|
|
1778
|
+
if (op == SLJIT_FAST_RETURN || op == SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN) {
|
|
1779
|
+
CHECK_ARGUMENT(src != SLJIT_IMM);
|
|
1780
|
+
compiler->last_flags = 0;
|
|
1781
|
+
} else if (op >= SLJIT_PREFETCH_L1 && op <= SLJIT_PREFETCH_ONCE) {
|
|
1782
|
+
CHECK_ARGUMENT(src & SLJIT_MEM);
|
|
1783
|
+
}
|
|
1784
|
+
#endif
|
|
1785
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
1786
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
1787
|
+
fprintf(compiler->verbose, " %s ", op_src_dst_names[op - SLJIT_OP_SRC_DST_BASE]);
|
|
1788
|
+
sljit_verbose_param(compiler, src, srcw);
|
|
1789
|
+
fprintf(compiler->verbose, "\n");
|
|
1790
|
+
}
|
|
1791
|
+
#endif
|
|
1792
|
+
CHECK_RETURN_OK;
|
|
1793
|
+
}
|
|
1794
|
+
|
|
1795
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op,
|
|
1796
|
+
sljit_s32 dst, sljit_sw dstw)
|
|
1797
|
+
{
|
|
1798
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
1799
|
+
CHECK_ARGUMENT(op >= SLJIT_FAST_ENTER && op <= SLJIT_GET_RETURN_ADDRESS);
|
|
1800
|
+
FUNCTION_CHECK_DST(dst, dstw);
|
|
1801
|
+
|
|
1802
|
+
if (op == SLJIT_FAST_ENTER)
|
|
1803
|
+
compiler->last_flags = 0;
|
|
1804
|
+
#endif
|
|
1805
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
1806
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
1807
|
+
fprintf(compiler->verbose, " %s ", op_src_dst_names[op - SLJIT_OP_SRC_DST_BASE]);
|
|
1808
|
+
sljit_verbose_param(compiler, dst, dstw);
|
|
1809
|
+
fprintf(compiler->verbose, "\n");
|
|
1810
|
+
}
|
|
1811
|
+
#endif
|
|
1812
|
+
CHECK_RETURN_OK;
|
|
1813
|
+
}
|
|
1814
|
+
|
|
1815
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_s32 type, sljit_s32 reg)
|
|
1816
|
+
{
|
|
1817
|
+
SLJIT_UNUSED_ARG(type);
|
|
1818
|
+
SLJIT_UNUSED_ARG(reg);
|
|
1819
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
1820
|
+
if (type == SLJIT_GP_REGISTER) {
|
|
1821
|
+
CHECK_ARGUMENT((reg > 0 && reg <= SLJIT_NUMBER_OF_REGISTERS)
|
|
1822
|
+
|| (reg >= SLJIT_TMP_REGISTER_BASE && reg < (SLJIT_TMP_REGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_REGISTERS)));
|
|
1823
|
+
} else {
|
|
1824
|
+
CHECK_ARGUMENT(type == SLJIT_FLOAT_REGISTER || ((type >> 12) == 0 || ((type >> 12) >= 3 && (type >> 12) <= 6)));
|
|
1825
|
+
CHECK_ARGUMENT((reg > 0 && reg <= SLJIT_NUMBER_OF_FLOAT_REGISTERS)
|
|
1826
|
+
|| (reg >= SLJIT_TMP_FREGISTER_BASE && reg < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)));
|
|
1827
|
+
}
|
|
1828
|
+
#endif
|
|
1829
|
+
CHECK_RETURN_OK;
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1832
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_compiler *compiler,
|
|
1833
|
+
void *instruction, sljit_u32 size)
|
|
1834
|
+
{
|
|
1835
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
1836
|
+
sljit_u32 i;
|
|
1837
|
+
#endif
|
|
1838
|
+
|
|
1839
|
+
SLJIT_UNUSED_ARG(compiler);
|
|
1840
|
+
|
|
1841
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
1842
|
+
CHECK_ARGUMENT(instruction);
|
|
1843
|
+
|
|
1844
|
+
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
|
|
1845
|
+
CHECK_ARGUMENT(size > 0 && size < 16);
|
|
1846
|
+
#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
|
|
1847
|
+
CHECK_ARGUMENT((size == 2 && (((sljit_sw)instruction) & 0x1) == 0)
|
|
1848
|
+
|| (size == 4 && (((sljit_sw)instruction) & 0x3) == 0));
|
|
1849
|
+
#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
|
|
1850
|
+
CHECK_ARGUMENT(size == 2 || size == 4 || size == 6);
|
|
1851
|
+
#else
|
|
1852
|
+
CHECK_ARGUMENT(size == 4 && (((sljit_sw)instruction) & 0x3) == 0);
|
|
1853
|
+
#endif
|
|
1854
|
+
|
|
1855
|
+
compiler->last_flags = 0;
|
|
1856
|
+
#endif
|
|
1857
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
1858
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
1859
|
+
fprintf(compiler->verbose, " op_custom");
|
|
1860
|
+
for (i = 0; i < size; i++)
|
|
1861
|
+
fprintf(compiler->verbose, " 0x%x", ((sljit_u8*)instruction)[i]);
|
|
1862
|
+
fprintf(compiler->verbose, "\n");
|
|
1863
|
+
}
|
|
1864
|
+
#endif
|
|
1865
|
+
CHECK_RETURN_OK;
|
|
1866
|
+
}
|
|
1867
|
+
|
|
1868
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
|
|
1869
|
+
sljit_s32 dst, sljit_sw dstw,
|
|
1870
|
+
sljit_s32 src, sljit_sw srcw)
|
|
1871
|
+
{
|
|
1872
|
+
if (SLJIT_UNLIKELY(compiler->skip_checks)) {
|
|
1873
|
+
compiler->skip_checks = 0;
|
|
1874
|
+
CHECK_RETURN_OK;
|
|
1875
|
+
}
|
|
1876
|
+
|
|
1877
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
1878
|
+
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
|
|
1879
|
+
CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV_F64 && GET_OPCODE(op) <= SLJIT_ABS_F64);
|
|
1880
|
+
CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
|
|
1881
|
+
FUNCTION_FCHECK(src, srcw, op & SLJIT_32);
|
|
1882
|
+
FUNCTION_FCHECK(dst, dstw, op & SLJIT_32);
|
|
1883
|
+
#endif
|
|
1884
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
1885
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
1886
|
+
if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
|
|
1887
|
+
fprintf(compiler->verbose, " %s%s ", fop1_names[SLJIT_CONV_F64_FROM_F32 - SLJIT_FOP1_BASE],
|
|
1888
|
+
(op & SLJIT_32) ? ".f32.from.f64" : ".f64.from.f32");
|
|
1889
|
+
else
|
|
1890
|
+
fprintf(compiler->verbose, " %s%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],
|
|
1891
|
+
(op & SLJIT_32) ? ".f32" : ".f64");
|
|
1892
|
+
|
|
1893
|
+
sljit_verbose_fparam(compiler, dst, dstw);
|
|
1894
|
+
fprintf(compiler->verbose, ", ");
|
|
1895
|
+
sljit_verbose_fparam(compiler, src, srcw);
|
|
1896
|
+
fprintf(compiler->verbose, "\n");
|
|
1897
|
+
}
|
|
1898
|
+
#endif
|
|
1899
|
+
CHECK_RETURN_OK;
|
|
1900
|
+
}
|
|
1901
|
+
|
|
1902
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op,
|
|
1903
|
+
sljit_s32 src1, sljit_sw src1w,
|
|
1904
|
+
sljit_s32 src2, sljit_sw src2w)
|
|
1905
|
+
{
|
|
1906
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
1907
|
+
compiler->last_flags = GET_FLAG_TYPE(op) | (op & SLJIT_32);
|
|
1908
|
+
#endif
|
|
1909
|
+
|
|
1910
|
+
if (SLJIT_UNLIKELY(compiler->skip_checks)) {
|
|
1911
|
+
compiler->skip_checks = 0;
|
|
1912
|
+
CHECK_RETURN_OK;
|
|
1913
|
+
}
|
|
1914
|
+
|
|
1915
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
1916
|
+
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
|
|
1917
|
+
CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_CMP_F64);
|
|
1918
|
+
CHECK_ARGUMENT(!(op & SLJIT_SET_Z));
|
|
1919
|
+
CHECK_ARGUMENT((op & VARIABLE_FLAG_MASK)
|
|
1920
|
+
|| (GET_FLAG_TYPE(op) >= SLJIT_F_EQUAL && GET_FLAG_TYPE(op) <= SLJIT_ORDERED_LESS_EQUAL));
|
|
1921
|
+
FUNCTION_FCHECK(src1, src1w, op & SLJIT_32);
|
|
1922
|
+
FUNCTION_FCHECK(src2, src2w, op & SLJIT_32);
|
|
1923
|
+
#endif
|
|
1924
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
1925
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
1926
|
+
fprintf(compiler->verbose, " %s%s", fop1_names[SLJIT_CMP_F64 - SLJIT_FOP1_BASE], (op & SLJIT_32) ? ".f32" : ".f64");
|
|
1927
|
+
if (op & VARIABLE_FLAG_MASK) {
|
|
1928
|
+
fprintf(compiler->verbose, ".%s", jump_names[GET_FLAG_TYPE(op)]);
|
|
1929
|
+
}
|
|
1930
|
+
fprintf(compiler->verbose, " ");
|
|
1931
|
+
sljit_verbose_fparam(compiler, src1, src1w);
|
|
1932
|
+
fprintf(compiler->verbose, ", ");
|
|
1933
|
+
sljit_verbose_fparam(compiler, src2, src2w);
|
|
1934
|
+
fprintf(compiler->verbose, "\n");
|
|
1935
|
+
}
|
|
1936
|
+
#endif
|
|
1937
|
+
CHECK_RETURN_OK;
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1940
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
|
|
1941
|
+
sljit_s32 dst, sljit_sw dstw,
|
|
1942
|
+
sljit_s32 src, sljit_sw srcw)
|
|
1943
|
+
{
|
|
1944
|
+
if (SLJIT_UNLIKELY(compiler->skip_checks)) {
|
|
1945
|
+
compiler->skip_checks = 0;
|
|
1946
|
+
CHECK_RETURN_OK;
|
|
1947
|
+
}
|
|
1948
|
+
|
|
1949
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
1950
|
+
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
|
|
1951
|
+
CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
|
|
1952
|
+
FUNCTION_FCHECK(src, srcw, op & SLJIT_32);
|
|
1953
|
+
FUNCTION_CHECK_DST(dst, dstw);
|
|
1954
|
+
#endif
|
|
1955
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
1956
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
1957
|
+
fprintf(compiler->verbose, " %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],
|
|
1958
|
+
fop1_conv_types[GET_OPCODE(op) - SLJIT_CONV_SW_FROM_F64],
|
|
1959
|
+
(op & SLJIT_32) ? ".f32" : ".f64");
|
|
1960
|
+
sljit_verbose_param(compiler, dst, dstw);
|
|
1961
|
+
fprintf(compiler->verbose, ", ");
|
|
1962
|
+
sljit_verbose_fparam(compiler, src, srcw);
|
|
1963
|
+
fprintf(compiler->verbose, "\n");
|
|
1964
|
+
}
|
|
1965
|
+
#endif
|
|
1966
|
+
CHECK_RETURN_OK;
|
|
1967
|
+
}
|
|
1968
|
+
|
|
1969
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_f64_from_w(struct sljit_compiler *compiler, sljit_s32 op,
|
|
1970
|
+
sljit_s32 dst, sljit_sw dstw,
|
|
1971
|
+
sljit_s32 src, sljit_sw srcw)
|
|
1972
|
+
{
|
|
1973
|
+
if (SLJIT_UNLIKELY(compiler->skip_checks)) {
|
|
1974
|
+
compiler->skip_checks = 0;
|
|
1975
|
+
CHECK_RETURN_OK;
|
|
1976
|
+
}
|
|
1977
|
+
|
|
1978
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
1979
|
+
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
|
|
1980
|
+
CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
|
|
1981
|
+
FUNCTION_CHECK_SRC(src, srcw);
|
|
1982
|
+
FUNCTION_FCHECK(dst, dstw, op & SLJIT_32);
|
|
1983
|
+
#endif
|
|
1984
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
1985
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
1986
|
+
fprintf(compiler->verbose, " %s%s.from.%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE],
|
|
1987
|
+
(op & SLJIT_32) ? ".f32" : ".f64",
|
|
1988
|
+
fop1_conv_types[GET_OPCODE(op) - SLJIT_CONV_SW_FROM_F64]);
|
|
1989
|
+
sljit_verbose_fparam(compiler, dst, dstw);
|
|
1990
|
+
fprintf(compiler->verbose, ", ");
|
|
1991
|
+
sljit_verbose_param(compiler, src, srcw);
|
|
1992
|
+
fprintf(compiler->verbose, "\n");
|
|
1993
|
+
}
|
|
1994
|
+
#endif
|
|
1995
|
+
CHECK_RETURN_OK;
|
|
1996
|
+
}
|
|
1997
|
+
|
|
1998
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
|
|
1999
|
+
sljit_s32 dst, sljit_sw dstw,
|
|
2000
|
+
sljit_s32 src1, sljit_sw src1w,
|
|
2001
|
+
sljit_s32 src2, sljit_sw src2w)
|
|
2002
|
+
{
|
|
2003
|
+
if (SLJIT_UNLIKELY(compiler->skip_checks)) {
|
|
2004
|
+
compiler->skip_checks = 0;
|
|
2005
|
+
CHECK_RETURN_OK;
|
|
2006
|
+
}
|
|
2007
|
+
|
|
2008
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2009
|
+
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
|
|
2010
|
+
CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD_F64 && GET_OPCODE(op) <= SLJIT_DIV_F64);
|
|
2011
|
+
CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
|
|
2012
|
+
FUNCTION_FCHECK(src1, src1w, op & SLJIT_32);
|
|
2013
|
+
FUNCTION_FCHECK(src2, src2w, op & SLJIT_32);
|
|
2014
|
+
FUNCTION_FCHECK(dst, dstw, op & SLJIT_32);
|
|
2015
|
+
#endif
|
|
2016
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2017
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
2018
|
+
fprintf(compiler->verbose, " %s%s ", fop2_names[GET_OPCODE(op) - SLJIT_FOP2_BASE], (op & SLJIT_32) ? ".f32" : ".f64");
|
|
2019
|
+
sljit_verbose_fparam(compiler, dst, dstw);
|
|
2020
|
+
fprintf(compiler->verbose, ", ");
|
|
2021
|
+
sljit_verbose_fparam(compiler, src1, src1w);
|
|
2022
|
+
fprintf(compiler->verbose, ", ");
|
|
2023
|
+
sljit_verbose_fparam(compiler, src2, src2w);
|
|
2024
|
+
fprintf(compiler->verbose, "\n");
|
|
2025
|
+
}
|
|
2026
|
+
#endif
|
|
2027
|
+
CHECK_RETURN_OK;
|
|
2028
|
+
}
|
|
2029
|
+
|
|
2030
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2r(struct sljit_compiler *compiler, sljit_s32 op,
|
|
2031
|
+
sljit_s32 dst_freg,
|
|
2032
|
+
sljit_s32 src1, sljit_sw src1w,
|
|
2033
|
+
sljit_s32 src2, sljit_sw src2w)
|
|
2034
|
+
{
|
|
2035
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2036
|
+
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
|
|
2037
|
+
CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_COPYSIGN_F64);
|
|
2038
|
+
FUNCTION_FCHECK(src1, src1w, op & SLJIT_32);
|
|
2039
|
+
FUNCTION_FCHECK(src2, src2w, op & SLJIT_32);
|
|
2040
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(dst_freg, op & SLJIT_32));
|
|
2041
|
+
#endif
|
|
2042
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2043
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
2044
|
+
fprintf(compiler->verbose, " %s%s ", fop2r_names[GET_OPCODE(op) - SLJIT_FOP2R_BASE], (op & SLJIT_32) ? ".f32" : ".f64");
|
|
2045
|
+
sljit_verbose_freg(compiler, dst_freg);
|
|
2046
|
+
fprintf(compiler->verbose, ", ");
|
|
2047
|
+
sljit_verbose_fparam(compiler, src1, src1w);
|
|
2048
|
+
fprintf(compiler->verbose, ", ");
|
|
2049
|
+
sljit_verbose_fparam(compiler, src2, src2w);
|
|
2050
|
+
fprintf(compiler->verbose, "\n");
|
|
2051
|
+
}
|
|
2052
|
+
#endif
|
|
2053
|
+
CHECK_RETURN_OK;
|
|
2054
|
+
}
|
|
2055
|
+
|
|
2056
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fset32(struct sljit_compiler *compiler,
|
|
2057
|
+
sljit_s32 freg, sljit_f32 value)
|
|
2058
|
+
{
|
|
2059
|
+
SLJIT_UNUSED_ARG(value);
|
|
2060
|
+
|
|
2061
|
+
if (SLJIT_UNLIKELY(compiler->skip_checks)) {
|
|
2062
|
+
compiler->skip_checks = 0;
|
|
2063
|
+
CHECK_RETURN_OK;
|
|
2064
|
+
}
|
|
2065
|
+
|
|
2066
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2067
|
+
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
|
|
2068
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 1));
|
|
2069
|
+
#endif
|
|
2070
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2071
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
2072
|
+
fprintf(compiler->verbose, " fset32 ");
|
|
2073
|
+
sljit_verbose_freg(compiler, freg);
|
|
2074
|
+
fprintf(compiler->verbose, ", %f\n", value);
|
|
2075
|
+
}
|
|
2076
|
+
#endif
|
|
2077
|
+
CHECK_RETURN_OK;
|
|
2078
|
+
}
|
|
2079
|
+
|
|
2080
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fset64(struct sljit_compiler *compiler,
|
|
2081
|
+
sljit_s32 freg, sljit_f64 value)
|
|
2082
|
+
{
|
|
2083
|
+
SLJIT_UNUSED_ARG(value);
|
|
2084
|
+
|
|
2085
|
+
if (SLJIT_UNLIKELY(compiler->skip_checks)) {
|
|
2086
|
+
compiler->skip_checks = 0;
|
|
2087
|
+
CHECK_RETURN_OK;
|
|
2088
|
+
}
|
|
2089
|
+
|
|
2090
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2091
|
+
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
|
|
2092
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0));
|
|
2093
|
+
#endif
|
|
2094
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2095
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
2096
|
+
fprintf(compiler->verbose, " fset64 ");
|
|
2097
|
+
sljit_verbose_freg(compiler, freg);
|
|
2098
|
+
fprintf(compiler->verbose, ", %f\n", value);
|
|
2099
|
+
}
|
|
2100
|
+
#endif
|
|
2101
|
+
CHECK_RETURN_OK;
|
|
2102
|
+
}
|
|
2103
|
+
|
|
2104
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op,
|
|
2105
|
+
sljit_s32 freg, sljit_s32 reg)
|
|
2106
|
+
{
|
|
2107
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2108
|
+
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
|
|
2109
|
+
CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_COPY_TO_F64 && GET_OPCODE(op) <= SLJIT_COPY_FROM_F64);
|
|
2110
|
+
CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
|
|
2111
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, op & SLJIT_32));
|
|
2112
|
+
|
|
2113
|
+
#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
|
|
2114
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(reg));
|
|
2115
|
+
#else /* !SLJIT_64BIT_ARCHITECTURE */
|
|
2116
|
+
switch (op) {
|
|
2117
|
+
case SLJIT_COPY32_TO_F32:
|
|
2118
|
+
case SLJIT_COPY32_FROM_F32:
|
|
2119
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(reg));
|
|
2120
|
+
break;
|
|
2121
|
+
case SLJIT_COPY_TO_F64:
|
|
2122
|
+
case SLJIT_COPY_FROM_F64:
|
|
2123
|
+
if (reg & REG_PAIR_MASK) {
|
|
2124
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(REG_PAIR_FIRST(reg)));
|
|
2125
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(REG_PAIR_SECOND(reg)));
|
|
2126
|
+
|
|
2127
|
+
if (op == SLJIT_COPY_TO_F64)
|
|
2128
|
+
break;
|
|
2129
|
+
|
|
2130
|
+
CHECK_ARGUMENT(REG_PAIR_FIRST(reg) != REG_PAIR_SECOND(reg));
|
|
2131
|
+
break;
|
|
2132
|
+
}
|
|
2133
|
+
|
|
2134
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(reg));
|
|
2135
|
+
break;
|
|
2136
|
+
}
|
|
2137
|
+
#endif /* SLJIT_64BIT_ARCHITECTURE */
|
|
2138
|
+
#endif
|
|
2139
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2140
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
2141
|
+
fprintf(compiler->verbose, " copy%s_%s_f%s ", (op & SLJIT_32) ? "32" : "",
|
|
2142
|
+
GET_OPCODE(op) == SLJIT_COPY_TO_F64 ? "to" : "from", (op & SLJIT_32) ? "32" : "64");
|
|
2143
|
+
|
|
2144
|
+
sljit_verbose_freg(compiler, freg);
|
|
2145
|
+
|
|
2146
|
+
if (reg & REG_PAIR_MASK) {
|
|
2147
|
+
fprintf(compiler->verbose, ", {");
|
|
2148
|
+
sljit_verbose_reg(compiler, REG_PAIR_FIRST(reg));
|
|
2149
|
+
fprintf(compiler->verbose, ", ");
|
|
2150
|
+
sljit_verbose_reg(compiler, REG_PAIR_SECOND(reg));
|
|
2151
|
+
fprintf(compiler->verbose, "}\n");
|
|
2152
|
+
} else {
|
|
2153
|
+
fprintf(compiler->verbose, ", ");
|
|
2154
|
+
sljit_verbose_reg(compiler, reg);
|
|
2155
|
+
fprintf(compiler->verbose, "\n");
|
|
2156
|
+
}
|
|
2157
|
+
}
|
|
2158
|
+
#endif
|
|
2159
|
+
CHECK_RETURN_OK;
|
|
2160
|
+
}
|
|
2161
|
+
|
|
2162
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_label(struct sljit_compiler *compiler)
|
|
2163
|
+
{
|
|
2164
|
+
SLJIT_UNUSED_ARG(compiler);
|
|
2165
|
+
|
|
2166
|
+
if (SLJIT_UNLIKELY(compiler->skip_checks)) {
|
|
2167
|
+
compiler->skip_checks = 0;
|
|
2168
|
+
CHECK_RETURN_OK;
|
|
2169
|
+
}
|
|
2170
|
+
|
|
2171
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2172
|
+
compiler->last_flags = 0;
|
|
2173
|
+
#endif
|
|
2174
|
+
|
|
2175
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2176
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose))
|
|
2177
|
+
fprintf(compiler->verbose, "label:\n");
|
|
2178
|
+
#endif
|
|
2179
|
+
CHECK_RETURN_OK;
|
|
2180
|
+
}
|
|
2181
|
+
|
|
2182
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2183
|
+
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
|
|
2184
|
+
|| (defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM)
|
|
2185
|
+
#define CHECK_UNORDERED(type, last_flags) \
|
|
2186
|
+
((((type) & 0xfe) == SLJIT_ORDERED) && \
|
|
2187
|
+
((last_flags) & 0xff) >= SLJIT_UNORDERED && ((last_flags) & 0xff) <= SLJIT_ORDERED_LESS_EQUAL)
|
|
2188
|
+
#else
|
|
2189
|
+
#define CHECK_UNORDERED(type, last_flags) 0
|
|
2190
|
+
#endif
|
|
2191
|
+
#endif /* SLJIT_ARGUMENT_CHECKS */
|
|
2192
|
+
|
|
2193
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
|
|
2194
|
+
{
|
|
2195
|
+
if (SLJIT_UNLIKELY(compiler->skip_checks)) {
|
|
2196
|
+
compiler->skip_checks = 0;
|
|
2197
|
+
CHECK_RETURN_OK;
|
|
2198
|
+
}
|
|
2199
|
+
|
|
2200
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2201
|
+
CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP)));
|
|
2202
|
+
CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_FAST_CALL);
|
|
2203
|
+
|
|
2204
|
+
if ((type & 0xff) < SLJIT_JUMP) {
|
|
2205
|
+
if ((type & 0xff) <= SLJIT_NOT_ZERO)
|
|
2206
|
+
CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);
|
|
2207
|
+
else if ((compiler->last_flags & 0xff) == SLJIT_CARRY) {
|
|
2208
|
+
CHECK_ARGUMENT((type & 0xfe) == SLJIT_CARRY);
|
|
2209
|
+
compiler->last_flags = 0;
|
|
2210
|
+
} else
|
|
2211
|
+
CHECK_ARGUMENT((type & 0xfe) == (compiler->last_flags & 0xff)
|
|
2212
|
+
|| CHECK_UNORDERED(type, compiler->last_flags));
|
|
2213
|
+
}
|
|
2214
|
+
#endif
|
|
2215
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2216
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose))
|
|
2217
|
+
fprintf(compiler->verbose, " jump%s %s\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r",
|
|
2218
|
+
jump_names[type & 0xff]);
|
|
2219
|
+
#endif
|
|
2220
|
+
CHECK_RETURN_OK;
|
|
2221
|
+
}
|
|
2222
|
+
|
|
2223
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
|
|
2224
|
+
sljit_s32 arg_types)
|
|
2225
|
+
{
|
|
2226
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2227
|
+
CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_CALL_RETURN)));
|
|
2228
|
+
CHECK_ARGUMENT((type & 0xff) >= SLJIT_CALL && (type & 0xff) <= SLJIT_CALL_REG_ARG);
|
|
2229
|
+
CHECK_ARGUMENT(function_check_arguments(arg_types, compiler->scratches, -1, compiler->fscratches));
|
|
2230
|
+
|
|
2231
|
+
if (type & SLJIT_CALL_RETURN) {
|
|
2232
|
+
CHECK_ARGUMENT((arg_types & SLJIT_ARG_MASK) == compiler->last_return);
|
|
2233
|
+
|
|
2234
|
+
if (compiler->options & SLJIT_ENTER_REG_ARG) {
|
|
2235
|
+
CHECK_ARGUMENT((type & 0xff) == SLJIT_CALL_REG_ARG);
|
|
2236
|
+
} else {
|
|
2237
|
+
CHECK_ARGUMENT((type & 0xff) != SLJIT_CALL_REG_ARG);
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2240
|
+
#endif
|
|
2241
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2242
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
2243
|
+
fprintf(compiler->verbose, " %s%s%s ret[%s", jump_names[type & 0xff],
|
|
2244
|
+
!(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r",
|
|
2245
|
+
!(type & SLJIT_CALL_RETURN) ? "" : ".ret",
|
|
2246
|
+
call_arg_names[arg_types & SLJIT_ARG_MASK]);
|
|
2247
|
+
|
|
2248
|
+
arg_types >>= SLJIT_ARG_SHIFT;
|
|
2249
|
+
if (arg_types) {
|
|
2250
|
+
fprintf(compiler->verbose, "], args[");
|
|
2251
|
+
do {
|
|
2252
|
+
fprintf(compiler->verbose, "%s", call_arg_names[arg_types & SLJIT_ARG_MASK]);
|
|
2253
|
+
arg_types >>= SLJIT_ARG_SHIFT;
|
|
2254
|
+
if (arg_types)
|
|
2255
|
+
fprintf(compiler->verbose, ",");
|
|
2256
|
+
} while (arg_types);
|
|
2257
|
+
}
|
|
2258
|
+
fprintf(compiler->verbose, "]\n");
|
|
2259
|
+
}
|
|
2260
|
+
#endif
|
|
2261
|
+
CHECK_RETURN_OK;
|
|
2262
|
+
}
|
|
2263
|
+
|
|
2264
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
|
|
2265
|
+
sljit_s32 src1, sljit_sw src1w,
|
|
2266
|
+
sljit_s32 src2, sljit_sw src2w)
|
|
2267
|
+
{
|
|
2268
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2269
|
+
CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_32)));
|
|
2270
|
+
CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_SIG_LESS_EQUAL);
|
|
2271
|
+
FUNCTION_CHECK_SRC(src1, src1w);
|
|
2272
|
+
FUNCTION_CHECK_SRC(src2, src2w);
|
|
2273
|
+
compiler->last_flags = 0;
|
|
2274
|
+
#endif
|
|
2275
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2276
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
2277
|
+
fprintf(compiler->verbose, " cmp%s%s %s, ", (type & SLJIT_32) ? "32" : "",
|
|
2278
|
+
!(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]);
|
|
2279
|
+
sljit_verbose_param(compiler, src1, src1w);
|
|
2280
|
+
fprintf(compiler->verbose, ", ");
|
|
2281
|
+
sljit_verbose_param(compiler, src2, src2w);
|
|
2282
|
+
fprintf(compiler->verbose, "\n");
|
|
2283
|
+
}
|
|
2284
|
+
#endif
|
|
2285
|
+
CHECK_RETURN_OK;
|
|
2286
|
+
}
|
|
2287
|
+
|
|
2288
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,
|
|
2289
|
+
sljit_s32 src1, sljit_sw src1w,
|
|
2290
|
+
sljit_s32 src2, sljit_sw src2w)
|
|
2291
|
+
{
|
|
2292
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2293
|
+
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
|
|
2294
|
+
CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_32)));
|
|
2295
|
+
CHECK_ARGUMENT((type & 0xff) >= SLJIT_F_EQUAL && (type & 0xff) <= SLJIT_ORDERED_LESS_EQUAL);
|
|
2296
|
+
FUNCTION_FCHECK(src1, src1w, type & SLJIT_32);
|
|
2297
|
+
FUNCTION_FCHECK(src2, src2w, type & SLJIT_32);
|
|
2298
|
+
compiler->last_flags = 0;
|
|
2299
|
+
#endif
|
|
2300
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2301
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
2302
|
+
fprintf(compiler->verbose, " fcmp%s%s %s, ", (type & SLJIT_32) ? ".f32" : ".f64",
|
|
2303
|
+
!(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]);
|
|
2304
|
+
sljit_verbose_fparam(compiler, src1, src1w);
|
|
2305
|
+
fprintf(compiler->verbose, ", ");
|
|
2306
|
+
sljit_verbose_fparam(compiler, src2, src2w);
|
|
2307
|
+
fprintf(compiler->verbose, "\n");
|
|
2308
|
+
}
|
|
2309
|
+
#endif
|
|
2310
|
+
CHECK_RETURN_OK;
|
|
2311
|
+
}
|
|
2312
|
+
|
|
2313
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type,
|
|
2314
|
+
sljit_s32 src, sljit_sw srcw)
|
|
2315
|
+
{
|
|
2316
|
+
if (SLJIT_UNLIKELY(compiler->skip_checks)) {
|
|
2317
|
+
compiler->skip_checks = 0;
|
|
2318
|
+
CHECK_RETURN_OK;
|
|
2319
|
+
}
|
|
2320
|
+
|
|
2321
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2322
|
+
CHECK_ARGUMENT(type >= SLJIT_JUMP && type <= SLJIT_FAST_CALL);
|
|
2323
|
+
FUNCTION_CHECK_SRC(src, srcw);
|
|
2324
|
+
#endif
|
|
2325
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2326
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
2327
|
+
fprintf(compiler->verbose, " ijump.%s ", jump_names[type]);
|
|
2328
|
+
sljit_verbose_param(compiler, src, srcw);
|
|
2329
|
+
fprintf(compiler->verbose, "\n");
|
|
2330
|
+
}
|
|
2331
|
+
#endif
|
|
2332
|
+
CHECK_RETURN_OK;
|
|
2333
|
+
}
|
|
2334
|
+
|
|
2335
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
|
|
2336
|
+
sljit_s32 arg_types,
|
|
2337
|
+
sljit_s32 src, sljit_sw srcw)
|
|
2338
|
+
{
|
|
2339
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2340
|
+
CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_CALL_RETURN)));
|
|
2341
|
+
CHECK_ARGUMENT((type & 0xff) >= SLJIT_CALL && (type & 0xff) <= SLJIT_CALL_REG_ARG);
|
|
2342
|
+
CHECK_ARGUMENT(function_check_arguments(arg_types, compiler->scratches, -1, compiler->fscratches));
|
|
2343
|
+
FUNCTION_CHECK_SRC(src, srcw);
|
|
2344
|
+
|
|
2345
|
+
if (type & SLJIT_CALL_RETURN) {
|
|
2346
|
+
CHECK_ARGUMENT((arg_types & SLJIT_ARG_MASK) == compiler->last_return);
|
|
2347
|
+
|
|
2348
|
+
if (compiler->options & SLJIT_ENTER_REG_ARG) {
|
|
2349
|
+
CHECK_ARGUMENT((type & 0xff) == SLJIT_CALL_REG_ARG);
|
|
2350
|
+
} else {
|
|
2351
|
+
CHECK_ARGUMENT((type & 0xff) != SLJIT_CALL_REG_ARG);
|
|
2352
|
+
}
|
|
2353
|
+
}
|
|
2354
|
+
#endif
|
|
2355
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2356
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
2357
|
+
fprintf(compiler->verbose, " i%s%s ret[%s", jump_names[type & 0xff],
|
|
2358
|
+
!(type & SLJIT_CALL_RETURN) ? "" : ".ret",
|
|
2359
|
+
call_arg_names[arg_types & SLJIT_ARG_MASK]);
|
|
2360
|
+
|
|
2361
|
+
arg_types >>= SLJIT_ARG_SHIFT;
|
|
2362
|
+
if (arg_types) {
|
|
2363
|
+
fprintf(compiler->verbose, "], args[");
|
|
2364
|
+
do {
|
|
2365
|
+
fprintf(compiler->verbose, "%s", call_arg_names[arg_types & SLJIT_ARG_MASK]);
|
|
2366
|
+
arg_types >>= SLJIT_ARG_SHIFT;
|
|
2367
|
+
if (arg_types)
|
|
2368
|
+
fprintf(compiler->verbose, ",");
|
|
2369
|
+
} while (arg_types);
|
|
2370
|
+
}
|
|
2371
|
+
fprintf(compiler->verbose, "], ");
|
|
2372
|
+
sljit_verbose_param(compiler, src, srcw);
|
|
2373
|
+
fprintf(compiler->verbose, "\n");
|
|
2374
|
+
}
|
|
2375
|
+
#endif
|
|
2376
|
+
CHECK_RETURN_OK;
|
|
2377
|
+
}
|
|
2378
|
+
|
|
2379
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
|
|
2380
|
+
sljit_s32 dst, sljit_sw dstw,
|
|
2381
|
+
sljit_s32 type)
|
|
2382
|
+
{
|
|
2383
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2384
|
+
CHECK_ARGUMENT(type >= SLJIT_EQUAL && type <= SLJIT_ORDERED_LESS_EQUAL);
|
|
2385
|
+
CHECK_ARGUMENT(op == SLJIT_MOV || op == SLJIT_MOV32
|
|
2386
|
+
|| (GET_OPCODE(op) >= SLJIT_AND && GET_OPCODE(op) <= SLJIT_XOR));
|
|
2387
|
+
CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK));
|
|
2388
|
+
|
|
2389
|
+
if (type <= SLJIT_NOT_ZERO)
|
|
2390
|
+
CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);
|
|
2391
|
+
else
|
|
2392
|
+
CHECK_ARGUMENT((type & 0xfe) == (compiler->last_flags & 0xff)
|
|
2393
|
+
|| CHECK_UNORDERED(type, compiler->last_flags));
|
|
2394
|
+
|
|
2395
|
+
FUNCTION_CHECK_DST(dst, dstw);
|
|
2396
|
+
|
|
2397
|
+
if (GET_OPCODE(op) >= SLJIT_ADD)
|
|
2398
|
+
compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_32 | SLJIT_SET_Z));
|
|
2399
|
+
#endif
|
|
2400
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2401
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
2402
|
+
fprintf(compiler->verbose, " flags.%s%s%s ",
|
|
2403
|
+
GET_OPCODE(op) < SLJIT_OP2_BASE ? "mov" : op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE],
|
|
2404
|
+
GET_OPCODE(op) < SLJIT_OP2_BASE ? op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE] : ((op & SLJIT_32) ? "32" : ""),
|
|
2405
|
+
!(op & SLJIT_SET_Z) ? "" : ".z");
|
|
2406
|
+
sljit_verbose_param(compiler, dst, dstw);
|
|
2407
|
+
fprintf(compiler->verbose, ", %s\n", jump_names[type]);
|
|
2408
|
+
}
|
|
2409
|
+
#endif
|
|
2410
|
+
CHECK_RETURN_OK;
|
|
2411
|
+
}
|
|
2412
|
+
|
|
2413
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type,
|
|
2414
|
+
sljit_s32 dst_reg,
|
|
2415
|
+
sljit_s32 src1, sljit_sw src1w,
|
|
2416
|
+
sljit_s32 src2_reg)
|
|
2417
|
+
{
|
|
2418
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2419
|
+
sljit_s32 cond = type & ~SLJIT_32;
|
|
2420
|
+
|
|
2421
|
+
CHECK_ARGUMENT(cond >= SLJIT_EQUAL && cond <= SLJIT_ORDERED_LESS_EQUAL);
|
|
2422
|
+
|
|
2423
|
+
CHECK_ARGUMENT(compiler->scratches != -1 && compiler->saveds != -1);
|
|
2424
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg));
|
|
2425
|
+
FUNCTION_CHECK_SRC(src1, src1w);
|
|
2426
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src2_reg));
|
|
2427
|
+
|
|
2428
|
+
if (cond <= SLJIT_NOT_ZERO)
|
|
2429
|
+
CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);
|
|
2430
|
+
else if ((compiler->last_flags & 0xff) == SLJIT_CARRY) {
|
|
2431
|
+
CHECK_ARGUMENT((type & 0xfe) == SLJIT_CARRY);
|
|
2432
|
+
compiler->last_flags = 0;
|
|
2433
|
+
} else
|
|
2434
|
+
CHECK_ARGUMENT((cond & 0xfe) == (compiler->last_flags & 0xff)
|
|
2435
|
+
|| CHECK_UNORDERED(cond, compiler->last_flags));
|
|
2436
|
+
#endif
|
|
2437
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2438
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
2439
|
+
fprintf(compiler->verbose, " select%s %s, ",
|
|
2440
|
+
!(type & SLJIT_32) ? "" : "32",
|
|
2441
|
+
jump_names[type & ~SLJIT_32]);
|
|
2442
|
+
sljit_verbose_reg(compiler, dst_reg);
|
|
2443
|
+
fprintf(compiler->verbose, ", ");
|
|
2444
|
+
sljit_verbose_param(compiler, src1, src1w);
|
|
2445
|
+
fprintf(compiler->verbose, ", ");
|
|
2446
|
+
sljit_verbose_reg(compiler, src2_reg);
|
|
2447
|
+
fprintf(compiler->verbose, "\n");
|
|
2448
|
+
}
|
|
2449
|
+
#endif
|
|
2450
|
+
CHECK_RETURN_OK;
|
|
2451
|
+
}
|
|
2452
|
+
|
|
2453
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type,
|
|
2454
|
+
sljit_s32 dst_freg,
|
|
2455
|
+
sljit_s32 src1, sljit_sw src1w,
|
|
2456
|
+
sljit_s32 src2_freg)
|
|
2457
|
+
{
|
|
2458
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2459
|
+
sljit_s32 cond = type & ~SLJIT_32;
|
|
2460
|
+
|
|
2461
|
+
CHECK_ARGUMENT(cond >= SLJIT_EQUAL && cond <= SLJIT_ORDERED_LESS_EQUAL);
|
|
2462
|
+
|
|
2463
|
+
CHECK_ARGUMENT(compiler->fscratches != -1 && compiler->fsaveds != -1);
|
|
2464
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(dst_freg, type & SLJIT_32));
|
|
2465
|
+
FUNCTION_FCHECK(src1, src1w, type & SLJIT_32);
|
|
2466
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(src2_freg, type & SLJIT_32));
|
|
2467
|
+
|
|
2468
|
+
if (cond <= SLJIT_NOT_ZERO)
|
|
2469
|
+
CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);
|
|
2470
|
+
else if ((compiler->last_flags & 0xff) == SLJIT_CARRY) {
|
|
2471
|
+
CHECK_ARGUMENT((type & 0xfe) == SLJIT_CARRY);
|
|
2472
|
+
compiler->last_flags = 0;
|
|
2473
|
+
} else
|
|
2474
|
+
CHECK_ARGUMENT((cond & 0xfe) == (compiler->last_flags & 0xff)
|
|
2475
|
+
|| CHECK_UNORDERED(cond, compiler->last_flags));
|
|
2476
|
+
#endif
|
|
2477
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2478
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
2479
|
+
fprintf(compiler->verbose, " fselect%s %s, ",
|
|
2480
|
+
!(type & SLJIT_32) ? "" : "32",
|
|
2481
|
+
jump_names[type & ~SLJIT_32]);
|
|
2482
|
+
sljit_verbose_freg(compiler, dst_freg);
|
|
2483
|
+
fprintf(compiler->verbose, ", ");
|
|
2484
|
+
sljit_verbose_fparam(compiler, src1, src1w);
|
|
2485
|
+
fprintf(compiler->verbose, ", ");
|
|
2486
|
+
sljit_verbose_freg(compiler, src2_freg);
|
|
2487
|
+
fprintf(compiler->verbose, "\n");
|
|
2488
|
+
}
|
|
2489
|
+
#endif
|
|
2490
|
+
CHECK_RETURN_OK;
|
|
2491
|
+
}
|
|
2492
|
+
|
|
2493
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
|
|
2494
|
+
sljit_s32 reg,
|
|
2495
|
+
sljit_s32 mem, sljit_sw memw)
|
|
2496
|
+
{
|
|
2497
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2498
|
+
sljit_s32 allowed_flags;
|
|
2499
|
+
#endif /* SLJIT_ARGUMENT_CHECKS */
|
|
2500
|
+
|
|
2501
|
+
if (SLJIT_UNLIKELY(compiler->skip_checks)) {
|
|
2502
|
+
compiler->skip_checks = 0;
|
|
2503
|
+
CHECK_RETURN_OK;
|
|
2504
|
+
}
|
|
2505
|
+
|
|
2506
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2507
|
+
if (type & SLJIT_MEM_UNALIGNED) {
|
|
2508
|
+
CHECK_ARGUMENT(!(type & (SLJIT_MEM_ALIGNED_16 | SLJIT_MEM_ALIGNED_32)));
|
|
2509
|
+
} else if (type & SLJIT_MEM_ALIGNED_16) {
|
|
2510
|
+
CHECK_ARGUMENT(!(type & SLJIT_MEM_ALIGNED_32));
|
|
2511
|
+
} else {
|
|
2512
|
+
CHECK_ARGUMENT((reg & REG_PAIR_MASK) || (type & SLJIT_MEM_ALIGNED_32));
|
|
2513
|
+
}
|
|
2514
|
+
|
|
2515
|
+
allowed_flags = SLJIT_MEM_UNALIGNED;
|
|
2516
|
+
|
|
2517
|
+
switch (type & 0xff) {
|
|
2518
|
+
case SLJIT_MOV_P:
|
|
2519
|
+
case SLJIT_MOV:
|
|
2520
|
+
allowed_flags |= SLJIT_MEM_ALIGNED_32;
|
|
2521
|
+
/* fallthrough */
|
|
2522
|
+
case SLJIT_MOV_U32:
|
|
2523
|
+
case SLJIT_MOV_S32:
|
|
2524
|
+
case SLJIT_MOV32:
|
|
2525
|
+
allowed_flags |= SLJIT_MEM_ALIGNED_16;
|
|
2526
|
+
break;
|
|
2527
|
+
}
|
|
2528
|
+
|
|
2529
|
+
CHECK_ARGUMENT((type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | allowed_flags)) == 0);
|
|
2530
|
+
|
|
2531
|
+
if (reg & REG_PAIR_MASK) {
|
|
2532
|
+
CHECK_ARGUMENT((type & 0xff) == SLJIT_MOV);
|
|
2533
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(REG_PAIR_FIRST(reg)));
|
|
2534
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(REG_PAIR_SECOND(reg)));
|
|
2535
|
+
CHECK_ARGUMENT(REG_PAIR_FIRST(reg) != REG_PAIR_SECOND(reg));
|
|
2536
|
+
} else {
|
|
2537
|
+
CHECK_ARGUMENT((type & 0xff) >= SLJIT_MOV && (type & 0xff) <= SLJIT_MOV_P);
|
|
2538
|
+
CHECK_ARGUMENT(!(type & SLJIT_32) || ((type & 0xff) >= SLJIT_MOV_U8 && (type & 0xff) <= SLJIT_MOV_S16));
|
|
2539
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(reg));
|
|
2540
|
+
}
|
|
2541
|
+
|
|
2542
|
+
FUNCTION_CHECK_SRC_MEM(mem, memw);
|
|
2543
|
+
#endif
|
|
2544
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2545
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
2546
|
+
if ((type & 0xff) == SLJIT_MOV32)
|
|
2547
|
+
fprintf(compiler->verbose, " %s32",
|
|
2548
|
+
(type & SLJIT_MEM_STORE) ? "store" : "load");
|
|
2549
|
+
else
|
|
2550
|
+
fprintf(compiler->verbose, " %s%s%s",
|
|
2551
|
+
(type & SLJIT_MEM_STORE) ? "store" : "load",
|
|
2552
|
+
!(type & SLJIT_32) ? "" : "32", op1_types[(type & 0xff) - SLJIT_OP1_BASE]);
|
|
2553
|
+
|
|
2554
|
+
if (type & SLJIT_MEM_UNALIGNED)
|
|
2555
|
+
printf(".unal");
|
|
2556
|
+
else if (type & SLJIT_MEM_ALIGNED_16)
|
|
2557
|
+
printf(".al16");
|
|
2558
|
+
else if (type & SLJIT_MEM_ALIGNED_32)
|
|
2559
|
+
printf(".al32");
|
|
2560
|
+
|
|
2561
|
+
if (reg & REG_PAIR_MASK) {
|
|
2562
|
+
fprintf(compiler->verbose, " {");
|
|
2563
|
+
sljit_verbose_reg(compiler, REG_PAIR_FIRST(reg));
|
|
2564
|
+
fprintf(compiler->verbose, ", ");
|
|
2565
|
+
sljit_verbose_reg(compiler, REG_PAIR_SECOND(reg));
|
|
2566
|
+
fprintf(compiler->verbose, "}, ");
|
|
2567
|
+
} else {
|
|
2568
|
+
fprintf(compiler->verbose, " ");
|
|
2569
|
+
sljit_verbose_reg(compiler, reg);
|
|
2570
|
+
fprintf(compiler->verbose, ", ");
|
|
2571
|
+
}
|
|
2572
|
+
sljit_verbose_param(compiler, mem, memw);
|
|
2573
|
+
fprintf(compiler->verbose, "\n");
|
|
2574
|
+
}
|
|
2575
|
+
#endif
|
|
2576
|
+
CHECK_RETURN_OK;
|
|
2577
|
+
}
|
|
2578
|
+
|
|
2579
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type,
|
|
2580
|
+
sljit_s32 reg,
|
|
2581
|
+
sljit_s32 mem, sljit_sw memw)
|
|
2582
|
+
{
|
|
2583
|
+
if (SLJIT_UNLIKELY(compiler->skip_checks)) {
|
|
2584
|
+
compiler->skip_checks = 0;
|
|
2585
|
+
CHECK_RETURN_OK;
|
|
2586
|
+
}
|
|
2587
|
+
|
|
2588
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2589
|
+
CHECK_ARGUMENT((type & 0xff) >= SLJIT_MOV && (type & 0xff) <= SLJIT_MOV_P);
|
|
2590
|
+
CHECK_ARGUMENT((type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_SUPP | SLJIT_MEM_POST)) == 0);
|
|
2591
|
+
CHECK_ARGUMENT((mem & REG_MASK) != 0 && (mem & REG_MASK) != reg);
|
|
2592
|
+
|
|
2593
|
+
FUNCTION_CHECK_SRC_MEM(mem, memw);
|
|
2594
|
+
#endif
|
|
2595
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2596
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
2597
|
+
if (type & SLJIT_MEM_SUPP)
|
|
2598
|
+
CHECK_RETURN_OK;
|
|
2599
|
+
if (sljit_emit_mem_update(compiler, type | SLJIT_MEM_SUPP, reg, mem, memw) == SLJIT_ERR_UNSUPPORTED) {
|
|
2600
|
+
fprintf(compiler->verbose, " # mem: unsupported form, no instructions are emitted\n");
|
|
2601
|
+
CHECK_RETURN_OK;
|
|
2602
|
+
}
|
|
2603
|
+
|
|
2604
|
+
if ((type & 0xff) == SLJIT_MOV32)
|
|
2605
|
+
fprintf(compiler->verbose, " %s32.%s ",
|
|
2606
|
+
(type & SLJIT_MEM_STORE) ? "store" : "load",
|
|
2607
|
+
(type & SLJIT_MEM_POST) ? "post" : "pre");
|
|
2608
|
+
else
|
|
2609
|
+
fprintf(compiler->verbose, " %s%s%s.%s ",
|
|
2610
|
+
(type & SLJIT_MEM_STORE) ? "store" : "load",
|
|
2611
|
+
!(type & SLJIT_32) ? "" : "32",
|
|
2612
|
+
op1_types[(type & 0xff) - SLJIT_OP1_BASE],
|
|
2613
|
+
(type & SLJIT_MEM_POST) ? "post" : "pre");
|
|
2614
|
+
|
|
2615
|
+
sljit_verbose_reg(compiler, reg);
|
|
2616
|
+
fprintf(compiler->verbose, ", ");
|
|
2617
|
+
sljit_verbose_param(compiler, mem, memw);
|
|
2618
|
+
fprintf(compiler->verbose, "\n");
|
|
2619
|
+
}
|
|
2620
|
+
#endif
|
|
2621
|
+
CHECK_RETURN_OK;
|
|
2622
|
+
}
|
|
2623
|
+
|
|
2624
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
|
|
2625
|
+
sljit_s32 freg,
|
|
2626
|
+
sljit_s32 mem, sljit_sw memw)
|
|
2627
|
+
{
|
|
2628
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2629
|
+
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
|
|
2630
|
+
CHECK_ARGUMENT((type & 0xff) == SLJIT_MOV_F64);
|
|
2631
|
+
|
|
2632
|
+
if (type & SLJIT_MEM_UNALIGNED) {
|
|
2633
|
+
CHECK_ARGUMENT(!(type & (SLJIT_MEM_ALIGNED_16 | SLJIT_MEM_ALIGNED_32)));
|
|
2634
|
+
} else if (type & SLJIT_MEM_ALIGNED_16) {
|
|
2635
|
+
CHECK_ARGUMENT(!(type & SLJIT_MEM_ALIGNED_32));
|
|
2636
|
+
} else {
|
|
2637
|
+
CHECK_ARGUMENT(type & SLJIT_MEM_ALIGNED_32);
|
|
2638
|
+
CHECK_ARGUMENT(!(type & SLJIT_32));
|
|
2639
|
+
}
|
|
2640
|
+
|
|
2641
|
+
CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_UNALIGNED | SLJIT_MEM_ALIGNED_16 | SLJIT_MEM_ALIGNED_32)));
|
|
2642
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, type & SLJIT_32));
|
|
2643
|
+
FUNCTION_CHECK_SRC_MEM(mem, memw);
|
|
2644
|
+
#endif
|
|
2645
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2646
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
2647
|
+
fprintf(compiler->verbose, " %s.%s",
|
|
2648
|
+
(type & SLJIT_MEM_STORE) ? "store" : "load",
|
|
2649
|
+
!(type & SLJIT_32) ? "f64" : "f32");
|
|
2650
|
+
|
|
2651
|
+
if (type & SLJIT_MEM_UNALIGNED)
|
|
2652
|
+
printf(".unal");
|
|
2653
|
+
else if (type & SLJIT_MEM_ALIGNED_16)
|
|
2654
|
+
printf(".al16");
|
|
2655
|
+
else if (type & SLJIT_MEM_ALIGNED_32)
|
|
2656
|
+
printf(".al32");
|
|
2657
|
+
|
|
2658
|
+
fprintf(compiler->verbose, " ");
|
|
2659
|
+
sljit_verbose_freg(compiler, freg);
|
|
2660
|
+
fprintf(compiler->verbose, ", ");
|
|
2661
|
+
sljit_verbose_param(compiler, mem, memw);
|
|
2662
|
+
fprintf(compiler->verbose, "\n");
|
|
2663
|
+
}
|
|
2664
|
+
#endif
|
|
2665
|
+
CHECK_RETURN_OK;
|
|
2666
|
+
}
|
|
2667
|
+
|
|
2668
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem_update(struct sljit_compiler *compiler, sljit_s32 type,
|
|
2669
|
+
sljit_s32 freg,
|
|
2670
|
+
sljit_s32 mem, sljit_sw memw)
|
|
2671
|
+
{
|
|
2672
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2673
|
+
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
|
|
2674
|
+
CHECK_ARGUMENT((type & 0xff) == SLJIT_MOV_F64);
|
|
2675
|
+
CHECK_ARGUMENT((type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_SUPP | SLJIT_MEM_POST)) == 0);
|
|
2676
|
+
FUNCTION_CHECK_SRC_MEM(mem, memw);
|
|
2677
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, type & SLJIT_32));
|
|
2678
|
+
#endif
|
|
2679
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2680
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
2681
|
+
if (type & SLJIT_MEM_SUPP)
|
|
2682
|
+
CHECK_RETURN_OK;
|
|
2683
|
+
if (sljit_emit_fmem_update(compiler, type | SLJIT_MEM_SUPP, freg, mem, memw) == SLJIT_ERR_UNSUPPORTED) {
|
|
2684
|
+
fprintf(compiler->verbose, " # fmem: unsupported form, no instructions are emitted\n");
|
|
2685
|
+
CHECK_RETURN_OK;
|
|
2686
|
+
}
|
|
2687
|
+
|
|
2688
|
+
fprintf(compiler->verbose, " %s.%s.%s ",
|
|
2689
|
+
(type & SLJIT_MEM_STORE) ? "store" : "load",
|
|
2690
|
+
!(type & SLJIT_32) ? "f64" : "f32",
|
|
2691
|
+
(type & SLJIT_MEM_POST) ? "post" : "pre");
|
|
2692
|
+
|
|
2693
|
+
sljit_verbose_freg(compiler, freg);
|
|
2694
|
+
fprintf(compiler->verbose, ", ");
|
|
2695
|
+
sljit_verbose_param(compiler, mem, memw);
|
|
2696
|
+
fprintf(compiler->verbose, "\n");
|
|
2697
|
+
}
|
|
2698
|
+
#endif
|
|
2699
|
+
CHECK_RETURN_OK;
|
|
2700
|
+
}
|
|
2701
|
+
|
|
2702
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type,
|
|
2703
|
+
sljit_s32 freg,
|
|
2704
|
+
sljit_s32 srcdst, sljit_sw srcdstw)
|
|
2705
|
+
{
|
|
2706
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2707
|
+
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD));
|
|
2708
|
+
CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK2(SLJIT_SIMD_STORE)) == 0);
|
|
2709
|
+
CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));
|
|
2710
|
+
CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) <= SLJIT_SIMD_GET_REG_SIZE(type));
|
|
2711
|
+
CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM2_SIZE(type) <= (srcdst & SLJIT_MEM) ? SLJIT_SIMD_GET_REG_SIZE(type) : 0);
|
|
2712
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0));
|
|
2713
|
+
FUNCTION_FCHECK(srcdst, srcdstw, 0);
|
|
2714
|
+
#endif
|
|
2715
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2716
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
2717
|
+
if (type & SLJIT_SIMD_TEST)
|
|
2718
|
+
CHECK_RETURN_OK;
|
|
2719
|
+
if (sljit_emit_simd_mov(compiler, type | SLJIT_SIMD_TEST, freg, srcdst, srcdstw) == SLJIT_ERR_UNSUPPORTED) {
|
|
2720
|
+
fprintf(compiler->verbose, " # simd_mem: unsupported form, no instructions are emitted\n");
|
|
2721
|
+
CHECK_RETURN_OK;
|
|
2722
|
+
}
|
|
2723
|
+
|
|
2724
|
+
fprintf(compiler->verbose, " simd_%s.%d.%s%d",
|
|
2725
|
+
(type & SLJIT_SIMD_STORE) ? "store" : "load",
|
|
2726
|
+
(8 << SLJIT_SIMD_GET_REG_SIZE(type)),
|
|
2727
|
+
(type & SLJIT_SIMD_FLOAT) ? "f" : "",
|
|
2728
|
+
(8 << SLJIT_SIMD_GET_ELEM_SIZE(type)));
|
|
2729
|
+
|
|
2730
|
+
if ((type & 0x3f000000) == SLJIT_SIMD_MEM_UNALIGNED)
|
|
2731
|
+
fprintf(compiler->verbose, ".unal ");
|
|
2732
|
+
else
|
|
2733
|
+
fprintf(compiler->verbose, ".al%d ", (8 << SLJIT_SIMD_GET_ELEM2_SIZE(type)));
|
|
2734
|
+
|
|
2735
|
+
sljit_verbose_freg(compiler, freg);
|
|
2736
|
+
fprintf(compiler->verbose, ", ");
|
|
2737
|
+
sljit_verbose_fparam(compiler, srcdst, srcdstw);
|
|
2738
|
+
fprintf(compiler->verbose, "\n");
|
|
2739
|
+
}
|
|
2740
|
+
#endif
|
|
2741
|
+
CHECK_RETURN_OK;
|
|
2742
|
+
}
|
|
2743
|
+
|
|
2744
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type,
|
|
2745
|
+
sljit_s32 freg,
|
|
2746
|
+
sljit_s32 src, sljit_sw srcw)
|
|
2747
|
+
{
|
|
2748
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2749
|
+
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD));
|
|
2750
|
+
CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(0)) == 0);
|
|
2751
|
+
CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));
|
|
2752
|
+
CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type));
|
|
2753
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0));
|
|
2754
|
+
|
|
2755
|
+
if (type & SLJIT_SIMD_FLOAT) {
|
|
2756
|
+
if (src == SLJIT_IMM) {
|
|
2757
|
+
CHECK_ARGUMENT(srcw == 0);
|
|
2758
|
+
} else {
|
|
2759
|
+
FUNCTION_FCHECK(src, srcw, SLJIT_SIMD_GET_ELEM_SIZE(type) == 2);
|
|
2760
|
+
}
|
|
2761
|
+
} else if (src != SLJIT_IMM) {
|
|
2762
|
+
FUNCTION_CHECK_DST(src, srcw);
|
|
2763
|
+
}
|
|
2764
|
+
#endif
|
|
2765
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2766
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
2767
|
+
if (type & SLJIT_SIMD_TEST)
|
|
2768
|
+
CHECK_RETURN_OK;
|
|
2769
|
+
if (sljit_emit_simd_replicate(compiler, type | SLJIT_SIMD_TEST, freg, src, srcw) == SLJIT_ERR_UNSUPPORTED) {
|
|
2770
|
+
fprintf(compiler->verbose, " # simd_dup: unsupported form, no instructions are emitted\n");
|
|
2771
|
+
CHECK_RETURN_OK;
|
|
2772
|
+
}
|
|
2773
|
+
|
|
2774
|
+
fprintf(compiler->verbose, " simd_replicate.%d.%s%d ",
|
|
2775
|
+
(8 << SLJIT_SIMD_GET_REG_SIZE(type)),
|
|
2776
|
+
(type & SLJIT_SIMD_FLOAT) ? "f" : "",
|
|
2777
|
+
(8 << SLJIT_SIMD_GET_ELEM_SIZE(type)));
|
|
2778
|
+
|
|
2779
|
+
sljit_verbose_freg(compiler, freg);
|
|
2780
|
+
fprintf(compiler->verbose, ", ");
|
|
2781
|
+
if (type & SLJIT_SIMD_FLOAT)
|
|
2782
|
+
sljit_verbose_fparam(compiler, src, srcw);
|
|
2783
|
+
else
|
|
2784
|
+
sljit_verbose_param(compiler, src, srcw);
|
|
2785
|
+
fprintf(compiler->verbose, "\n");
|
|
2786
|
+
}
|
|
2787
|
+
#endif
|
|
2788
|
+
CHECK_RETURN_OK;
|
|
2789
|
+
}
|
|
2790
|
+
|
|
2791
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type,
|
|
2792
|
+
sljit_s32 freg, sljit_s32 lane_index,
|
|
2793
|
+
sljit_s32 srcdst, sljit_sw srcdstw)
|
|
2794
|
+
{
|
|
2795
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2796
|
+
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD));
|
|
2797
|
+
CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(SLJIT_SIMD_STORE | SLJIT_SIMD_LANE_ZERO | SLJIT_SIMD_LANE_SIGNED | SLJIT_32)) == 0);
|
|
2798
|
+
CHECK_ARGUMENT((type & (SLJIT_SIMD_STORE | SLJIT_SIMD_LANE_ZERO)) != (SLJIT_SIMD_STORE | SLJIT_SIMD_LANE_ZERO));
|
|
2799
|
+
CHECK_ARGUMENT((type & (SLJIT_SIMD_STORE | SLJIT_SIMD_LANE_SIGNED)) != SLJIT_SIMD_LANE_SIGNED);
|
|
2800
|
+
CHECK_ARGUMENT(!(type & SLJIT_SIMD_FLOAT) || !(type & (SLJIT_SIMD_LANE_SIGNED | SLJIT_32)));
|
|
2801
|
+
CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));
|
|
2802
|
+
CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type));
|
|
2803
|
+
CHECK_ARGUMENT(!(type & SLJIT_32) || SLJIT_SIMD_GET_ELEM_SIZE(type) <= 2);
|
|
2804
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0));
|
|
2805
|
+
CHECK_ARGUMENT(lane_index >= 0 && lane_index < (1 << (SLJIT_SIMD_GET_REG_SIZE(type) - SLJIT_SIMD_GET_ELEM_SIZE(type))));
|
|
2806
|
+
|
|
2807
|
+
if (type & SLJIT_SIMD_FLOAT) {
|
|
2808
|
+
FUNCTION_FCHECK(srcdst, srcdstw, SLJIT_SIMD_GET_ELEM_SIZE(type) == 2);
|
|
2809
|
+
} else if ((type & SLJIT_SIMD_STORE) || srcdst != SLJIT_IMM) {
|
|
2810
|
+
FUNCTION_CHECK_DST(srcdst, srcdstw);
|
|
2811
|
+
}
|
|
2812
|
+
#endif
|
|
2813
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2814
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
2815
|
+
if (type & SLJIT_SIMD_TEST)
|
|
2816
|
+
CHECK_RETURN_OK;
|
|
2817
|
+
if (sljit_emit_simd_lane_mov(compiler, type | SLJIT_SIMD_TEST, freg, lane_index, srcdst, srcdstw) == SLJIT_ERR_UNSUPPORTED) {
|
|
2818
|
+
fprintf(compiler->verbose, " # simd_move_lane: unsupported form, no instructions are emitted\n");
|
|
2819
|
+
CHECK_RETURN_OK;
|
|
2820
|
+
}
|
|
2821
|
+
|
|
2822
|
+
fprintf(compiler->verbose, " simd_%s_lane%s%s%s.%d.%s%d ",
|
|
2823
|
+
(type & SLJIT_SIMD_STORE) ? "store" : "load",
|
|
2824
|
+
(type & SLJIT_32) ? "32" : "",
|
|
2825
|
+
(type & SLJIT_SIMD_LANE_ZERO) ? "_z" : "",
|
|
2826
|
+
(type & SLJIT_SIMD_LANE_SIGNED) ? "_s" : "",
|
|
2827
|
+
(8 << SLJIT_SIMD_GET_REG_SIZE(type)),
|
|
2828
|
+
(type & SLJIT_SIMD_FLOAT) ? "f" : "",
|
|
2829
|
+
(8 << SLJIT_SIMD_GET_ELEM_SIZE(type)));
|
|
2830
|
+
|
|
2831
|
+
sljit_verbose_freg(compiler, freg);
|
|
2832
|
+
fprintf(compiler->verbose, "[%d], ", lane_index);
|
|
2833
|
+
if (type & SLJIT_SIMD_FLOAT)
|
|
2834
|
+
sljit_verbose_fparam(compiler, srcdst, srcdstw);
|
|
2835
|
+
else
|
|
2836
|
+
sljit_verbose_param(compiler, srcdst, srcdstw);
|
|
2837
|
+
fprintf(compiler->verbose, "\n");
|
|
2838
|
+
}
|
|
2839
|
+
#endif
|
|
2840
|
+
CHECK_RETURN_OK;
|
|
2841
|
+
}
|
|
2842
|
+
|
|
2843
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type,
|
|
2844
|
+
sljit_s32 freg,
|
|
2845
|
+
sljit_s32 src, sljit_s32 src_lane_index)
|
|
2846
|
+
{
|
|
2847
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2848
|
+
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD));
|
|
2849
|
+
CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(0)) == 0);
|
|
2850
|
+
CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));
|
|
2851
|
+
CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type));
|
|
2852
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0));
|
|
2853
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(src, 0));
|
|
2854
|
+
CHECK_ARGUMENT(src_lane_index >= 0 && src_lane_index < (1 << (SLJIT_SIMD_GET_REG_SIZE(type) - SLJIT_SIMD_GET_ELEM_SIZE(type))));
|
|
2855
|
+
#endif
|
|
2856
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2857
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
2858
|
+
if (type & SLJIT_SIMD_TEST)
|
|
2859
|
+
CHECK_RETURN_OK;
|
|
2860
|
+
if (sljit_emit_simd_lane_replicate(compiler, type | SLJIT_SIMD_TEST, freg, src, src_lane_index) == SLJIT_ERR_UNSUPPORTED) {
|
|
2861
|
+
fprintf(compiler->verbose, " # simd_lane_replicate: unsupported form, no instructions are emitted\n");
|
|
2862
|
+
CHECK_RETURN_OK;
|
|
2863
|
+
}
|
|
2864
|
+
|
|
2865
|
+
fprintf(compiler->verbose, " simd_lane_replicate.%d.%s%d ",
|
|
2866
|
+
(8 << SLJIT_SIMD_GET_REG_SIZE(type)),
|
|
2867
|
+
(type & SLJIT_SIMD_FLOAT) ? "f" : "",
|
|
2868
|
+
(8 << SLJIT_SIMD_GET_ELEM_SIZE(type)));
|
|
2869
|
+
|
|
2870
|
+
sljit_verbose_freg(compiler, freg);
|
|
2871
|
+
fprintf(compiler->verbose, ", ");
|
|
2872
|
+
sljit_verbose_freg(compiler, src);
|
|
2873
|
+
fprintf(compiler->verbose, "[%d]\n", src_lane_index);
|
|
2874
|
+
}
|
|
2875
|
+
#endif
|
|
2876
|
+
CHECK_RETURN_OK;
|
|
2877
|
+
}
|
|
2878
|
+
|
|
2879
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type,
|
|
2880
|
+
sljit_s32 freg,
|
|
2881
|
+
sljit_s32 src, sljit_sw srcw)
|
|
2882
|
+
{
|
|
2883
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2884
|
+
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD));
|
|
2885
|
+
CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK2(SLJIT_SIMD_EXTEND_SIGNED)) == 0);
|
|
2886
|
+
CHECK_ARGUMENT((type & (SLJIT_SIMD_EXTEND_SIGNED | SLJIT_SIMD_FLOAT)) != (SLJIT_SIMD_EXTEND_SIGNED | SLJIT_SIMD_FLOAT));
|
|
2887
|
+
CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));
|
|
2888
|
+
CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM2_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type));
|
|
2889
|
+
CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_ELEM2_SIZE(type));
|
|
2890
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0));
|
|
2891
|
+
FUNCTION_FCHECK(src, srcw, SLJIT_SIMD_GET_ELEM_SIZE(type) == 2);
|
|
2892
|
+
#endif
|
|
2893
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2894
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
2895
|
+
if (type & SLJIT_SIMD_TEST)
|
|
2896
|
+
CHECK_RETURN_OK;
|
|
2897
|
+
if (sljit_emit_simd_extend(compiler, type | SLJIT_SIMD_TEST, freg, src, srcw) == SLJIT_ERR_UNSUPPORTED) {
|
|
2898
|
+
fprintf(compiler->verbose, " # simd_extend: unsupported form, no instructions are emitted\n");
|
|
2899
|
+
CHECK_RETURN_OK;
|
|
2900
|
+
}
|
|
2901
|
+
|
|
2902
|
+
fprintf(compiler->verbose, " simd_load_extend%s.%d.%s%d.%s%d ",
|
|
2903
|
+
(type & SLJIT_SIMD_EXTEND_SIGNED) ? "_s" : "",
|
|
2904
|
+
(8 << SLJIT_SIMD_GET_REG_SIZE(type)),
|
|
2905
|
+
(type & SLJIT_SIMD_FLOAT) ? "f" : "",
|
|
2906
|
+
(8 << SLJIT_SIMD_GET_ELEM2_SIZE(type)),
|
|
2907
|
+
(type & SLJIT_SIMD_FLOAT) ? "f" : "",
|
|
2908
|
+
(8 << SLJIT_SIMD_GET_ELEM_SIZE(type)));
|
|
2909
|
+
|
|
2910
|
+
sljit_verbose_freg(compiler, freg);
|
|
2911
|
+
fprintf(compiler->verbose, ", ");
|
|
2912
|
+
sljit_verbose_fparam(compiler, src, srcw);
|
|
2913
|
+
fprintf(compiler->verbose, "\n");
|
|
2914
|
+
}
|
|
2915
|
+
#endif
|
|
2916
|
+
CHECK_RETURN_OK;
|
|
2917
|
+
}
|
|
2918
|
+
|
|
2919
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type,
|
|
2920
|
+
sljit_s32 freg,
|
|
2921
|
+
sljit_s32 dst, sljit_sw dstw)
|
|
2922
|
+
{
|
|
2923
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2924
|
+
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD));
|
|
2925
|
+
CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(SLJIT_32)) == SLJIT_SIMD_STORE);
|
|
2926
|
+
CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));
|
|
2927
|
+
CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type));
|
|
2928
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0));
|
|
2929
|
+
FUNCTION_CHECK_DST(dst, dstw);
|
|
2930
|
+
#endif
|
|
2931
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2932
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
2933
|
+
if (type & SLJIT_SIMD_TEST)
|
|
2934
|
+
CHECK_RETURN_OK;
|
|
2935
|
+
if (sljit_emit_simd_sign(compiler, type | SLJIT_SIMD_TEST, freg, dst, dstw) == SLJIT_ERR_UNSUPPORTED) {
|
|
2936
|
+
fprintf(compiler->verbose, " # simd_sign: unsupported form, no instructions are emitted\n");
|
|
2937
|
+
CHECK_RETURN_OK;
|
|
2938
|
+
}
|
|
2939
|
+
|
|
2940
|
+
fprintf(compiler->verbose, " simd_store_sign%s.%d.%s%d ",
|
|
2941
|
+
(type & SLJIT_32) ? "32" : "",
|
|
2942
|
+
(8 << SLJIT_SIMD_GET_REG_SIZE(type)),
|
|
2943
|
+
(type & SLJIT_SIMD_FLOAT) ? "f" : "",
|
|
2944
|
+
(8 << SLJIT_SIMD_GET_ELEM_SIZE(type)));
|
|
2945
|
+
|
|
2946
|
+
sljit_verbose_freg(compiler, freg);
|
|
2947
|
+
fprintf(compiler->verbose, ", ");
|
|
2948
|
+
sljit_verbose_param(compiler, dst, dstw);
|
|
2949
|
+
fprintf(compiler->verbose, "\n");
|
|
2950
|
+
}
|
|
2951
|
+
#endif
|
|
2952
|
+
CHECK_RETURN_OK;
|
|
2953
|
+
}
|
|
2954
|
+
|
|
2955
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type,
|
|
2956
|
+
sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg)
|
|
2957
|
+
{
|
|
2958
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2959
|
+
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD));
|
|
2960
|
+
CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(0)) >= SLJIT_SIMD_OP2_AND && (type & SLJIT_SIMD_TYPE_MASK(0)) <= SLJIT_SIMD_OP2_XOR);
|
|
2961
|
+
CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type));
|
|
2962
|
+
CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) <= SLJIT_SIMD_GET_REG_SIZE(type));
|
|
2963
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(dst_freg, 0));
|
|
2964
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(src1_freg, 0));
|
|
2965
|
+
CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(src2_freg, 0));
|
|
2966
|
+
#endif
|
|
2967
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
2968
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
2969
|
+
if (type & SLJIT_SIMD_TEST)
|
|
2970
|
+
CHECK_RETURN_OK;
|
|
2971
|
+
if (sljit_emit_simd_op2(compiler, type | SLJIT_SIMD_TEST, dst_freg, src1_freg, src2_freg) == SLJIT_ERR_UNSUPPORTED) {
|
|
2972
|
+
fprintf(compiler->verbose, " # simd_op2: unsupported form, no instructions are emitted\n");
|
|
2973
|
+
CHECK_RETURN_OK;
|
|
2974
|
+
}
|
|
2975
|
+
|
|
2976
|
+
fprintf(compiler->verbose, " simd_%s.%d.%s%d ",
|
|
2977
|
+
simd_op2_names[SLJIT_SIMD_GET_OPCODE(type) - 1],
|
|
2978
|
+
(8 << SLJIT_SIMD_GET_REG_SIZE(type)),
|
|
2979
|
+
(type & SLJIT_SIMD_FLOAT) ? "f" : "",
|
|
2980
|
+
(8 << SLJIT_SIMD_GET_ELEM_SIZE(type)));
|
|
2981
|
+
|
|
2982
|
+
sljit_verbose_freg(compiler, dst_freg);
|
|
2983
|
+
fprintf(compiler->verbose, ", ");
|
|
2984
|
+
sljit_verbose_freg(compiler, src1_freg);
|
|
2985
|
+
fprintf(compiler->verbose, ", ");
|
|
2986
|
+
sljit_verbose_freg(compiler, src2_freg);
|
|
2987
|
+
fprintf(compiler->verbose, "\n");
|
|
2988
|
+
}
|
|
2989
|
+
#endif
|
|
2990
|
+
CHECK_RETURN_OK;
|
|
2991
|
+
}
|
|
2992
|
+
|
|
2993
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
|
|
2994
|
+
{
|
|
2995
|
+
/* Any offset is allowed. */
|
|
2996
|
+
SLJIT_UNUSED_ARG(offset);
|
|
2997
|
+
|
|
2998
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
2999
|
+
FUNCTION_CHECK_DST(dst, dstw);
|
|
3000
|
+
#endif
|
|
3001
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
3002
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
3003
|
+
fprintf(compiler->verbose, " local_base ");
|
|
3004
|
+
sljit_verbose_param(compiler, dst, dstw);
|
|
3005
|
+
fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", offset);
|
|
3006
|
+
}
|
|
3007
|
+
#endif
|
|
3008
|
+
CHECK_RETURN_OK;
|
|
3009
|
+
}
|
|
3010
|
+
|
|
3011
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
|
|
3012
|
+
{
|
|
3013
|
+
SLJIT_UNUSED_ARG(init_value);
|
|
3014
|
+
|
|
3015
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
3016
|
+
FUNCTION_CHECK_DST(dst, dstw);
|
|
3017
|
+
#endif
|
|
3018
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
3019
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
3020
|
+
fprintf(compiler->verbose, " const ");
|
|
3021
|
+
sljit_verbose_param(compiler, dst, dstw);
|
|
3022
|
+
fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", init_value);
|
|
3023
|
+
}
|
|
3024
|
+
#endif
|
|
3025
|
+
CHECK_RETURN_OK;
|
|
3026
|
+
}
|
|
3027
|
+
|
|
3028
|
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
|
|
3029
|
+
{
|
|
3030
|
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|
3031
|
+
FUNCTION_CHECK_DST(dst, dstw);
|
|
3032
|
+
#endif
|
|
3033
|
+
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|
3034
|
+
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|
3035
|
+
fprintf(compiler->verbose, " mov_addr ");
|
|
3036
|
+
sljit_verbose_param(compiler, dst, dstw);
|
|
3037
|
+
fprintf(compiler->verbose, "\n");
|
|
3038
|
+
}
|
|
3039
|
+
#endif
|
|
3040
|
+
CHECK_RETURN_OK;
|
|
3041
|
+
}
|
|
3042
|
+
|
|
3043
|
+
#else /* !SLJIT_ARGUMENT_CHECKS && !SLJIT_VERBOSE */
|
|
3044
|
+
|
|
3045
|
+
#define SLJIT_SKIP_CHECKS(compiler)
|
|
3046
|
+
|
|
3047
|
+
#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */
|
|
3048
|
+
|
|
3049
|
+
#define SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw) \
|
|
3050
|
+
SLJIT_COMPILE_ASSERT(!(SLJIT_CONV_SW_FROM_F64 & 0x1) && !(SLJIT_CONV_F64_FROM_SW & 0x1) && !(SLJIT_CONV_F64_FROM_UW & 0x1), \
|
|
3051
|
+
invalid_float_opcodes); \
|
|
3052
|
+
if (GET_OPCODE(op) >= SLJIT_CONV_SW_FROM_F64 && GET_OPCODE(op) <= SLJIT_CMP_F64) { \
|
|
3053
|
+
if (GET_OPCODE(op) == SLJIT_CMP_F64) { \
|
|
3054
|
+
CHECK(check_sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw)); \
|
|
3055
|
+
ADJUST_LOCAL_OFFSET(dst, dstw); \
|
|
3056
|
+
ADJUST_LOCAL_OFFSET(src, srcw); \
|
|
3057
|
+
return sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw); \
|
|
3058
|
+
} \
|
|
3059
|
+
if ((GET_OPCODE(op) | 0x1) == SLJIT_CONV_S32_FROM_F64) { \
|
|
3060
|
+
CHECK(check_sljit_emit_fop1_conv_sw_from_f64(compiler, op, dst, dstw, src, srcw)); \
|
|
3061
|
+
ADJUST_LOCAL_OFFSET(dst, dstw); \
|
|
3062
|
+
ADJUST_LOCAL_OFFSET(src, srcw); \
|
|
3063
|
+
return sljit_emit_fop1_conv_sw_from_f64(compiler, op, dst, dstw, src, srcw); \
|
|
3064
|
+
} \
|
|
3065
|
+
if ((GET_OPCODE(op) | 0x1) == SLJIT_CONV_F64_FROM_S32) { \
|
|
3066
|
+
CHECK(check_sljit_emit_fop1_conv_f64_from_w(compiler, op, dst, dstw, src, srcw)); \
|
|
3067
|
+
ADJUST_LOCAL_OFFSET(dst, dstw); \
|
|
3068
|
+
ADJUST_LOCAL_OFFSET(src, srcw); \
|
|
3069
|
+
return sljit_emit_fop1_conv_f64_from_sw(compiler, op, dst, dstw, src, srcw); \
|
|
3070
|
+
} \
|
|
3071
|
+
CHECK(check_sljit_emit_fop1_conv_f64_from_w(compiler, op, dst, dstw, src, srcw)); \
|
|
3072
|
+
ADJUST_LOCAL_OFFSET(dst, dstw); \
|
|
3073
|
+
ADJUST_LOCAL_OFFSET(src, srcw); \
|
|
3074
|
+
return sljit_emit_fop1_conv_f64_from_uw(compiler, op, dst, dstw, src, srcw); \
|
|
3075
|
+
} \
|
|
3076
|
+
CHECK(check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw)); \
|
|
3077
|
+
ADJUST_LOCAL_OFFSET(dst, dstw); \
|
|
3078
|
+
ADJUST_LOCAL_OFFSET(src, srcw);
|
|
3079
|
+
|
|
3080
|
+
#if (!(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) || (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6))
|
|
3081
|
+
|
|
3082
|
+
static sljit_s32 sljit_emit_mem_unaligned(struct sljit_compiler *compiler, sljit_s32 type,
|
|
3083
|
+
sljit_s32 reg,
|
|
3084
|
+
sljit_s32 mem, sljit_sw memw)
|
|
3085
|
+
{
|
|
3086
|
+
SLJIT_SKIP_CHECKS(compiler);
|
|
3087
|
+
|
|
3088
|
+
if (type & SLJIT_MEM_STORE)
|
|
3089
|
+
return sljit_emit_op1(compiler, type & (0xff | SLJIT_32), mem, memw, reg, 0);
|
|
3090
|
+
return sljit_emit_op1(compiler, type & (0xff | SLJIT_32), reg, 0, mem, memw);
|
|
3091
|
+
}
|
|
3092
|
+
|
|
3093
|
+
#endif /* (!SLJIT_CONFIG_MIPS || SLJIT_MIPS_REV >= 6) */
|
|
3094
|
+
|
|
3095
|
+
#if (!(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) || (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)) \
|
|
3096
|
+
&& !(defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32)
|
|
3097
|
+
|
|
3098
|
+
static sljit_s32 sljit_emit_fmem_unaligned(struct sljit_compiler *compiler, sljit_s32 type,
|
|
3099
|
+
sljit_s32 freg,
|
|
3100
|
+
sljit_s32 mem, sljit_sw memw)
|
|
3101
|
+
{
|
|
3102
|
+
SLJIT_SKIP_CHECKS(compiler);
|
|
3103
|
+
|
|
3104
|
+
if (type & SLJIT_MEM_STORE)
|
|
3105
|
+
return sljit_emit_fop1(compiler, type & (0xff | SLJIT_32), mem, memw, freg, 0);
|
|
3106
|
+
return sljit_emit_fop1(compiler, type & (0xff | SLJIT_32), freg, 0, mem, memw);
|
|
3107
|
+
}
|
|
3108
|
+
|
|
3109
|
+
#endif /* (!SLJIT_CONFIG_MIPS || SLJIT_MIPS_REV >= 6) && !SLJIT_CONFIG_ARM */
|
|
3110
|
+
|
|
3111
|
+
/* CPU description section */
|
|
3112
|
+
|
|
3113
|
+
#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)
|
|
3114
|
+
#define SLJIT_CPUINFO_PART1 " 32bit ("
|
|
3115
|
+
#elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
|
|
3116
|
+
#define SLJIT_CPUINFO_PART1 " 64bit ("
|
|
3117
|
+
#else
|
|
3118
|
+
#error "Internal error: CPU type info missing"
|
|
3119
|
+
#endif
|
|
3120
|
+
|
|
3121
|
+
#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
|
|
3122
|
+
#define SLJIT_CPUINFO_PART2 "little endian + "
|
|
3123
|
+
#elif (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN)
|
|
3124
|
+
#define SLJIT_CPUINFO_PART2 "big endian + "
|
|
3125
|
+
#else
|
|
3126
|
+
#error "Internal error: CPU type info missing"
|
|
3127
|
+
#endif
|
|
3128
|
+
|
|
3129
|
+
#if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED)
|
|
3130
|
+
#define SLJIT_CPUINFO_PART3 "unaligned)"
|
|
3131
|
+
#else
|
|
3132
|
+
#define SLJIT_CPUINFO_PART3 "aligned)"
|
|
3133
|
+
#endif
|
|
3134
|
+
|
|
3135
|
+
#define SLJIT_CPUINFO SLJIT_CPUINFO_PART1 SLJIT_CPUINFO_PART2 SLJIT_CPUINFO_PART3
|
|
3136
|
+
|
|
3137
|
+
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
|
|
3138
|
+
# include "sljitNativeX86_common.c"
|
|
3139
|
+
#elif (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
|
|
3140
|
+
# include "sljitNativeARM_32.c"
|
|
3141
|
+
#elif (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
|
|
3142
|
+
# include "sljitNativeARM_32.c"
|
|
3143
|
+
#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
|
|
3144
|
+
# include "sljitNativeARM_T2_32.c"
|
|
3145
|
+
#elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
|
|
3146
|
+
# include "sljitNativeARM_64.c"
|
|
3147
|
+
#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
|
|
3148
|
+
# include "sljitNativePPC_common.c"
|
|
3149
|
+
#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
|
|
3150
|
+
# include "sljitNativeMIPS_common.c"
|
|
3151
|
+
#elif (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)
|
|
3152
|
+
# include "sljitNativeRISCV_common.c"
|
|
3153
|
+
#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
|
|
3154
|
+
# include "sljitNativeS390X.c"
|
|
3155
|
+
#elif (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)
|
|
3156
|
+
# include "sljitNativeLOONGARCH_64.c"
|
|
3157
|
+
#endif
|
|
3158
|
+
|
|
3159
|
+
#include "sljitSerialize.c"
|
|
3160
|
+
|
|
3161
|
+
static SLJIT_INLINE sljit_s32 emit_mov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
|
|
3162
|
+
{
|
|
3163
|
+
#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
|
|
3164
|
+
/* At the moment the pointer size is always equal to sljit_sw. May be changed in the future. */
|
|
3165
|
+
if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_P))
|
|
3166
|
+
return SLJIT_SUCCESS;
|
|
3167
|
+
#else
|
|
3168
|
+
if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_U32 || op == SLJIT_MOV_S32 || op == SLJIT_MOV_P))
|
|
3169
|
+
return SLJIT_SUCCESS;
|
|
3170
|
+
#endif
|
|
3171
|
+
|
|
3172
|
+
SLJIT_SKIP_CHECKS(compiler);
|
|
3173
|
+
return sljit_emit_op1(compiler, op, SLJIT_RETURN_REG, 0, src, srcw);
|
|
3174
|
+
}
|
|
3175
|
+
|
|
3176
|
+
#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
|
|
3177
|
+
&& !((defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && defined __SOFTFP__)
|
|
3178
|
+
|
|
3179
|
+
static SLJIT_INLINE sljit_s32 emit_fmov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
|
|
3180
|
+
{
|
|
3181
|
+
if (src == SLJIT_FR0)
|
|
3182
|
+
return SLJIT_SUCCESS;
|
|
3183
|
+
|
|
3184
|
+
SLJIT_SKIP_CHECKS(compiler);
|
|
3185
|
+
return sljit_emit_fop1(compiler, op, SLJIT_RETURN_FREG, 0, src, srcw);
|
|
3186
|
+
}
|
|
3187
|
+
|
|
3188
|
+
#endif /* !SLJIT_CONFIG_X86_32 && !(SLJIT_CONFIG_ARM_32 && __SOFTFP__) */
|
|
3189
|
+
|
|
3190
|
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
|
|
3191
|
+
{
|
|
3192
|
+
CHECK_ERROR();
|
|
3193
|
+
CHECK(check_sljit_emit_return(compiler, op, src, srcw));
|
|
3194
|
+
|
|
3195
|
+
if (GET_OPCODE(op) < SLJIT_MOV_F64) {
|
|
3196
|
+
FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
|
|
3197
|
+
} else {
|
|
3198
|
+
FAIL_IF(emit_fmov_before_return(compiler, op, src, srcw));
|
|
3199
|
+
}
|
|
3200
|
+
|
|
3201
|
+
SLJIT_SKIP_CHECKS(compiler);
|
|
3202
|
+
return sljit_emit_return_void(compiler);
|
|
3203
|
+
}
|
|
3204
|
+
|
|
3205
|
+
#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
|
|
3206
|
+
&& !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \
|
|
3207
|
+
&& !(defined(SLJIT_CONFIG_LOONGARCH_64) && SLJIT_CONFIG_LOONGARCH_64)
|
|
3208
|
+
|
|
3209
|
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2r(struct sljit_compiler *compiler, sljit_s32 op,
|
|
3210
|
+
sljit_s32 dst_freg,
|
|
3211
|
+
sljit_s32 src1, sljit_sw src1w,
|
|
3212
|
+
sljit_s32 src2, sljit_sw src2w)
|
|
3213
|
+
{
|
|
3214
|
+
CHECK_ERROR();
|
|
3215
|
+
CHECK(check_sljit_emit_fop2r(compiler, op, dst_freg, src1, src1w, src2, src2w));
|
|
3216
|
+
ADJUST_LOCAL_OFFSET(src1, src1w);
|
|
3217
|
+
ADJUST_LOCAL_OFFSET(src2, src2w);
|
|
3218
|
+
|
|
3219
|
+
SLJIT_SKIP_CHECKS(compiler);
|
|
3220
|
+
return sljit_emit_fop2(compiler, op, dst_freg, 0, src1, src1w, src2, src2w);
|
|
3221
|
+
}
|
|
3222
|
+
|
|
3223
|
+
#endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_S390X && !SLJIT_CONFIG_LOONGARCH_64 */
|
|
3224
|
+
|
|
3225
|
+
#if !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) \
|
|
3226
|
+
&& !(defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \
|
|
3227
|
+
&& !(defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)
|
|
3228
|
+
|
|
3229
|
+
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
|
|
3230
|
+
sljit_s32 src1, sljit_sw src1w,
|
|
3231
|
+
sljit_s32 src2, sljit_sw src2w)
|
|
3232
|
+
{
|
|
3233
|
+
/* Default compare for most architectures. */
|
|
3234
|
+
sljit_s32 flags, tmp_src, condition;
|
|
3235
|
+
sljit_sw tmp_srcw;
|
|
3236
|
+
|
|
3237
|
+
CHECK_ERROR_PTR();
|
|
3238
|
+
CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));
|
|
3239
|
+
|
|
3240
|
+
condition = type & 0xff;
|
|
3241
|
+
#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
|
|
3242
|
+
if ((condition == SLJIT_EQUAL || condition == SLJIT_NOT_EQUAL)) {
|
|
3243
|
+
if (src1 == SLJIT_IMM && !src1w) {
|
|
3244
|
+
src1 = src2;
|
|
3245
|
+
src1w = src2w;
|
|
3246
|
+
src2 = SLJIT_IMM;
|
|
3247
|
+
src2w = 0;
|
|
3248
|
+
}
|
|
3249
|
+
if (src2 == SLJIT_IMM && !src2w)
|
|
3250
|
+
return emit_cmp_to0(compiler, type, src1, src1w);
|
|
3251
|
+
}
|
|
3252
|
+
#endif
|
|
3253
|
+
|
|
3254
|
+
if (SLJIT_UNLIKELY(src1 == SLJIT_IMM && src2 != SLJIT_IMM)) {
|
|
3255
|
+
/* Immediate is preferred as second argument by most architectures. */
|
|
3256
|
+
switch (condition) {
|
|
3257
|
+
case SLJIT_LESS:
|
|
3258
|
+
condition = SLJIT_GREATER;
|
|
3259
|
+
break;
|
|
3260
|
+
case SLJIT_GREATER_EQUAL:
|
|
3261
|
+
condition = SLJIT_LESS_EQUAL;
|
|
3262
|
+
break;
|
|
3263
|
+
case SLJIT_GREATER:
|
|
3264
|
+
condition = SLJIT_LESS;
|
|
3265
|
+
break;
|
|
3266
|
+
case SLJIT_LESS_EQUAL:
|
|
3267
|
+
condition = SLJIT_GREATER_EQUAL;
|
|
3268
|
+
break;
|
|
3269
|
+
case SLJIT_SIG_LESS:
|
|
3270
|
+
condition = SLJIT_SIG_GREATER;
|
|
3271
|
+
break;
|
|
3272
|
+
case SLJIT_SIG_GREATER_EQUAL:
|
|
3273
|
+
condition = SLJIT_SIG_LESS_EQUAL;
|
|
3274
|
+
break;
|
|
3275
|
+
case SLJIT_SIG_GREATER:
|
|
3276
|
+
condition = SLJIT_SIG_LESS;
|
|
3277
|
+
break;
|
|
3278
|
+
case SLJIT_SIG_LESS_EQUAL:
|
|
3279
|
+
condition = SLJIT_SIG_GREATER_EQUAL;
|
|
3280
|
+
break;
|
|
3281
|
+
}
|
|
3282
|
+
|
|
3283
|
+
type = condition | (type & (SLJIT_32 | SLJIT_REWRITABLE_JUMP));
|
|
3284
|
+
tmp_src = src1;
|
|
3285
|
+
src1 = src2;
|
|
3286
|
+
src2 = tmp_src;
|
|
3287
|
+
tmp_srcw = src1w;
|
|
3288
|
+
src1w = src2w;
|
|
3289
|
+
src2w = tmp_srcw;
|
|
3290
|
+
}
|
|
3291
|
+
|
|
3292
|
+
if (condition <= SLJIT_NOT_ZERO)
|
|
3293
|
+
flags = SLJIT_SET_Z;
|
|
3294
|
+
else
|
|
3295
|
+
flags = (condition & 0xfe) << VARIABLE_FLAG_SHIFT;
|
|
3296
|
+
|
|
3297
|
+
SLJIT_SKIP_CHECKS(compiler);
|
|
3298
|
+
PTR_FAIL_IF(sljit_emit_op2u(compiler,
|
|
3299
|
+
SLJIT_SUB | flags | (type & SLJIT_32), src1, src1w, src2, src2w));
|
|
3300
|
+
|
|
3301
|
+
SLJIT_SKIP_CHECKS(compiler);
|
|
3302
|
+
return sljit_emit_jump(compiler, condition | (type & (SLJIT_REWRITABLE_JUMP | SLJIT_32)));
|
|
3303
|
+
}
|
|
3304
|
+
|
|
3305
|
+
#endif /* !SLJIT_CONFIG_MIPS */
|
|
3306
|
+
|
|
3307
|
+
#if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32)
|
|
3308
|
+
|
|
3309
|
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)
|
|
3310
|
+
{
|
|
3311
|
+
switch (type) {
|
|
3312
|
+
case SLJIT_UNORDERED_OR_EQUAL:
|
|
3313
|
+
case SLJIT_ORDERED_NOT_EQUAL:
|
|
3314
|
+
return 1;
|
|
3315
|
+
}
|
|
3316
|
+
|
|
3317
|
+
return 0;
|
|
3318
|
+
}
|
|
3319
|
+
|
|
3320
|
+
#endif /* SLJIT_CONFIG_ARM */
|
|
3321
|
+
|
|
3322
|
+
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,
|
|
3323
|
+
sljit_s32 src1, sljit_sw src1w,
|
|
3324
|
+
sljit_s32 src2, sljit_sw src2w)
|
|
3325
|
+
{
|
|
3326
|
+
CHECK_ERROR_PTR();
|
|
3327
|
+
CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w));
|
|
3328
|
+
|
|
3329
|
+
SLJIT_SKIP_CHECKS(compiler);
|
|
3330
|
+
sljit_emit_fop1(compiler, SLJIT_CMP_F64 | ((type & 0xfe) << VARIABLE_FLAG_SHIFT) | (type & SLJIT_32), src1, src1w, src2, src2w);
|
|
3331
|
+
|
|
3332
|
+
SLJIT_SKIP_CHECKS(compiler);
|
|
3333
|
+
return sljit_emit_jump(compiler, type);
|
|
3334
|
+
}
|
|
3335
|
+
|
|
3336
|
+
#if !(defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM) \
|
|
3337
|
+
&& !(defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
|
|
3338
|
+
|
|
3339
|
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type,
|
|
3340
|
+
sljit_s32 reg,
|
|
3341
|
+
sljit_s32 mem, sljit_sw memw)
|
|
3342
|
+
{
|
|
3343
|
+
CHECK_ERROR();
|
|
3344
|
+
CHECK(check_sljit_emit_mem_update(compiler, type, reg, mem, memw));
|
|
3345
|
+
SLJIT_UNUSED_ARG(type);
|
|
3346
|
+
SLJIT_UNUSED_ARG(reg);
|
|
3347
|
+
SLJIT_UNUSED_ARG(mem);
|
|
3348
|
+
SLJIT_UNUSED_ARG(memw);
|
|
3349
|
+
|
|
3350
|
+
return SLJIT_ERR_UNSUPPORTED;
|
|
3351
|
+
}
|
|
3352
|
+
|
|
3353
|
+
#endif /* !SLJIT_CONFIG_ARM && !SLJIT_CONFIG_PPC */
|
|
3354
|
+
|
|
3355
|
+
#if !(defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \
|
|
3356
|
+
&& !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
|
|
3357
|
+
|
|
3358
|
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
|
|
3359
|
+
sljit_s32 freg,
|
|
3360
|
+
sljit_s32 mem, sljit_sw memw)
|
|
3361
|
+
{
|
|
3362
|
+
CHECK_ERROR();
|
|
3363
|
+
CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));
|
|
3364
|
+
|
|
3365
|
+
return sljit_emit_fmem_unaligned(compiler, type, freg, mem, memw);
|
|
3366
|
+
}
|
|
3367
|
+
|
|
3368
|
+
#endif /* !SLJIT_CONFIG_ARM_32 && !SLJIT_CONFIG_MIPS */
|
|
3369
|
+
|
|
3370
|
+
#if !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
|
|
3371
|
+
&& !(defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
|
|
3372
|
+
|
|
3373
|
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler *compiler, sljit_s32 type,
|
|
3374
|
+
sljit_s32 freg,
|
|
3375
|
+
sljit_s32 mem, sljit_sw memw)
|
|
3376
|
+
{
|
|
3377
|
+
CHECK_ERROR();
|
|
3378
|
+
CHECK(check_sljit_emit_fmem_update(compiler, type, freg, mem, memw));
|
|
3379
|
+
SLJIT_UNUSED_ARG(type);
|
|
3380
|
+
SLJIT_UNUSED_ARG(freg);
|
|
3381
|
+
SLJIT_UNUSED_ARG(mem);
|
|
3382
|
+
SLJIT_UNUSED_ARG(memw);
|
|
3383
|
+
|
|
3384
|
+
return SLJIT_ERR_UNSUPPORTED;
|
|
3385
|
+
}
|
|
3386
|
+
|
|
3387
|
+
#endif /* !SLJIT_CONFIG_ARM_64 && !SLJIT_CONFIG_PPC */
|
|
3388
|
+
|
|
3389
|
+
#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
|
|
3390
|
+
&& !(defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM) \
|
|
3391
|
+
&& !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \
|
|
3392
|
+
&& !(defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)
|
|
3393
|
+
|
|
3394
|
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type,
|
|
3395
|
+
sljit_s32 freg,
|
|
3396
|
+
sljit_s32 srcdst, sljit_sw srcdstw)
|
|
3397
|
+
{
|
|
3398
|
+
CHECK_ERROR();
|
|
3399
|
+
CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw));
|
|
3400
|
+
SLJIT_UNUSED_ARG(compiler);
|
|
3401
|
+
SLJIT_UNUSED_ARG(type);
|
|
3402
|
+
SLJIT_UNUSED_ARG(freg);
|
|
3403
|
+
SLJIT_UNUSED_ARG(srcdst);
|
|
3404
|
+
SLJIT_UNUSED_ARG(srcdstw);
|
|
3405
|
+
|
|
3406
|
+
return SLJIT_ERR_UNSUPPORTED;
|
|
3407
|
+
}
|
|
3408
|
+
|
|
3409
|
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type,
|
|
3410
|
+
sljit_s32 freg,
|
|
3411
|
+
sljit_s32 src, sljit_sw srcw)
|
|
3412
|
+
{
|
|
3413
|
+
CHECK_ERROR();
|
|
3414
|
+
CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw));
|
|
3415
|
+
SLJIT_UNUSED_ARG(compiler);
|
|
3416
|
+
SLJIT_UNUSED_ARG(type);
|
|
3417
|
+
SLJIT_UNUSED_ARG(freg);
|
|
3418
|
+
SLJIT_UNUSED_ARG(src);
|
|
3419
|
+
SLJIT_UNUSED_ARG(srcw);
|
|
3420
|
+
|
|
3421
|
+
return SLJIT_ERR_UNSUPPORTED;
|
|
3422
|
+
}
|
|
3423
|
+
|
|
3424
|
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type,
|
|
3425
|
+
sljit_s32 freg, sljit_s32 lane_index,
|
|
3426
|
+
sljit_s32 srcdst, sljit_sw srcdstw)
|
|
3427
|
+
{
|
|
3428
|
+
CHECK_ERROR();
|
|
3429
|
+
CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw));
|
|
3430
|
+
SLJIT_UNUSED_ARG(compiler);
|
|
3431
|
+
SLJIT_UNUSED_ARG(type);
|
|
3432
|
+
SLJIT_UNUSED_ARG(freg);
|
|
3433
|
+
SLJIT_UNUSED_ARG(lane_index);
|
|
3434
|
+
SLJIT_UNUSED_ARG(srcdst);
|
|
3435
|
+
SLJIT_UNUSED_ARG(srcdstw);
|
|
3436
|
+
|
|
3437
|
+
return SLJIT_ERR_UNSUPPORTED;
|
|
3438
|
+
}
|
|
3439
|
+
|
|
3440
|
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type,
|
|
3441
|
+
sljit_s32 freg,
|
|
3442
|
+
sljit_s32 src, sljit_s32 src_lane_index)
|
|
3443
|
+
{
|
|
3444
|
+
CHECK_ERROR();
|
|
3445
|
+
CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index));
|
|
3446
|
+
SLJIT_UNUSED_ARG(compiler);
|
|
3447
|
+
SLJIT_UNUSED_ARG(type);
|
|
3448
|
+
SLJIT_UNUSED_ARG(freg);
|
|
3449
|
+
SLJIT_UNUSED_ARG(src);
|
|
3450
|
+
SLJIT_UNUSED_ARG(src_lane_index);
|
|
3451
|
+
|
|
3452
|
+
return SLJIT_ERR_UNSUPPORTED;
|
|
3453
|
+
}
|
|
3454
|
+
|
|
3455
|
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type,
|
|
3456
|
+
sljit_s32 freg,
|
|
3457
|
+
sljit_s32 src, sljit_sw srcw)
|
|
3458
|
+
{
|
|
3459
|
+
CHECK_ERROR();
|
|
3460
|
+
CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw));
|
|
3461
|
+
SLJIT_UNUSED_ARG(compiler);
|
|
3462
|
+
SLJIT_UNUSED_ARG(type);
|
|
3463
|
+
SLJIT_UNUSED_ARG(freg);
|
|
3464
|
+
SLJIT_UNUSED_ARG(src);
|
|
3465
|
+
SLJIT_UNUSED_ARG(srcw);
|
|
3466
|
+
|
|
3467
|
+
return SLJIT_ERR_UNSUPPORTED;
|
|
3468
|
+
}
|
|
3469
|
+
|
|
3470
|
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type,
|
|
3471
|
+
sljit_s32 freg,
|
|
3472
|
+
sljit_s32 dst, sljit_sw dstw)
|
|
3473
|
+
{
|
|
3474
|
+
CHECK_ERROR();
|
|
3475
|
+
CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw));
|
|
3476
|
+
SLJIT_UNUSED_ARG(compiler);
|
|
3477
|
+
SLJIT_UNUSED_ARG(type);
|
|
3478
|
+
SLJIT_UNUSED_ARG(freg);
|
|
3479
|
+
SLJIT_UNUSED_ARG(dst);
|
|
3480
|
+
SLJIT_UNUSED_ARG(dstw);
|
|
3481
|
+
|
|
3482
|
+
return SLJIT_ERR_UNSUPPORTED;
|
|
3483
|
+
}
|
|
3484
|
+
|
|
3485
|
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type,
|
|
3486
|
+
sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg)
|
|
3487
|
+
{
|
|
3488
|
+
CHECK_ERROR();
|
|
3489
|
+
CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg));
|
|
3490
|
+
SLJIT_UNUSED_ARG(compiler);
|
|
3491
|
+
SLJIT_UNUSED_ARG(type);
|
|
3492
|
+
SLJIT_UNUSED_ARG(dst_freg);
|
|
3493
|
+
SLJIT_UNUSED_ARG(src1_freg);
|
|
3494
|
+
SLJIT_UNUSED_ARG(src2_freg);
|
|
3495
|
+
|
|
3496
|
+
return SLJIT_ERR_UNSUPPORTED;
|
|
3497
|
+
}
|
|
3498
|
+
|
|
3499
|
+
#endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_ARM */
|
|
3500
|
+
|
|
3501
|
+
#if !(defined(SLJIT_CONFIG_X86) && SLJIT_CONFIG_X86) \
|
|
3502
|
+
&& !(defined(SLJIT_CONFIG_ARM) && SLJIT_CONFIG_ARM) \
|
|
3503
|
+
&& !(defined(SLJIT_CONFIG_S390X) && SLJIT_CONFIG_S390X) \
|
|
3504
|
+
&& !(defined(SLJIT_CONFIG_LOONGARCH) && SLJIT_CONFIG_LOONGARCH)
|
|
3505
|
+
|
|
3506
|
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler,
|
|
3507
|
+
sljit_s32 op,
|
|
3508
|
+
sljit_s32 dst_reg,
|
|
3509
|
+
sljit_s32 mem_reg)
|
|
3510
|
+
{
|
|
3511
|
+
SLJIT_UNUSED_ARG(compiler);
|
|
3512
|
+
SLJIT_UNUSED_ARG(op);
|
|
3513
|
+
SLJIT_UNUSED_ARG(dst_reg);
|
|
3514
|
+
SLJIT_UNUSED_ARG(mem_reg);
|
|
3515
|
+
|
|
3516
|
+
CHECK_ERROR();
|
|
3517
|
+
CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg));
|
|
3518
|
+
|
|
3519
|
+
return SLJIT_ERR_UNSUPPORTED;
|
|
3520
|
+
}
|
|
3521
|
+
|
|
3522
|
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler,
|
|
3523
|
+
sljit_s32 op,
|
|
3524
|
+
sljit_s32 src_reg,
|
|
3525
|
+
sljit_s32 mem_reg,
|
|
3526
|
+
sljit_s32 temp_reg)
|
|
3527
|
+
{
|
|
3528
|
+
SLJIT_UNUSED_ARG(compiler);
|
|
3529
|
+
SLJIT_UNUSED_ARG(op);
|
|
3530
|
+
SLJIT_UNUSED_ARG(src_reg);
|
|
3531
|
+
SLJIT_UNUSED_ARG(mem_reg);
|
|
3532
|
+
SLJIT_UNUSED_ARG(temp_reg);
|
|
3533
|
+
|
|
3534
|
+
CHECK_ERROR();
|
|
3535
|
+
CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg));
|
|
3536
|
+
|
|
3537
|
+
return SLJIT_ERR_UNSUPPORTED;
|
|
3538
|
+
}
|
|
3539
|
+
|
|
3540
|
+
#endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_ARM && !SLJIT_CONFIG_S390X && !SLJIT_CONFIG_LOONGARCH */
|
|
3541
|
+
|
|
3542
|
+
#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
|
|
3543
|
+
&& !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
|
|
3544
|
+
|
|
3545
|
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
|
|
3546
|
+
{
|
|
3547
|
+
CHECK_ERROR();
|
|
3548
|
+
CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset));
|
|
3549
|
+
|
|
3550
|
+
ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_SP), offset);
|
|
3551
|
+
|
|
3552
|
+
SLJIT_SKIP_CHECKS(compiler);
|
|
3553
|
+
|
|
3554
|
+
if (offset != 0)
|
|
3555
|
+
return sljit_emit_op2(compiler, SLJIT_ADD, dst, dstw, SLJIT_SP, 0, SLJIT_IMM, offset);
|
|
3556
|
+
return sljit_emit_op1(compiler, SLJIT_MOV, dst, dstw, SLJIT_SP, 0);
|
|
3557
|
+
}
|
|
3558
|
+
|
|
3559
|
+
#endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_ARM_64 */
|
|
3560
|
+
|
|
3561
|
+
#endif /* !SLJIT_CONFIG_UNSUPPORTED */
|