Spin wait gates: tools/spin_waits.py (the nxnative search) lists the loops that only another thread can end, the patch tables carry them as spin lines (857 in 1.4.3, 864 in 1.2.1), the generator sends their back-edges through rt_spin_gate, and the gate pauses the core once per pass and hands the virtual core to a waiter after 50 us of polling (TOTK_SPIN, TOTK_SPIN_HANDOFF_US)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Valiantsin DzerakhandClaude Opus 5.5 committed 2026-10-27 15:51:47 +03:00
1 parent 8e0d6b3119
commit 3984344635
12 files changed
+2368 -17

No files matched your search

+1
View File
@@ -13,6 +13,7 @@ Code copied or adapted from another project is listed here with its source, the
| MacNativeGames RomFS index builder (`TOTKRFS1` layout) | https://github.com/ly05010419/MacNativeGames @ `b75be8cfa704df3701e86130c8ced268e79d6b11` (`games/totk/scripts/prepare_romfs_backend.py`), Copyright (c) 2026 MacNativeGames contributors | MIT | `tools/romfs_index.py` |
| d2r-mobile host thread environment (TLR, TLS, thread object), the origin of MacNativeGames' thread layer; d2r-mobile NVN host object layouts, command record format and NVN front end, as adapted for TotK in MacNativeGames' `d2r_gfx` copy | https://github.com/jhaizhou-ops/d2r-mobile @ `53e7c5bb9ca3ea53e2160005be8fbe920cd9cb53` (`dm/host/thread.c`, `dm/host/hle_thread.c`); the NVN layouts and front end via https://github.com/ly05010419/MacNativeGames @ `b75be8cfa704df3701e86130c8ced268e79d6b11` (`games/totk/third_party/d2r_gfx/gfx/nvn/nvn_obj.h`, the two types of `nvn_tex.h`, `hle_nvn.c`, `totk_nvn_ext.c`, `nvn_impl.h`, `nvn_hmap.h`, `nvn_pool_index.h`, the request checks and mapping semantics of `totk_vpool.c`, the generation stamps of `nvn_dirty.c`, texture mirroring and texel copies of `nvn_mtl.m`; licence in `games/totk/third_party/d2r_gfx/LICENSE`), Copyright (c) 2026 jhaizhou | MIT | `runtime/kernel.c`; `runtime/nvn_obj.h`; `runtime/nvn_api.h`, `runtime/nvn_api_core.c`, `runtime/nvn_hmap.h`, `runtime/nvn_pool_index.h`; `runtime/nvn_api_obj.c` (also `nvn_pace.h`); `runtime/nvn_api_cmd.c`, `runtime/nvn_ext.c`; `runtime/vk_memory.c`, `runtime/vk_texture.c`; `runtime/vk_sync.c` (side effects written after GPU completion, `hle_nvn.c`); `runtime/vk_pipeline.c` (pipeline key and state mapping of `nvn_mtl.m` `pso_key_fill` / `pso_desc`, its `vfmt` vertex formats and the missing-varying fix-up of `msl_varyings`); `runtime/vk_exec.c`, `runtime/vk_exec.h` (op loop, pure-state ops and state defaults of `nvn_mtl.m` `mtl_exec` / `state_op` / `state_reset`); `runtime/vk_exec_xfer.c` (copy, clear, event, counter and conditional-render semantics of `nvn_mtl.m` `copy_t2b` / `copy_b2t` / `copy_t2t` / `clear_tex` / `cond_eval`); `runtime/vk_exec_draw.c` (bind ops, draw and dispatch flow, vertex streams of `nvn_mtl.m` `state_op` / `bind_vertex_streams` / `draw_inner` / `dispatch`) |
| nxnative NVN front end (d2r-mobile's successor): texture view depth-stencil mode bits, stencil-view rule, `Downsample` and indirect draw and dispatch records | https://github.com/seedds/nxnative @ `d5b380b3a80495609c2e751bb994911a638935ad` (`dm/gfx/nvn/hle_nvn.c`, `nvn_obj.h`, `nvn_mtl.m`), Copyright (c) 2026 jhaizhou | MIT | `runtime/nvn_obj.h`, `runtime/nvn_ext.c`, `runtime/nvn_api_cmd.c`, `runtime/vk_exec_draw.c` |
| nxnative spin wait search and gate: loops that only another thread can end, polls that take a spin lock, the gate's wait and hand-off rule; MacNativeGames' TotK port of the gate | https://github.com/seedds/nxnative @ `6d349844880eb0527be77d7e0e4b8d999c0ae2f4` (`dm/tools/patch_nso.py` "Spin waits", `dm/tools/tests/test_spin_waits.py`, `dm/host/hle_thread.c` dm_spin_wait), Copyright (c) 2026 seedds; https://github.com/ly05010419/MacNativeGames @ `a038e6be7608e6f4eba6fc0381026cebf24ef4a3` (`games/totk/runtime/threads.c` runtime_spin_wait), Copyright (c) 2026 MacNativeGames contributors | MIT | `tools/spin_waits.py`, `tests/spin_waits_test.py`, `runtime/kernel.c` (rt_spin_gate) |
| NVN type definitions reconstructed from Darksiders II DWARF information, with MacNativeGames' TotK size annotations | h1k421, via https://github.com/ly05010419/MacNativeGames @ `b75be8cfa704df3701e86130c8ced268e79d6b11` (`games/totk/third_party/d2r_gfx/gfx/nvn/include/nvn.h`), Copyright (c) 2020 h1k421 | MIT | `runtime/nvn.h` (unmodified) |
| Ryujinx.Audio voice state and effects, as ported in MacNativeGames' audio renderer | https://github.com/Ryujinx/Ryujinx, via MacNativeGames @ `b75be8cfa704df3701e86130c8ced268e79d6b11` (`games/totk/runtime/audio_renderer.c`, `audio_effects.c`, `audio_reverb.c`; licence text in `games/totk/third_party/licenses/Ryujinx-Audio.txt`), Copyright (c) Ryujinx Team and Contributors | MIT | `runtime/audren.c` |
| REA agent skill `reverse-engineer-anything` | https://github.com/morluto/rea @ `799e8265b254e225dc1dabdd25e56f0ab7f86bd3`, Copyright (c) 2026 morluto | MIT | `.claude/skills/reverse-engineer-anything/`, `.agents/skills/reverse-engineer-anything/` (pinned in `.claude/skills/skills-lock.json`) |
+10 -6
View File
@@ -205,10 +205,11 @@ def partition(est, max_fns, max_bytes, big_fn):
class Emitter:
"""C for the functions of one module. starts is the set of every function start of the module."""
def __init__(self, mod, starts, patched=None):
def __init__(self, mod, starts, patched=None, spins=None):
self.mod = mod
self.starts = starts
self.patched = patched or {} # {address: (set index, [replacement words])} (recomp/patches.py)
self.spins = spins or {} # {spin wait back-edge: its head} (recomp/patches.py `spin`)
self.uses_patches = False
self.stats = Counter()
self.unsupported = Counter()
@@ -316,10 +317,12 @@ class Emitter:
out.append(patch(ins, a))
elif k == 'op' or k == 'trap':
out.append(' ' + ins.code)
elif k == 'b':
out.append(' ' + jump(ins.target))
elif k == 'bcond':
out.append(f' if ({ins.cond}) {{ {jump(ins.target)} }}')
elif k in ('b', 'bcond'):
j = jump(ins.target)
if self.spins.get(a) == ins.target and entry <= ins.target < end:
j = f'rt_spin_gate(c, {hx(ins.target)}); {j}' # a pass of a spin wait
self.stats['spin_gates'] += 1
out.append(' ' + j if k == 'b' else f' if ({ins.cond}) {{ {j} }}')
elif k == 'bl':
out.append(' ' + call(ins.target, a))
elif k == 'blr':
@@ -414,7 +417,7 @@ def _emitter(name):
path, base = _W['mods'][name]
mod = Module(name, path, base, 'c')
e = _W['emitters'][name] = Emitter(mod, set(_W['starts'][name].tolist()),
_W['patches'].for_module(name, base))
_W['patches'].for_module(name, base), _W['patches'].spins_for(name, base))
return e
@@ -562,6 +565,7 @@ def main():
'br_dispatch': stats['br_dispatch'],
'traps': stats['traps'],
'patched_sites': stats['patched_sites'],
'spin_gates': stats['spin_gates'],
'unsupported': stats['unsupported'],
'external_branches': stats['external_branches'],
'external_calls': stats['external_calls'],
+867
View File
@@ -63,3 +63,870 @@ site output main cc3f58 f9400015 f94012b5 # ldr x21, [x0] -> ldr x21, [x21, #3
site scene main cc3f68 5e21d900 @page:x9 # scvtf s0, s8 -> adrp x9, page
site scene main cc3f70 bd0cc660 2d420520 # str s0, [x19, #0xcc4] -> ldp s0, s1, [x9, #16]
site scene main cc3f74 5e21d921 bd0cc660 # scvtf s1, s9 -> str s0, [x19, #0xcc4]
# Spin waits, from tools/spin_waits.py --exefs build/extracted/v121/exefs --patches recomp/patches-v121.txt: loops that only
# another thread can end; their back-edges pass rt_spin_gate (runtime/kernel.c), TOTK_SPIN=0 keeps the core.
spin main ac600 ac620 ac630 # 13 instructions; loads
spin main ac680 ac6a8 ac6b8 # 15 instructions; loads
spin main ac6f0 ac718 ac728 # 15 instructions; loads
spin main e8544 e854c # 3 instructions; loads
spin main 2457f0 245804 # 6 instructions; loads
spin main 634d3c 634d50 # 6 instructions; loads
spin main 65ddf8 65de0c # 6 instructions; loads
spin main 65fe1c 65fe30 # 6 instructions; loads
spin main 664350 664364 # 6 instructions; loads
spin main 664558 66456c # 6 instructions; loads
spin main 66764c 667660 # 6 instructions; loads
spin main 66fce0 66fcf4 # 6 instructions; loads
spin main 66fe64 66fe78 # 6 instructions; loads
spin main 670af8 670b0c # 6 instructions; loads
spin main 670ee8 670efc # 6 instructions; loads
spin main 671214 671228 # 6 instructions; loads
spin main 673a3c 673a50 # 6 instructions; loads
spin main 673a80 673a94 # 6 instructions; loads
spin main 673ac4 673ad8 # 6 instructions; loads
spin main 673b08 673b1c # 6 instructions; loads
spin main 678774 678788 # 6 instructions; loads
spin main 678814 678828 # 6 instructions; loads
spin main 67a270 67a284 # 6 instructions; loads
spin main 67a5c8 67a5dc # 6 instructions; loads
spin main 67b8a4 67b8b8 # 6 instructions; loads
spin main 67dde8 67ddfc # 6 instructions; loads
spin main 682650 682664 # 6 instructions; loads
spin main 683c5c 683c70 # 6 instructions; loads
spin main 68b1fc 68b210 # 6 instructions; loads
spin main 68ff0c 68ff20 # 6 instructions; loads
spin main 6917ec 691800 # 6 instructions; loads
spin main 6a5338 6a534c # 6 instructions; loads
spin main 6a55b4 6a55c8 # 6 instructions; loads
spin main 6a9488 6a949c # 6 instructions; loads
spin main 6a98b8 6a98cc # 6 instructions; loads
spin main 6ac5bc 6ac5d0 # 6 instructions; loads
spin main 6afad0 6afae4 # 6 instructions; loads
spin main 6bb02c 6bb040 # 6 instructions; loads
spin main 6bb078 6bb08c # 6 instructions; loads
spin main 6c8680 6c8694 # 6 instructions; loads
spin main 6ca094 6ca0a8 # 6 instructions; loads
spin main 6d1404 6d1418 # 6 instructions; loads
spin main 6d8280 6d8294 # 6 instructions; loads
spin main 6de7b4 6de7c8 # 6 instructions; loads
spin main 6e0740 6e0754 # 6 instructions; loads
spin main 6ec574 6ec588 # 6 instructions; loads
spin main 6ec6d4 6ec6e8 # 6 instructions; loads
spin main 708250 708264 # 6 instructions; loads
spin main 708d1c 708d30 # 6 instructions; loads
spin main 7090dc 7090f0 # 6 instructions; loads
spin main 7093ec 709400 # 6 instructions; loads
spin main 709754 709768 # 6 instructions; loads
spin main 709b2c 709b40 # 6 instructions; loads
spin main 709dd0 709de4 # 6 instructions; loads
spin main 709e64 709e78 # 6 instructions; loads
spin main 70a444 70a458 # 6 instructions; loads
spin main 70a718 70a72c # 6 instructions; loads
spin main 70bb8c 70bba8 # 8 instructions; loads
spin main 70bc3c 70bc58 # 8 instructions; loads
spin main 70d6e4 70d6f8 # 6 instructions; loads
spin main 70d8c4 70d8d8 # 6 instructions; loads
spin main 70db14 70db28 # 6 instructions; loads
spin main 70e7b4 70e7d0 # 8 instructions; loads
spin main 70ec04 70ec18 # 6 instructions; loads
spin main 70f140 70f154 # 6 instructions; loads
spin main 70fd10 70fd24 # 6 instructions; loads
spin main 70fe4c 70fe60 # 6 instructions; loads
spin main 7101b8 7101cc # 6 instructions; loads
spin main 7109a4 7109b8 # 6 instructions; loads
spin main 710f04 710f18 # 6 instructions; loads
spin main 7111a4 7111b8 # 6 instructions; loads
spin main 711424 711438 # 6 instructions; loads
spin main 71144c 711460 # 6 instructions; loads
spin main 711474 711488 # 6 instructions; loads
spin main 711ccc 711ce0 # 6 instructions; loads
spin main 711cf4 711d08 # 6 instructions; loads
spin main 712cd0 712ce4 # 6 instructions; loads
spin main 712dc0 712dd4 # 6 instructions; loads
spin main 7130f8 71310c # 6 instructions; loads
spin main 716398 7163ac # 6 instructions; loads
spin main 7163c0 7163d4 # 6 instructions; loads
spin main 7163e8 7163fc # 6 instructions; loads
spin main 717b40 717b54 # 6 instructions; loads
spin main 7180fc 718110 # 6 instructions; loads
spin main 71819c 7181b0 # 6 instructions; loads
spin main 7187c8 7187dc # 6 instructions; loads
spin main 719124 719138 # 6 instructions; loads
spin main 71a638 71a64c # 6 instructions; loads
spin main 71cec8 71cedc # 6 instructions; loads
spin main 71cef0 71cf04 # 6 instructions; loads
spin main 71fcac 71fcc0 # 6 instructions; loads
spin main 71fcd4 71fce8 # 6 instructions; loads
spin main 71fcfc 71fd10 # 6 instructions; loads
spin main 71fd24 71fd38 # 6 instructions; loads
spin main 71fd4c 71fd60 # 6 instructions; loads
spin main 71fd74 71fd88 # 6 instructions; loads
spin main 71fd9c 71fdb0 # 6 instructions; loads
spin main 71fdc4 71fdd8 # 6 instructions; loads
spin main 71fdec 71fe00 # 6 instructions; loads
spin main 71fe14 71fe28 # 6 instructions; loads
spin main 71fe3c 71fe50 # 6 instructions; loads
spin main 71fe64 71fe78 # 6 instructions; loads
spin main 71fe8c 71fea0 # 6 instructions; loads
spin main 720678 72068c # 6 instructions; loads
spin main 7206a0 7206b4 # 6 instructions; loads
spin main 7206c8 7206dc # 6 instructions; loads
spin main 7206f0 720704 # 6 instructions; loads
spin main 720b0c 720b20 # 6 instructions; loads
spin main 720f40 720f54 # 6 instructions; loads
spin main 7214d0 7214e4 # 6 instructions; loads
spin main 721a90 721aa4 # 6 instructions; loads
spin main 721f28 721f3c # 6 instructions; loads
spin main 721f50 721f64 # 6 instructions; loads
spin main 72590c 725920 # 6 instructions; loads
spin main 726340 726354 # 6 instructions; loads
spin main 7265d4 7265e8 # 6 instructions; loads
spin main 726620 726634 # 6 instructions; loads
spin main 727d28 727d3c # 6 instructions; loads
spin main 727d50 727d64 # 6 instructions; loads
spin main 729da0 729db4 # 6 instructions; loads
spin main 729de8 729dfc # 6 instructions; loads
spin main 72aa08 72aa1c # 6 instructions; loads
spin main 72aa30 72aa44 # 6 instructions; loads
spin main 72aef4 72af08 # 6 instructions; loads
spin main 72b4cc 72b4e0 # 6 instructions; loads
spin main 732c8c 732ca0 # 6 instructions; loads
spin main 732cd0 732ce4 # 6 instructions; loads
spin main 732cf8 732d0c # 6 instructions; loads
spin main 733be8 733bfc # 6 instructions; loads
spin main 737fc4 737fd8 # 6 instructions; loads
spin main 7395fc 739610 # 6 instructions; loads
spin main 73a8b8 73a8cc # 6 instructions; loads
spin main 73a8f8 73a90c # 6 instructions; loads
spin main 73add0 73ade4 # 6 instructions; loads
spin main 73aff4 73b008 # 6 instructions; loads
spin main 73b074 73b088 # 6 instructions; loads
spin main 73b3f0 73b404 # 6 instructions; loads
spin main 73bd4c 73bd60 # 6 instructions; loads
spin main 73d330 73d344 # 6 instructions; loads
spin main 73ea0c 73ea20 # 6 instructions; loads
spin main 7877ac 7877c0 # 6 instructions; loads
spin main 78c7b0 78c7c4 # 6 instructions; loads
spin main 78c8ac 78c8c0 # 6 instructions; loads
spin main 78d5ec 78d600 # 6 instructions; loads
spin main 78d7d0 78d7e4 # 6 instructions; loads
spin main 78db70 78db84 # 6 instructions; loads
spin main 78dbe0 78dbf4 # 6 instructions; loads
spin main 78e298 78e2ac # 6 instructions; loads
spin main 78ebb8 78ebcc # 6 instructions; loads
spin main 791164 791178 # 6 instructions; loads
spin main 7911b8 7911cc # 6 instructions; loads
spin main 791c28 791c3c # 6 instructions; loads
spin main 791cac 791cc0 # 6 instructions; loads
spin main 7923dc 7923f0 # 6 instructions; loads
spin main 7946f8 79470c # 6 instructions; loads
spin main 79474c 794760 # 6 instructions; loads
spin main 795dfc 795e10 # 6 instructions; loads
spin main 795f58 795f6c # 6 instructions; loads
spin main 79632c 796348 # 8 instructions; loads
spin main 7a23ac 7a23c0 # 6 instructions; loads
spin main 7a23d4 7a23e8 # 6 instructions; loads
spin main 7a267c 7a2690 # 6 instructions; loads
spin main 7a26d8 7a26ec # 6 instructions; loads
spin main 7a3a5c 7a3a70 # 6 instructions; loads
spin main 7aec90 7aeca4 # 6 instructions; loads
spin main 7b5c70 7b5c84 # 6 instructions; loads
spin main 7bc3b8 7bc3cc # 6 instructions; loads
spin main 7bc60c 7bc620 # 6 instructions; loads
spin main 7db040 7db054 # 6 instructions; loads
spin main 7ddfb0 7ddfc4 # 6 instructions; loads
spin main 809758 80976c # 6 instructions; loads
spin main 825de4 825df8 # 6 instructions; loads
spin main 825e68 825e7c # 6 instructions; loads
spin main 825fb4 825fc8 # 6 instructions; loads
spin main 826080 826094 # 6 instructions; loads
spin main 828158 82816c # 6 instructions; loads
spin main 838340 838354 # 6 instructions; loads
spin main 842fbc 842fd0 # 6 instructions; loads
spin main 8440e8 8440fc # 6 instructions; loads
spin main 8464f4 846508 # 6 instructions; loads
spin main 84cbb0 84cbc4 # 6 instructions; loads
spin main 84cbf8 84cc0c # 6 instructions; loads
spin main 84d430 84d444 # 6 instructions; loads
spin main 85db98 85dbac # 6 instructions; loads
spin main 85ed2c 85ed40 # 6 instructions; loads
spin main 860d64 860d78 # 6 instructions; loads
spin main 867f4c 868048 # 4 instructions; loads
spin main 8876e0 8876f4 # 6 instructions; loads
spin main 887c50 887c64 # 6 instructions; loads
spin main 892ff4 893008 # 6 instructions; loads
spin main 893448 89345c # 6 instructions; loads
spin main 893a04 893a18 # 6 instructions; loads
spin main 893b14 893b28 # 6 instructions; loads
spin main 895210 895224 # 6 instructions; loads
spin main 895238 89524c # 6 instructions; loads
spin main 8b6b60 8b6b74 # 6 instructions; loads
spin main 8b7ff0 8b8010 # 9 instructions; loads
spin main 8ceed8 8ceeec # 6 instructions; loads
spin main 8cf204 8cf218 # 6 instructions; loads
spin main 8cf520 8cf534 # 6 instructions; loads
spin main 8cf6b8 8cf6cc # 6 instructions; loads
spin main 8cf940 8cf954 # 6 instructions; loads
spin main 8cfb94 8cfba8 # 6 instructions; loads
spin main 8e763c 8e764c # 5 instructions; loads
spin main 8e7898 8e78c4 # 12 instructions; loads
spin main 8e78d8 8e78e8 # 5 instructions; loads
spin main 8e8114 8e8128 # 6 instructions; loads
spin main 90750c 907520 # 6 instructions; loads
spin main 907534 907548 # 6 instructions; loads
spin main 90755c 907570 # 6 instructions; loads
spin main 907584 907598 # 6 instructions; loads
spin main 908a84 908a98 # 6 instructions; loads
spin main 909250 909264 # 6 instructions; loads
spin main 91b3f4 91b408 # 6 instructions; loads
spin main 91b41c 91b430 # 6 instructions; loads
spin main 91dc0c 91dc20 # 6 instructions; loads
spin main 91dfbc 91dfd0 # 6 instructions; loads
spin main 91e390 91e3a4 # 6 instructions; loads
spin main 91e764 91e778 # 6 instructions; loads
spin main 923cc4 923cd8 # 6 instructions; loads
spin main 95517c 9551ac # 13 instructions; loads
spin main 9551c0 9551d0 # 5 instructions; loads
spin main 95f63c 95f66c # 13 instructions; loads
spin main 95f680 95f690 # 5 instructions; loads
spin main 96bb74 96bb84 # 5 instructions; loads
spin main 97266c 972688 # 8 instructions; loads
spin main 972738 972754 # 8 instructions; loads
spin main 9b677c 9b6790 # 6 instructions; loads
spin main 9d73b8 9d73cc # 6 instructions; loads
spin main 9e10ac 9e10c0 # 6 instructions; loads
spin main 9e9470 9e9484 # 6 instructions; loads
spin main 9ed71c 9ed730 # 6 instructions; loads
spin main 9f7adc 9f7af0 # 6 instructions; loads
spin main 9f7b04 9f7b18 # 6 instructions; loads
spin main 9f7b2c 9f7b40 # 6 instructions; loads
spin main a06cd8 a06cec # 6 instructions; loads
spin main a0cfe8 a0cffc # 6 instructions; loads
spin main a2abc0 a2abd4 # 6 instructions; loads
spin main a6d6f8 a6d70c # 6 instructions; loads
spin main a6edec a6ee00 # 6 instructions; loads
spin main a6ee30 a6ee44 # 6 instructions; loads
spin main a6ee74 a6ee88 # 6 instructions; loads
spin main a6f560 a6f574 # 6 instructions; loads
spin main a7e134 a7e1bc # 35 instructions; loads
spin main a84b24 a84b38 # 6 instructions; loads
spin main a84e3c a84e50 # 6 instructions; loads
spin main a84eec a84f00 # 6 instructions; loads
spin main a84f8c a84fa0 # 6 instructions; loads
spin main a8503c a85050 # 6 instructions; loads
spin main ab8898 ab88ac # 6 instructions; loads
spin main ac3cd8 ac3cec # 6 instructions; loads
spin main ac3d64 ac3d78 # 6 instructions; loads
spin main ac3fe4 ac3ff8 # 6 instructions; loads
spin main ac40e4 ac40f8 # 6 instructions; loads
spin main ac4740 ac4754 # 6 instructions; loads
spin main ac4890 ac48a4 # 6 instructions; loads
spin main ac5604 ac5618 # 6 instructions; loads
spin main ac58e0 ac58f4 # 6 instructions; loads
spin main ac798c ac79a0 # 6 instructions; loads
spin main ac79b4 ac79c8 # 6 instructions; loads
spin main ae567c ae5690 # 6 instructions; loads
spin main ae6da0 ae6db4 # 6 instructions; loads
spin main b1267c b12690 # 6 instructions; loads
spin main b12d5c b12d70 # 6 instructions; loads
spin main b15df0 b15e04 # 6 instructions; loads
spin main b1afbc b1b014 # 7 instructions; loads
spin main b2fa8c b2faa0 # 6 instructions; loads
spin main b35374 b35388 # 6 instructions; loads
spin main b386f4 b38708 # 6 instructions; loads
spin main b3871c b38730 # 6 instructions; loads
spin main b38744 b38758 # 6 instructions; loads
spin main b38780 b38794 # 6 instructions; loads
spin main b387a8 b387bc # 6 instructions; loads
spin main b387d0 b387e4 # 6 instructions; loads
spin main b53ce8 b53cfc # 6 instructions; loads
spin main b53e04 b53e18 # 6 instructions; loads
spin main b54178 b5418c # 6 instructions; loads
spin main b54688 b5469c # 6 instructions; loads
spin main b599f0 b59a04 # 6 instructions; loads
spin main b59a18 b59a2c # 6 instructions; loads
spin main b5f4ec b5f4fc # 5 instructions; loads
spin main b6f988 b6f99c # 6 instructions; loads
spin main b6faa4 b6fab8 # 6 instructions; loads
spin main b6fe28 b6fe3c # 6 instructions; loads
spin main b707b0 b707c4 # 6 instructions; loads
spin main b70814 b70828 # 6 instructions; loads
spin main b70974 b70988 # 6 instructions; loads
spin main b70b08 b70b1c # 6 instructions; loads
spin main b74104 b74118 # 6 instructions; loads
spin main b7426c b74280 # 6 instructions; loads
spin main b7e57c b7e590 # 6 instructions; loads
spin main b940fc b94110 # 6 instructions; loads
spin main b973a0 b973b4 # 6 instructions; loads
spin main b97998 b979ac # 6 instructions; loads
spin main b97be4 b97bf8 # 6 instructions; loads
spin main bbaaf4 bbab08 # 6 instructions; loads
spin main bbab1c bbab30 # 6 instructions; loads
spin main bc1fd8 bc1fec # 6 instructions; loads
spin main bc2078 bc208c # 6 instructions; loads
spin main bc20a0 bc20b4 # 6 instructions; loads
spin main bc2168 bc217c # 6 instructions; loads
spin main be3d24 be3d38 # 6 instructions; loads
spin main bf9fc4 bf9fd8 # 6 instructions; loads
spin main bfb184 bfb198 # 6 instructions; loads
spin main c1e5c0 c1e5d4 # 6 instructions; loads
spin main c4657c c46590 # 6 instructions; loads
spin main c50574 c50588 # 6 instructions; loads
spin main c51810 c51824 # 6 instructions; loads
spin main cb300c cb3020 # 6 instructions; loads
spin main cb3f68 cb3f7c # 6 instructions; loads
spin main cb3fac cb3fc0 # 6 instructions; loads
spin main cb4694 cb46a8 # 6 instructions; loads
spin main cb46d8 cb46ec # 6 instructions; loads
spin main cb48c4 cb48d8 # 6 instructions; loads
spin main cb59ec cb5a00 # 6 instructions; loads
spin main cb6f68 cb6f7c # 6 instructions; loads
spin main cba458 cba46c # 6 instructions; loads
spin main cce918 cce92c # 6 instructions; loads
spin main cd0144 cd0150 cd019c cd01b4 # 29 instructions; loads
spin main cd1fc0 cd1fd4 # 6 instructions; loads
spin main cf3c94 cf3ca8 # 6 instructions; loads
spin main d0b2a8 d0b2bc # 6 instructions; loads
spin main d105b4 d105c8 # 6 instructions; loads
spin main d11018 d1102c # 6 instructions; loads
spin main d1109c d110b0 # 6 instructions; loads
spin main d11148 d1115c # 6 instructions; loads
spin main d113a0 d113b4 # 6 instructions; loads
spin main d113c8 d113dc # 6 instructions; loads
spin main d113fc d11410 # 6 instructions; loads
spin main d11644 d11658 # 6 instructions; loads
spin main d12028 d12044 # 8 instructions; loads
spin main d129a8 d129bc # 6 instructions; loads
spin main d12d80 d12d94 # 6 instructions; loads
spin main d12dc8 d12ddc # 6 instructions; loads
spin main d12df0 d12e04 # 6 instructions; loads
spin main d12e18 d12e2c # 6 instructions; loads
spin main d12e84 d12e98 # 6 instructions; loads
spin main d12eb0 d12ec4 # 6 instructions; loads
spin main d12ed8 d12eec # 6 instructions; loads
spin main d12fe0 d12ff4 # 6 instructions; loads
spin main d17248 d1725c # 6 instructions; loads
spin main d17f58 d17f6c # 6 instructions; loads
spin main d189d0 d189e4 # 6 instructions; loads
spin main d18bac d18bc0 # 6 instructions; loads
spin main d2d2a0 d2d2b4 # 6 instructions; loads
spin main d2d430 d2d444 # 6 instructions; loads
spin main d337e4 d337f8 # 6 instructions; loads
spin main d33e1c d33e30 # 6 instructions; loads
spin main d34178 d3418c # 6 instructions; loads
spin main d34278 d3428c # 6 instructions; loads
spin main d3472c d34740 # 6 instructions; loads
spin main d3486c d34880 # 6 instructions; loads
spin main d35a9c d35ab0 # 6 instructions; loads
spin main d365a8 d365bc # 6 instructions; loads
spin main d365d4 d365e8 # 6 instructions; loads
spin main d38898 d388ac # 6 instructions; loads
spin main d3d6c0 d3d6d4 # 6 instructions; loads
spin main d3d6e8 d3d6fc # 6 instructions; loads
spin main d3f05c d3f070 # 6 instructions; loads
spin main d54c90 d54ca4 # 6 instructions; loads
spin main d54e14 d54e28 # 6 instructions; loads
spin main d55940 d55954 # 6 instructions; loads
spin main d56848 d5685c # 6 instructions; loads
spin main d5ef1c d5ef30 # 6 instructions; loads
spin main d5ef80 d5ef94 # 6 instructions; loads
spin main d66218 d6622c # 6 instructions; loads
spin main d69544 d69558 # 6 instructions; loads
spin main d6956c d69580 # 6 instructions; loads
spin main d7663c d76650 # 6 instructions; loads
spin main d7b1e4 d7b1f8 # 6 instructions; loads
spin main d7ca84 d7caa0 # 8 instructions; loads
spin main d808f4 d80908 # 6 instructions; loads
spin main d82a8c d82aa0 # 6 instructions; loads
spin main d82c10 d82c24 # 6 instructions; loads
spin main d85fc8 d86000 # 8 instructions; loads
spin main d86030 d86068 # 8 instructions; loads
spin main d8bb9c d8bbb0 # 6 instructions; loads
spin main d8be7c d8be90 # 6 instructions; loads
spin main d8dfe4 d8dff8 # 6 instructions; loads
spin main d8f9d4 d8f9e8 # 6 instructions; loads
spin main d90a58 d90a6c # 6 instructions; loads
spin main d90e74 d90e88 # 6 instructions; loads
spin main d92afc d92b10 # 6 instructions; loads
spin main d93320 d93334 # 6 instructions; loads
spin main d93b10 d93b24 # 6 instructions; loads
spin main d9cbe8 d9cbfc # 6 instructions; loads
spin main d9fe88 d9fe9c # 6 instructions; loads
spin main dc8368 dc837c # 6 instructions; loads
spin main de3ec0 de3ed4 # 6 instructions; loads
spin main dec308 dec31c # 6 instructions; loads
spin main dfe0bc dfe0d0 # 6 instructions; loads
spin main e3ef08 e3ef1c # 6 instructions; loads
spin main e3f1ec e3f200 # 6 instructions; loads
spin main e3f4d0 e3f4e4 # 6 instructions; loads
spin main e3f7b4 e3f7c8 # 6 instructions; loads
spin main e42c54 e42c68 # 6 instructions; loads
spin main e4a83c e4a850 # 6 instructions; loads
spin main e4ab60 e4ab74 # 6 instructions; loads
spin main e5413c e54150 # 6 instructions; loads
spin main e56300 e56314 # 6 instructions; loads
spin main e599b8 e599cc # 6 instructions; loads
spin main e59cc4 e59cd8 # 6 instructions; loads
spin main e59db0 e59dc4 # 6 instructions; loads
spin main e5dea0 e5deb4 # 6 instructions; loads
spin main e5eb04 e5eb18 # 6 instructions; loads
spin main e602c4 e602d8 # 6 instructions; loads
spin main e64d84 e64d98 # 6 instructions; loads
spin main e67d5c e67d70 # 6 instructions; loads
spin main e686b8 e686cc # 6 instructions; loads
spin main e6bd64 e6bd78 # 6 instructions; loads
spin main e75788 e7579c # 6 instructions; loads
spin main e7a790 e7a7a4 # 6 instructions; loads
spin main e892bc e892d0 # 6 instructions; loads
spin main e892f4 e89308 # 6 instructions; loads
spin main e894b4 e894c8 # 6 instructions; loads
spin main e8959c e895b0 # 6 instructions; loads
spin main e92610 e92624 # 6 instructions; loads
spin main e99480 e99494 # 6 instructions; loads
spin main e995d4 e995e8 # 6 instructions; loads
spin main e99b84 e99b98 # 6 instructions; loads
spin main e9a670 e9a684 # 6 instructions; loads
spin main e9a8c4 e9a8d8 # 6 instructions; loads
spin main e9aa38 e9aa4c # 6 instructions; loads
spin main e9abac e9abc0 # 6 instructions; loads
spin main e9ae58 e9ae6c # 6 instructions; loads
spin main e9b338 e9b34c # 6 instructions; loads
spin main e9b4a4 e9b4b8 # 6 instructions; loads
spin main e9bc7c e9bc90 # 6 instructions; loads
spin main e9c268 e9c27c # 6 instructions; loads
spin main e9c294 e9c2a8 # 6 instructions; loads
spin main e9d21c e9d230 # 6 instructions; loads
spin main e9d5e8 e9d5fc # 6 instructions; loads
spin main e9d610 e9d624 # 6 instructions; loads
spin main e9f978 e9f98c # 6 instructions; loads
spin main e9f9b8 e9f9cc # 6 instructions; loads
spin main e9f9e0 e9f9f4 # 6 instructions; loads
spin main e9fa08 e9fa1c # 6 instructions; loads
spin main e9ffec ea0000 # 6 instructions; loads
spin main ea0014 ea0028 # 6 instructions; loads
spin main ea1454 ea1468 # 6 instructions; loads
spin main eacd8c eacda0 # 6 instructions; loads
spin main eb8ec0 eb8ed4 # 6 instructions; loads
spin main ed2f5c ed2f70 # 6 instructions; loads
spin main ed34f0 ed3504 # 6 instructions; loads
spin main ed3dc0 ed3dd4 # 6 instructions; loads
spin main ed3df0 ed3e04 # 6 instructions; loads
spin main ed43b4 ed43c8 # 6 instructions; loads
spin main ed43e4 ed43f8 # 6 instructions; loads
spin main ed7870 ed7878 # 3 instructions; loads
spin main ed7880 ed7884 # 2 instructions; loads
spin main ed78ac ed78b4 # 3 instructions; loads
spin main ed85a8 ed85bc # 6 instructions; loads
spin main ed9ff8 eda00c # 6 instructions; loads
spin main eda1bc eda1d0 # 6 instructions; loads
spin main f0dcc4 f0dcd8 # 6 instructions; loads
spin main f0e598 f0e5ac # 6 instructions; loads
spin main f11920 f11934 # 6 instructions; loads
spin main f11f7c f11f90 # 6 instructions; loads
spin main f11fa8 f11fbc # 6 instructions; loads
spin main f17f98 f17fac # 6 instructions; loads
spin main f1c328 f1c33c # 6 instructions; loads
spin main f2403c f24050 # 6 instructions; loads
spin main f36b5c f36b70 # 6 instructions; loads
spin main f36b84 f36b98 # 6 instructions; loads
spin main f36dd4 f36de8 # 6 instructions; loads
spin main f36e68 f36e7c # 6 instructions; loads
spin main f36e90 f36ea4 # 6 instructions; loads
spin main f36eb8 f36ecc # 6 instructions; loads
spin main f3b5dc f3b5f0 # 6 instructions; loads
spin main f3b7e8 f3b7fc # 6 instructions; loads
spin main f3c3b4 f3c3c8 # 6 instructions; loads
spin main f3dcc8 f3dcdc # 6 instructions; loads
spin main f4181c f41830 # 6 instructions; loads
spin main f41978 f4198c # 6 instructions; loads
spin main f41ad4 f41ae8 # 6 instructions; loads
spin main f41c30 f41c44 # 6 instructions; loads
spin main f46af0 f46b04 # 6 instructions; loads
spin main f487d8 f487ec # 6 instructions; loads
spin main f4f108 f4f11c # 6 instructions; loads
spin main f4f7f4 f4f808 # 6 instructions; loads
spin main f4f880 f4f894 # 6 instructions; loads
spin main f53f9c f53fb0 # 6 instructions; loads
spin main f5df2c f5df40 # 6 instructions; loads
spin main f5f458 f5f46c # 6 instructions; loads
spin main f6f51c f6f530 # 6 instructions; loads
spin main f6f840 f6f854 # 6 instructions; loads
spin main f70270 f70284 # 6 instructions; loads
spin main f70294 f702a8 # 6 instructions; loads
spin main f70828 f7083c # 6 instructions; loads
spin main f7947c f79490 # 6 instructions; loads
spin main f794a4 f794b8 # 6 instructions; loads
spin main f7e318 f7e32c # 6 instructions; loads
spin main f8db54 f8db68 # 6 instructions; loads
spin main f8f9f4 f8fa08 # 6 instructions; loads
spin main f90178 f9018c # 6 instructions; loads
spin main f96a00 f96a14 # 6 instructions; loads
spin main f96c40 f96c54 # 6 instructions; loads
spin main f96e64 f96e78 # 6 instructions; loads
spin main f96fdc f96ff0 # 6 instructions; loads
spin main f97158 f9716c # 6 instructions; loads
spin main fa26d4 fa26e8 # 6 instructions; loads
spin main fa5a18 fa5a2c # 6 instructions; loads
spin main faa880 faa894 # 6 instructions; loads
spin main faab1c faab30 # 6 instructions; loads
spin main fabc28 fabc3c # 6 instructions; loads
spin main fac5d0 fac5e4 # 6 instructions; loads
spin main faece4 faecf8 # 6 instructions; loads
spin main faf014 faf028 # 6 instructions; loads
spin main fb4494 fb44b0 # 8 instructions; loads
spin main fb68f0 fb6904 # 6 instructions; loads
spin main fb7130 fb7144 # 6 instructions; loads
spin main fb7590 fb75a4 # 6 instructions; loads
spin main fb75f8 fb760c # 6 instructions; loads
spin main fb8ea4 fb8f90 # 4 instructions; loads
spin main fb9598 fb9620 # 4 instructions; loads
spin main fbfb8c fbfba0 # 6 instructions; loads
spin main fcbea0 fcbeb4 # 6 instructions; loads
spin main fcc110 fcc124 # 6 instructions; loads
spin main fd281c fd2830 # 6 instructions; loads
spin main fda1c4 fda1d8 # 6 instructions; loads
spin main fe7c74 fe7c88 # 6 instructions; loads
spin main fe802c fe8040 # 6 instructions; loads
spin main fe837c fe8390 # 6 instructions; loads
spin main fe867c fe8690 # 6 instructions; loads
spin main fe8bd4 fe8be8 # 6 instructions; loads
spin main fe8f6c fe8f80 # 6 instructions; loads
spin main fe92ec fe9300 # 6 instructions; loads
spin main fe9360 fe9374 # 6 instructions; loads
spin main fea288 fea29c # 6 instructions; loads
spin main fea5d4 fea5e8 # 6 instructions; loads
spin main feaa58 feaa6c # 6 instructions; loads
spin main feaca4 feacb8 # 6 instructions; loads
spin main feba88 feba9c # 6 instructions; loads
spin main febb20 febb34 # 6 instructions; loads
spin main fecce4 feccf8 # 6 instructions; loads
spin main fed1f8 fed20c # 6 instructions; loads
spin main fed830 fed844 # 6 instructions; loads
spin main fed8ec fed900 # 6 instructions; loads
spin main fed9a8 fed9bc # 6 instructions; loads
spin main feda64 feda78 # 6 instructions; loads
spin main fee228 fee23c # 6 instructions; loads
spin main ff0314 ff0328 # 6 instructions; loads
spin main ff05c4 ff05d8 # 6 instructions; loads
spin main ff08b0 ff08c4 # 6 instructions; loads
spin main ff0b64 ff0b78 # 6 instructions; loads
spin main ff0e28 ff0e3c # 6 instructions; loads
spin main ff112c ff1140 # 6 instructions; loads
spin main ff118c ff11a0 # 6 instructions; loads
spin main ff26d0 ff26ec # 8 instructions; loads
spin main ff38e0 ff38f4 # 6 instructions; loads
spin main ff3920 ff3934 # 6 instructions; loads
spin main ff3960 ff3974 # 6 instructions; loads
spin main ff39a0 ff39b4 # 6 instructions; loads
spin main ff39e0 ff39f4 # 6 instructions; loads
spin main ff65b0 ff65c4 # 6 instructions; loads
spin main ff96ec ff9700 # 6 instructions; loads
spin main 1017c00 1017c14 # 6 instructions; loads
spin main 101a9e4 101a9f8 # 6 instructions; loads
spin main 101c0b8 101c0cc # 6 instructions; loads
spin main 10242b0 10242c4 # 6 instructions; loads
spin main 102bc78 102bcc0 # 3 instructions; loads
spin main 1036db4 1036dc8 # 6 instructions; loads
spin main 1042cf0 1042cf8 # 3 instructions; loads
spin main 1042d00 1042d04 # 2 instructions; loads
spin main 1042d6c 1042d74 # 3 instructions; loads
spin main 10587c4 10587d8 # 6 instructions; loads
spin main 1059808 105981c # 6 instructions; loads
spin main 1059d2c 1059d40 # 6 instructions; loads
spin main 105beb0 105bec4 # 6 instructions; loads
spin main 105e700 105e714 # 6 instructions; loads
spin main 1066350 1066364 # 6 instructions; loads
spin main 1075340 1075354 # 6 instructions; loads
spin main 1086b00 1086b14 # 6 instructions; loads
spin main 1086b48 1086b5c # 6 instructions; loads
spin main 10a671c 10a6730 # 6 instructions; loads
spin main 10a9640 10a9654 # 6 instructions; loads
spin main 10ab2e8 10ab2fc # 6 instructions; loads
spin main 10ab310 10ab324 # 6 instructions; loads
spin main 10af3b8 10af3cc # 6 instructions; loads
spin main 10af9a8 10af9bc # 6 instructions; loads
spin main 10b6d0c 10b6d20 # 6 instructions; loads
spin main 10c765c 10c7670 # 6 instructions; loads
spin main 10d588c 10d58a0 # 6 instructions; loads
spin main 10dabd4 10dabe8 # 6 instructions; loads
spin main 10dafa8 10dafbc # 6 instructions; loads
spin main 10db6e0 10db6f4 # 6 instructions; loads
spin main 10dbc78 10dbc8c # 6 instructions; loads
spin main 10de660 10de674 # 6 instructions; loads
spin main 10ebcac 10ebcc0 # 6 instructions; loads
spin main 10ebd28 10ebd3c # 6 instructions; loads
spin main 10f3274 10f3288 # 6 instructions; loads
spin main 10f329c 10f32b0 # 6 instructions; loads
spin main 10f9384 10f94b8 # 4 instructions; loads
spin main 10f9408 10f949c # 4 instructions; loads
spin main 1106318 110632c # 6 instructions; loads
spin main 1106860 1106874 # 6 instructions; loads
spin main 1111040 1111054 # 6 instructions; loads
spin main 1111b8c 1111ba0 # 6 instructions; loads
spin main 1111dec 1111e00 # 6 instructions; loads
spin main 111256c 1112580 # 6 instructions; loads
spin main 1115ca4 1115cb8 # 6 instructions; loads
spin main 1117c88 1117c9c # 6 instructions; loads
spin main 111b654 111b668 # 6 instructions; loads
spin main 113bf9c 113bfb0 # 6 instructions; loads
spin main 113bfc4 113bfd8 # 6 instructions; loads
spin main 11404a0 11404b4 # 6 instructions; loads
spin main 114f7e8 114f7fc # 6 instructions; loads
spin main 115891c 1158930 # 6 instructions; loads
spin main 1159860 1159874 # 6 instructions; loads
spin main 116b594 116b5a8 # 6 instructions; loads
spin main 116b9ec 116ba00 # 6 instructions; loads
spin main 116ba14 116ba28 # 6 instructions; loads
spin main 1173168 117317c # 6 instructions; loads
spin main 1178e1c 1178e30 # 6 instructions; loads
spin main 117af24 117af38 # 6 instructions; loads
spin main 118444c 1184460 # 6 instructions; loads
spin main 1184828 118483c # 6 instructions; loads
spin main 1185b8c 1185ba0 # 6 instructions; loads
spin main 1186c48 1186c5c # 6 instructions; loads
spin main 118ba50 118ba64 # 6 instructions; loads
spin main 118ca3c 118ca50 # 6 instructions; loads
spin main 1191f94 1191fa8 # 6 instructions; loads
spin main 1191fbc 1191fd0 # 6 instructions; loads
spin main 1192b18 1192b2c # 6 instructions; loads
spin main 119b934 119b948 # 6 instructions; loads
spin main 119d40c 119d420 # 6 instructions; loads
spin main 11b1d80 11b1d94 # 6 instructions; loads
spin main 11b4ca0 11b4cb4 # 6 instructions; loads
spin main 11b6300 11b6314 # 6 instructions; loads
spin main 11b8e58 11b8e6c # 6 instructions; loads
spin main 11bea60 11bea74 # 6 instructions; loads
spin main 11d8218 11d822c # 6 instructions; loads
spin main 11db090 11db0a4 # 6 instructions; loads
spin main 11db0b8 11db0cc # 6 instructions; loads
spin main 1201688 120169c # 6 instructions; loads
spin main 12048a4 12048b8 # 6 instructions; loads
spin main 12048cc 12048e0 # 6 instructions; loads
spin main 1205868 120587c # 6 instructions; loads
spin main 1206350 1206364 # 6 instructions; loads
spin main 1226308 122631c # 6 instructions; loads
spin main 1226898 12268ac # 6 instructions; loads
spin main 12374a8 12374bc # 6 instructions; loads
spin main 1252260 1252274 # 6 instructions; loads
spin main 1252688 125269c # 6 instructions; loads
spin main 1252968 125297c # 6 instructions; loads
spin main 1271260 1271274 # 6 instructions; loads
spin main 127b710 127b724 # 6 instructions; loads
spin main 127b778 127b78c # 6 instructions; loads
spin main 127b928 127b93c # 6 instructions; loads
spin main 127b954 127b968 # 6 instructions; loads
spin main 127b980 127b994 # 6 instructions; loads
spin main 127b9ac 127b9c0 # 6 instructions; loads
spin main 127c150 127c164 # 6 instructions; loads
spin main 127c178 127c18c # 6 instructions; loads
spin main 12816c8 12816dc # 6 instructions; loads
spin main 1282010 1282024 # 6 instructions; loads
spin main 1282078 128208c # 6 instructions; loads
spin main 1285674 1285688 # 6 instructions; loads
spin main 12877c8 12877dc # 6 instructions; loads
spin main 128dd24 128dd38 # 6 instructions; loads
spin main 128f04c 128f060 # 6 instructions; loads
spin main 12af6ac 12af6c0 # 6 instructions; loads
spin main 12af6d4 12af6e8 # 6 instructions; loads
spin main 12ba674 12ba688 # 6 instructions; loads
spin main 12cc354 12cc368 # 6 instructions; loads
spin main 12fc134 12fc148 # 6 instructions; loads
spin main 12fc798 12fc7ac # 6 instructions; loads
spin main 13098cc 13098e0 # 6 instructions; loads
spin main 130ce14 130cef4 # 11 instructions; loads
spin main 1312798 13127ac # 6 instructions; loads
spin main 131363c 1313650 # 6 instructions; loads
spin main 1313900 1313914 # 6 instructions; loads
spin main 131b4c8 131b4dc # 6 instructions; loads
spin main 134c220 134c234 # 6 instructions; loads
spin main 13e7d68 13e7d7c # 6 instructions; loads
spin main 13e7f00 13e7f14 # 6 instructions; loads
spin main 1571e58 1571e6c # 6 instructions; loads
spin main 1578834 1578848 # 6 instructions; loads
spin main 1585d04 1585d18 # 6 instructions; loads
spin main 1587128 158713c # 6 instructions; loads
spin main 1587150 1587164 # 6 instructions; loads
spin main 158ec94 158eca8 # 6 instructions; loads
spin main 158f7d4 158f7e8 # 6 instructions; loads
spin main 158fab0 158fac4 # 6 instructions; loads
spin main 158fad8 158faec # 6 instructions; loads
spin main 1590c38 1590c4c # 6 instructions; loads
spin main 15a8180 15a8194 # 6 instructions; loads
spin main 15a8618 15a862c # 6 instructions; loads
spin main 15a8720 15a8734 # 6 instructions; loads
spin main 15a8a38 15a8a4c # 6 instructions; loads
spin main 15c4eb8 15c4ecc # 6 instructions; loads
spin main 15d8974 15d8988 # 6 instructions; loads
spin main 15d9f60 15d9f74 # 6 instructions; loads
spin main 15da008 15da01c # 6 instructions; loads
spin main 15df528 15df53c # 6 instructions; loads
spin main 15df668 15df67c # 6 instructions; loads
spin main 15df690 15df6a4 # 6 instructions; loads
spin main 15f7dfc 15f7e10 # 6 instructions; loads
spin main 15f8360 15f8374 # 6 instructions; loads
spin main 15f98a0 15f98b4 # 6 instructions; loads
spin main 1608f04 1608f18 # 6 instructions; loads
spin main 161523c 1615250 # 6 instructions; loads
spin main 161966c 1619680 # 6 instructions; loads
spin main 16196bc 16196d0 # 6 instructions; loads
spin main 161a810 161a824 # 6 instructions; loads
spin main 1625758 162576c # 6 instructions; loads
spin main 1627da8 1627dbc # 6 instructions; loads
spin main 1628534 1628548 # 6 instructions; loads
spin main 162ce60 162ce74 # 6 instructions; loads
spin main 1639828 163983c # 6 instructions; loads
spin main 1641574 1641588 # 6 instructions; loads
spin main 1643838 164384c # 6 instructions; loads
spin main 16496b4 16496bc # 3 instructions; loads
spin main 16496c4 16496c8 # 2 instructions; loads
spin main 16496fc 1649704 # 3 instructions; loads
spin main 1691fa4 1691fb8 # 6 instructions; loads
spin main 16cc754 16cc768 # 6 instructions; loads
spin main 172da0c 172da20 # 6 instructions; loads
spin main 1737834 1737848 # 6 instructions; loads
spin main 1737df8 1737e0c # 6 instructions; loads
spin main 1790da0 1790db4 # 6 instructions; loads
spin main 1922fec 1923000 # 6 instructions; loads
spin main 1924710 1924724 # 6 instructions; loads
spin main 1953798 19537a0 # 3 instructions; loads
spin main 19537a8 19537ac # 2 instructions; loads
spin main 1953830 1953838 # 3 instructions; loads
spin main 195391c 1953924 # 3 instructions; loads
spin main 195392c 1953930 # 2 instructions; loads
spin main 19539d8 19539e0 # 3 instructions; loads
spin main 1966130 1966138 # 3 instructions; loads
spin main 1966140 1966144 # 2 instructions; loads
spin main 1966168 1966170 # 3 instructions; loads
spin main 19661a0 19661a8 # 3 instructions; loads
spin main 19661b0 19661b4 # 2 instructions; loads
spin main 19661dc 19661e4 # 3 instructions; loads
spin main 19d6938 19d694c # 6 instructions; loads
spin main 1a7ce6c 1a7ce7c # 5 instructions; loads
spin main 1b5662c 1b56640 # 6 instructions; loads
spin main 1b566e8 1b566fc # 6 instructions; loads
spin main 1b567a4 1b567b8 # 6 instructions; loads
spin main 1b56da4 1b56db8 # 6 instructions; loads
spin main 1b56e60 1b56e74 # 6 instructions; loads
spin main 1b56f1c 1b56f30 # 6 instructions; loads
spin main 1d34e90 1d34ea4 # 6 instructions; loads
spin main 1df2cac 1df2cb8 # 4 instructions; loads
spin main 21dc108 21dc130 # 4 instructions; loads
spin main 221fe50 221fe6c # 8 instructions; loads
spin main 2227d40 2227d48 # 3 instructions; loads
spin main 2227dc8 2227dd0 # 3 instructions; loads
spin main 2227e58 2227e80 # 3 instructions; loads
spin main 222ed8c 222ed9c # 5 instructions; loads
spin main 2255970 2255978 # 3 instructions; loads
spin main 2255980 2255984 # 2 instructions; loads
spin main 2255a0c 2255a14 # 3 instructions; loads
spin main 2255a98 2255aa0 # 3 instructions; loads
spin main 2255aa8 2255aac # 2 instructions; loads
spin main 2255ac4 2255acc # 3 instructions; loads
spin main 22aeafc 22aeb10 # 6 instructions; loads
spin main 22aec60 22aec74 # 6 instructions; loads
spin main 22bd7bc 22bd7e0 # 4 instructions; loads
spin main 22bd8ac 22bd8b8 # 4 instructions; loads
spin main 23352a4 23352b8 # 6 instructions; loads
spin main 2406890 2406898 # 3 instructions; loads
spin main 24068a0 24068a4 # 2 instructions; loads
spin main 2406920 2406928 # 3 instructions; loads
spin main 240715c 2407164 # 3 instructions; loads
spin main 240716c 2407170 # 2 instructions; loads
spin main 24071dc 24071e4 # 3 instructions; loads
spin main 240767c 2407684 # 3 instructions; loads
spin main 240768c 2407690 # 2 instructions; loads
spin main 240771c 2407724 # 3 instructions; loads
spin main 2407860 2407868 # 3 instructions; loads
spin main 2407870 2407874 # 2 instructions; loads
spin main 24078c8 24078d0 # 3 instructions; loads
spin main 2407914 240791c # 3 instructions; loads
spin main 2407924 2407928 # 2 instructions; loads
spin main 24079dc 24079e4 # 3 instructions; loads
spin main 24079ec 24079f0 # 2 instructions; loads
spin main 2407a30 2407a38 # 3 instructions; loads
spin main 2407a60 2407a68 # 3 instructions; loads
spin main 2407b54 2407b5c # 3 instructions; loads
spin main 2407b64 2407b68 # 2 instructions; loads
spin main 2407c48 2407c50 # 3 instructions; loads
spin main 2407cdc 2407ce4 # 3 instructions; loads
spin main 2407cec 2407cf0 # 2 instructions; loads
spin main 2407da4 2407dac # 3 instructions; loads
spin main 2407dc4 2407dc8 # 2 instructions; loads
spin main 2407e68 2407e70 # 3 instructions; loads
spin main 2407e98 2407ea0 # 3 instructions; loads
spin main 2407ee0 2407ee8 # 3 instructions; loads
spin main 2407ef0 2407ef4 # 2 instructions; loads
spin main 2407f18 2407f20 # 3 instructions; loads
spin main 2407f64 2407f6c # 3 instructions; loads
spin main 2407f74 2407f78 # 2 instructions; loads
spin main 2407fa0 2407fa8 # 3 instructions; loads
spin main 24084fc 2408504 # 3 instructions; loads
spin main 240850c 2408510 # 2 instructions; loads
spin main 2408534 240853c # 3 instructions; loads
spin main 2408c68 2408c70 # 3 instructions; loads
spin main 2408c78 2408c7c # 2 instructions; loads
spin main 2408ca0 2408ca8 # 3 instructions; loads
spin main 240a564 240a56c # 3 instructions; loads
spin main 240a574 240a578 # 2 instructions; loads
spin main 240a5f8 240a600 # 3 instructions; loads
spin main 240a620 240a628 # 3 instructions; loads
spin main 240a630 240a634 # 2 instructions; loads
spin main 240a6b4 240a6bc # 3 instructions; loads
spin main 240aa50 240aa58 # 3 instructions; loads
spin main 240aa60 240aa64 # 2 instructions; loads
spin main 240aab4 240aabc # 3 instructions; loads
spin main 240aafc 240ab04 # 3 instructions; loads
spin main 240ab0c 240ab10 # 2 instructions; loads
spin main 240abac 240abb4 # 3 instructions; loads
spin main 240ac0c 240ac14 # 3 instructions; loads
spin main 240ac1c 240ac20 # 2 instructions; loads
spin main 240aca4 240acac # 3 instructions; loads
spin main 240d908 240d910 # 3 instructions; loads
spin main 240d918 240d91c # 2 instructions; loads
spin main 240d9a8 240d9b0 # 3 instructions; loads
spin main 240d9e4 240d9ec # 3 instructions; loads
spin main 240d9f4 240d9f8 # 2 instructions; loads
spin main 240da64 240da6c # 3 instructions; loads
spin main 240ff38 240ff40 # 3 instructions; loads
spin main 240ff48 240ff4c # 2 instructions; loads
spin main 240ff68 240ff70 # 3 instructions; loads
spin main 245c2ec 245c300 # 6 instructions; loads
spin main 245c314 245c328 # 6 instructions; loads
spin main 245f0dc 245f0f0 # 6 instructions; loads
spin main 245f570 245f584 # 6 instructions; loads
spin main 246ea9c 246eab0 # 6 instructions; loads
spin main 246eee8 246eefc # 6 instructions; loads
spin main 2472f60 2472f74 # 6 instructions; loads
spin main 24739ac 24739c0 # 6 instructions; loads
spin main 24741a8 24741bc # 6 instructions; loads
spin main 248f710 248f724 # 6 instructions; loads
spin main 287ff50 287ff64 # 6 instructions; loads
spin main 288000c 2880020 # 6 instructions; loads
spin main 28800c8 28800dc # 6 instructions; loads
spin main 2880ed4 2880ee8 # 6 instructions; loads
spin main 2880f90 2880fa4 # 6 instructions; loads
spin main 288104c 2881060 # 6 instructions; loads
spin main 2881108 288111c # 6 instructions; loads
spin main 28811c4 28811d8 # 6 instructions; loads
spin main 2881280 2881294 # 6 instructions; loads
spin main 288133c 2881350 # 6 instructions; loads
spin main 28813f8 288140c # 6 instructions; loads
spin main 28818c0 28818d4 # 6 instructions; loads
spin main 288197c 2881990 # 6 instructions; loads
spin main 2a38860 2a38868 # 3 instructions; loads
spin main 2a38870 2a38874 # 2 instructions; loads
spin main 2a388ac 2a388b4 # 3 instructions; loads
spin subsdk0 2090 20a4 # 6 instructions; loads
spin subsdk0 278b4 278c8 # 6 instructions; loads
spin subsdk0 bcf28 bcfd0 bcfd8 # 14 instructions; loads
spin subsdk0 bd0d0 bd178 bd180 # 14 instructions; loads
spin subsdk0 c03a0 c03b4 # 6 instructions; loads
spin subsdk0 1bbefc 1bbf08 # 4 instructions; loads
spin subsdk0 1bd838 1bd84c # 6 instructions; loads
spin subsdk0 1c0c68 1c0c74 # 4 instructions; loads
spin sdk f5218 f5350 # 14 instructions; loads
spin sdk 23a590 23a5d8 # 19 instructions; loads
spin sdk 23a658 23a6a0 # 19 instructions; loads
spin sdk 23a7fc 23a918 # 19 instructions; loads
spin sdk 3d3250 3d3270 # 9 instructions; loads
+860
View File
@@ -60,3 +60,863 @@ site scene main 585e48 1e220160 @page:x3 # scvtf s0, w11 -> adrp x3, page
site scene main 585e50 bd0cc660 2d420460 # str s0, [x19, #0xcc4] -> ldp s0, s1, [x3, #16]
site scene main 585e54 1e220140 bd0cc660 # scvtf s0, w10 -> str s0, [x19, #0xcc4]
site scene main 585e60 bd0cca60 bd0cca61 # str s0, [x19, #0xcc8] -> str s1, [x19, #0xcc8]
# Spin waits, from tools/spin_waits.py --exefs build/extracted/v143/exefs --patches recomp/patches-v143.txt: loops that only
# another thread can end; their back-edges pass rt_spin_gate (runtime/kernel.c), TOTK_SPIN=0 keeps the core.
spin main 231dc 231ec # 5 instructions; loads
spin main 24780 24790 # 5 instructions; loads
spin main 5748c 574a0 # 6 instructions; loads
spin main 574b8 574cc # 6 instructions; loads
spin main 5775c 57770 # 6 instructions; loads
spin main 577c8 577dc # 6 instructions; loads
spin main 59ac0 59ad4 # 6 instructions; loads
spin main 95298 952b0 # 7 instructions; loads
spin main 952c4 952dc # 7 instructions; loads
spin main 952ec 95304 # 7 instructions; loads
spin main aeeb0 aefa8 # 8 instructions; stc
spin main ee90c ee93c # 13 instructions; loads
spin main ee950 ee96c # 8 instructions; loads
spin main 11982c 11985c # 13 instructions; loads
spin main 11986c 119888 # 8 instructions; loads
spin main 1391f8 139208 # 5 instructions; loads
spin main 13abc8 13abfc # 14 instructions; loads
spin main 13ac0c 13ac28 # 8 instructions; loads
spin main 15c004 15c018 # 6 instructions; loads
spin main 15cb4c 15cb60 # 6 instructions; loads
spin main 15cc80 15cc94 # 6 instructions; loads
spin main 15d0c0 15d0d4 # 6 instructions; loads
spin main 176ec8 176edc # 6 instructions; loads
spin main 191be4 191bf8 # 6 instructions; loads
spin main 1946a4 1946b8 # 6 instructions; loads
spin main 1ac9b0 1ac9b8 # 3 instructions; loads
spin main 1f9720 1f9734 # 6 instructions; loads
spin main 212a28 212a3c # 6 instructions; loads
spin main 212afc 212b10 # 6 instructions; loads
spin main 213944 213958 # 6 instructions; loads
spin main 216378 21638c # 6 instructions; loads
spin main 2163d4 2163e8 # 6 instructions; loads
spin main 21bb64 21bb78 # 6 instructions; loads
spin main 21c0a0 21c0b4 # 6 instructions; loads
spin main 2368a8 2368bc # 6 instructions; loads
spin main 236a5c 236a70 # 6 instructions; loads
spin main 236c08 236c1c # 6 instructions; loads
spin main 236ebc 236ed0 # 6 instructions; loads
spin main 236fc4 236fd8 # 6 instructions; loads
spin main 23822c 238240 # 6 instructions; loads
spin main 239f08 239f1c # 6 instructions; loads
spin main 24f3ec 24f400 # 6 instructions; loads
spin main 24f500 24f514 # 6 instructions; loads
spin main 24f52c 24f540 # 6 instructions; loads
spin main 24f590 24f5a4 # 6 instructions; loads
spin main 24fa54 24fa68 # 6 instructions; loads
spin main 24fe38 24fe4c # 6 instructions; loads
spin main 25b364 25b378 # 6 instructions; loads
spin main 25b614 25b628 # 6 instructions; loads
spin main 25c1c8 25c1dc # 6 instructions; loads
spin main 270cd0 270ce4 # 6 instructions; loads
spin main 2836ac 2836c0 # 6 instructions; loads
spin main 28ae98 28aeac # 6 instructions; loads
spin main 29f890 29f8a4 # 6 instructions; loads
spin main 29f968 29f97c # 6 instructions; loads
spin main 2a8e74 2a8e88 # 6 instructions; loads
spin main 2dd3e8 2dd3fc # 6 instructions; loads
spin main 2e03c4 2e03d8 # 6 instructions; loads
spin main 2f9758 2f976c # 6 instructions; loads
spin main 2fddb8 2fddcc # 6 instructions; loads
spin main 2ffb20 2ffb34 # 6 instructions; loads
spin main 30e230 30e244 # 6 instructions; loads
spin main 3100e8 3100fc # 6 instructions; loads
spin main 317abc 317ad0 # 6 instructions; loads
spin main 319664 319678 # 6 instructions; loads
spin main 319f24 319f38 # 6 instructions; loads
spin main 31aeac 31aec0 # 6 instructions; loads
spin main 31b558 31b56c # 6 instructions; loads
spin main 33538c 3353a0 # 6 instructions; loads
spin main 33e898 33e8ac # 6 instructions; loads
spin main 34e07c 34e090 # 6 instructions; loads
spin main 350e7c 350e90 # 6 instructions; loads
spin main 350f28 350f3c # 6 instructions; loads
spin main 3510fc 351110 # 6 instructions; loads
spin main 3511b8 3511cc # 6 instructions; loads
spin main 352840 352854 # 6 instructions; loads
spin main 3528b0 3528c4 # 6 instructions; loads
spin main 36cec4 36ced8 # 6 instructions; loads
spin main 3a341c 3a3430 # 6 instructions; loads
spin main 3a3444 3a3458 # 6 instructions; loads
spin main 3de1cc 3de1e8 # 8 instructions; loads
spin main 3de2a4 3de2f0 # 7 instructions; loads
spin main 3de2fc 3de348 # 7 instructions; loads
spin main 3e8418 3e8428 # 5 instructions; loads
spin main 3e855c 3e856c # 5 instructions; loads
spin main 4096c4 4096d8 # 6 instructions; loads
spin main 409748 40975c # 6 instructions; loads
spin main 41e068 41e070 # 3 instructions; loads
spin main 42d138 42d14c # 6 instructions; loads
spin main 43b260 43b274 # 6 instructions; loads
spin main 43e01c 43e030 # 6 instructions; loads
spin main 446bac 446bc0 # 6 instructions; loads
spin main 4503f0 450404 # 6 instructions; loads
spin main 457274 457288 # 6 instructions; loads
spin main 4609dc 4609f0 # 6 instructions; loads
spin main 46313c 463150 # 6 instructions; loads
spin main 467844 467858 # 6 instructions; loads
spin main 467f68 467f7c # 6 instructions; loads
spin main 46ca90 46caa4 # 6 instructions; loads
spin main 46ef8c 46efa0 # 6 instructions; loads
spin main 472154 472168 # 6 instructions; loads
spin main 473b88 473b9c # 6 instructions; loads
spin main 47c85c 47c870 # 6 instructions; loads
spin main 47cb00 47cb14 # 6 instructions; loads
spin main 47da50 47da64 # 6 instructions; loads
spin main 47fcb4 47fcc8 # 6 instructions; loads
spin main 480b44 480b58 # 6 instructions; loads
spin main 480c18 480c2c # 6 instructions; loads
spin main 482c3c 482c50 # 6 instructions; loads
spin main 482d18 482d2c # 6 instructions; loads
spin main 482e78 482e8c # 6 instructions; loads
spin main 4902bc 4902d0 # 6 instructions; loads
spin main 490394 4903a8 # 6 instructions; loads
spin main 4904cc 4904e0 # 6 instructions; loads
spin main 49061c 490630 # 6 instructions; loads
spin main 49114c 491160 # 6 instructions; loads
spin main 491418 49142c # 6 instructions; loads
spin main 492234 492248 # 6 instructions; loads
spin main 4991bc 4991d0 # 6 instructions; loads
spin main 49de50 49de64 # 6 instructions; loads
spin main 49def8 49df0c # 6 instructions; loads
spin main 49f714 49f728 # 6 instructions; loads
spin main 4a0bf4 4a0c08 # 6 instructions; loads
spin main 4a2834 4a2848 # 6 instructions; loads
spin main 4a36a4 4a36b8 # 6 instructions; loads
spin main 4b99b8 4b99cc # 6 instructions; loads
spin main 4c05e8 4c05fc # 6 instructions; loads
spin main 4c0950 4c0964 # 6 instructions; loads
spin main 4c0bf4 4c0c08 # 6 instructions; loads
spin main 4d3088 4d309c # 6 instructions; loads
spin main 4d4bf4 4d4c08 # 6 instructions; loads
spin main 4e70dc 4e70f0 # 6 instructions; loads
spin main 4ec724 4ec738 # 6 instructions; loads
spin main 4f6068 4f607c # 6 instructions; loads
spin main 4f6264 4f6278 # 6 instructions; loads
spin main 4f94fc 4f9510 # 6 instructions; loads
spin main 4fcacc 4fcae0 # 6 instructions; loads
spin main 4fd858 4fd86c # 6 instructions; loads
spin main 4fedc0 4fedd4 # 6 instructions; loads
spin main 4feed4 4feee8 # 6 instructions; loads
spin main 4ff408 4ff41c # 6 instructions; loads
spin main 500960 500974 # 6 instructions; loads
spin main 50437c 504390 # 6 instructions; loads
spin main 504608 50461c # 6 instructions; loads
spin main 511b60 511b74 # 6 instructions; loads
spin main 587f98 587fac # 6 instructions; loads
spin main 5a9c04 5a9c18 # 6 instructions; loads
spin main 5b15a8 5b15bc # 6 instructions; loads
spin main 5b1600 5b1614 # 6 instructions; loads
spin main 5b1690 5b16a4 # 6 instructions; loads
spin main 5b16f0 5b1704 # 6 instructions; loads
spin main 5b7080 5b7094 # 6 instructions; loads
spin main 5bfc2c 5bfc40 # 6 instructions; loads
spin main 5bfd00 5bfd14 # 6 instructions; loads
spin main 5fe024 5fe038 # 6 instructions; loads
spin main 601814 601828 # 6 instructions; loads
spin main 602398 6023ac # 6 instructions; loads
spin main 602448 60245c # 6 instructions; loads
spin main 602914 602928 # 6 instructions; loads
spin main 602d8c 602da0 # 6 instructions; loads
spin main 6034ac 6034c0 # 6 instructions; loads
spin main 603560 603574 # 6 instructions; loads
spin main 603a44 603a58 # 6 instructions; loads
spin main 61ac14 61ac28 # 6 instructions; loads
spin main 628694 6286a8 # 6 instructions; loads
spin main 6289f8 628a0c # 6 instructions; loads
spin main 6294b4 6294c8 # 6 instructions; loads
spin main 62abc4 62abd8 # 6 instructions; loads
spin main 62d6a0 62d6b4 # 6 instructions; loads
spin main 62d9d8 62d9ec # 6 instructions; loads
spin main 631bdc 631bf0 # 6 instructions; loads
spin main 6575a4 6575b8 # 6 instructions; loads
spin main 65b450 65b464 # 6 instructions; loads
spin main 65bb7c 65bb90 # 6 instructions; loads
spin main 662d34 662d48 # 6 instructions; loads
spin main 662e38 662e4c # 6 instructions; loads
spin main 675a30 675a44 # 6 instructions; loads
spin main 68bb10 68bb24 # 6 instructions; loads
spin main 68bb60 68bb74 # 6 instructions; loads
spin main 68bd04 68bd18 # 6 instructions; loads
spin main 6b5038 6b504c # 6 instructions; loads
spin main 6b51c4 6b51d8 # 6 instructions; loads
spin main 6cf050 6cf064 # 6 instructions; loads
spin main 6cf0c8 6cf0dc # 6 instructions; loads
spin main 6cf160 6cf174 # 6 instructions; loads
spin main 6cf1b4 6cf1c8 # 6 instructions; loads
spin main 6cfc34 6cfc48 # 6 instructions; loads
spin main 6cfc5c 6cfc70 # 6 instructions; loads
spin main 6e41e4 6e41f8 # 6 instructions; loads
spin main 712ab8 712acc # 6 instructions; loads
spin main 715894 7158a8 # 6 instructions; loads
spin main 715aac 715ac0 # 6 instructions; loads
spin main 715e84 715e98 # 6 instructions; loads
spin main 715f30 715f44 # 6 instructions; loads
spin main 718a40 718a54 # 6 instructions; loads
spin main 718ae4 718af8 # 6 instructions; loads
spin main 718bd8 718bec # 6 instructions; loads
spin main 718c64 718c78 # 6 instructions; loads
spin main 72caa0 72cab4 # 6 instructions; loads
spin main 72e5c8 72e5dc # 6 instructions; loads
spin main 72ebfc 72ec10 # 6 instructions; loads
spin main 747f84 747f98 # 6 instructions; loads
spin main 748270 748284 # 6 instructions; loads
spin main 7487b4 7487c8 # 6 instructions; loads
spin main 748b10 748b24 # 6 instructions; loads
spin main 7522ac 7522c0 # 6 instructions; loads
spin main 75259c 7525b0 # 6 instructions; loads
spin main 7b5118 7b512c # 6 instructions; loads
spin main 7bb674 7bb688 # 6 instructions; loads
spin main 7bb724 7bb738 # 6 instructions; loads
spin main 7bb7d0 7bb7e4 # 6 instructions; loads
spin main 7bb87c 7bb890 # 6 instructions; loads
spin main 7cd938 7cd94c # 6 instructions; loads
spin main 7ce440 7ce454 # 6 instructions; loads
spin main 7ce7c0 7ce7d4 # 6 instructions; loads
spin main 7cea30 7cea44 # 6 instructions; loads
spin main 7ced60 7ced74 # 6 instructions; loads
spin main 7cf108 7cf11c # 6 instructions; loads
spin main 7cf374 7cf388 # 6 instructions; loads
spin main 7cf3ec 7cf400 # 6 instructions; loads
spin main 7cf8a8 7cf8bc # 6 instructions; loads
spin main 7cfbd0 7cfbe4 # 6 instructions; loads
spin main 7d2a34 7d2a48 # 6 instructions; loads
spin main 7d2c54 7d2c68 # 6 instructions; loads
spin main 7d4100 7d411c # 8 instructions; loads
spin main 7d41b0 7d41cc # 8 instructions; loads
spin main 7d4260 7d427c # 8 instructions; loads
spin main 7d46d4 7d46e8 # 6 instructions; loads
spin main 7d5128 7d513c # 6 instructions; loads
spin main 7d5760 7d5774 # 6 instructions; loads
spin main 7d57a8 7d57bc # 6 instructions; loads
spin main 7d664c 7d6660 # 6 instructions; loads
spin main 7d6748 7d675c # 6 instructions; loads
spin main 7d67f4 7d6808 # 6 instructions; loads
spin main 7d6b48 7d6b5c # 6 instructions; loads
spin main 7d6f18 7d6f2c # 6 instructions; loads
spin main 7d7168 7d717c # 6 instructions; loads
spin main 7d752c 7d7540 # 6 instructions; loads
spin main 7d79b8 7d79cc # 6 instructions; loads
spin main 7d7bf4 7d7c08 # 6 instructions; loads
spin main 7d8794 7d87a8 # 6 instructions; loads
spin main 7d8918 7d892c # 6 instructions; loads
spin main 7d8ab0 7d8ac4 # 6 instructions; loads
spin main 7d94e4 7d94f8 # 6 instructions; loads
spin main 7dd1cc 7dd1e0 # 6 instructions; loads
spin main 7ddd3c 7ddd50 # 6 instructions; loads
spin main 7de684 7de698 # 6 instructions; loads
spin main 7dead4 7deae8 # 6 instructions; loads
spin main 7deb48 7deb5c # 6 instructions; loads
spin main 7ded58 7ded6c # 6 instructions; loads
spin main 7e049c 7e04b0 # 6 instructions; loads
spin main 7e4570 7e4584 # 6 instructions; loads
spin main 7e462c 7e4640 # 6 instructions; loads
spin main 7e46dc 7e46f0 # 6 instructions; loads
spin main 7e478c 7e47a0 # 6 instructions; loads
spin main 7e4868 7e487c # 6 instructions; loads
spin main 7e4930 7e4944 # 6 instructions; loads
spin main 7e4a00 7e4a14 # 6 instructions; loads
spin main 7e4ac4 7e4ad8 # 6 instructions; loads
spin main 7e4b84 7e4b98 # 6 instructions; loads
spin main 7e4c44 7e4c58 # 6 instructions; loads
spin main 7e4d04 7e4d18 # 6 instructions; loads
spin main 7e4dd0 7e4de4 # 6 instructions; loads
spin main 7e4e94 7e4ea8 # 6 instructions; loads
spin main 7e528c 7e52a0 # 6 instructions; loads
spin main 7e53cc 7e53e0 # 6 instructions; loads
spin main 7e53f4 7e5408 # 6 instructions; loads
spin main 7e54a4 7e54b8 # 6 instructions; loads
spin main 7e5564 7e5578 # 6 instructions; loads
spin main 7e5664 7e5678 # 6 instructions; loads
spin main 7e572c 7e5740 # 6 instructions; loads
spin main 7e5e90 7e5ea4 # 6 instructions; loads
spin main 7e5f8c 7e5fa0 # 6 instructions; loads
spin main 7e64fc 7e6510 # 6 instructions; loads
spin main 7e65b8 7e65cc # 6 instructions; loads
spin main 7ead90 7eada4 # 6 instructions; loads
spin main 7eae34 7eae48 # 6 instructions; loads
spin main 7ed8ac 7ed8c0 # 6 instructions; loads
spin main 7ee8a8 7ee8bc # 6 instructions; loads
spin main 7eea7c 7eea90 # 6 instructions; loads
spin main 7eef80 7eef94 # 6 instructions; loads
spin main 7ef3a8 7ef3bc # 6 instructions; loads
spin main 7ef494 7ef4a8 # 6 instructions; loads
spin main 7ef584 7ef598 # 6 instructions; loads
spin main 7f00ac 7f00c0 # 6 instructions; loads
spin main 7f0470 7f0484 # 6 instructions; loads
spin main 7f0520 7f0534 # 6 instructions; loads
spin main 7f7be4 7f7bf8 # 6 instructions; loads
spin main 7f8df0 7f8e04 # 6 instructions; loads
spin main 7fcd74 7fcd88 # 6 instructions; loads
spin main 7fd738 7fd74c # 6 instructions; loads
spin main 7fd9d8 7fd9ec # 6 instructions; loads
spin main 7fda18 7fda2c # 6 instructions; loads
spin main 7ff020 7ff034 # 6 instructions; loads
spin main 7ff064 7ff078 # 6 instructions; loads
spin main 7ff624 7ff638 # 6 instructions; loads
spin main 7ff678 7ff68c # 6 instructions; loads
spin main 7ff6c8 7ff6dc # 6 instructions; loads
spin main 7ffff4 800010 # 8 instructions; loads
spin main 800504 800520 # 8 instructions; loads
spin main 800a3c 800a50 # 6 instructions; loads
spin main 807424 807438 # 6 instructions; loads
spin main 808910 808924 # 6 instructions; loads
spin main 8209cc 8209e0 # 6 instructions; loads
spin main 822a60 822a74 # 6 instructions; loads
spin main 83bf5c 83bf70 # 6 instructions; loads
spin main 83d5f0 83d604 # 6 instructions; loads
spin main 84643c 846450 # 6 instructions; loads
spin main 847d80 847d94 # 6 instructions; loads
spin main 849410 849424 # 6 instructions; loads
spin main 849b14 849b28 # 6 instructions; loads
spin main 8534dc 8534f0 # 6 instructions; loads
spin main 853d44 853d58 # 6 instructions; loads
spin main 86bd68 86bde0 # 9 instructions; loads
spin main 86be14 86be8c # 9 instructions; loads
spin main 871d20 871d34 # 6 instructions; loads
spin main 874a64 874a78 # 6 instructions; loads
spin main 8753a8 8753bc # 6 instructions; loads
spin main 885dc8 885ddc # 6 instructions; loads
spin main 88c4cc 88c4e0 # 6 instructions; loads
spin main 88cb8c 88cc14 # 6 instructions; loads
spin main 88dcf4 88dd08 # 6 instructions; loads
spin main 88de9c 88deb0 # 6 instructions; loads
spin main 88ecc0 88ecd4 # 6 instructions; loads
spin main 88fa2c 88fa40 # 6 instructions; loads
spin main 88fd00 88fd14 # 6 instructions; loads
spin main 8907b8 8907cc # 6 instructions; loads
spin main 890834 890848 # 6 instructions; loads
spin main 893a28 893a3c # 6 instructions; loads
spin main 893b18 893b2c # 6 instructions; loads
spin main 894278 89428c # 6 instructions; loads
spin main 8a5964 8a5978 # 6 instructions; loads
spin main 8ac4fc 8ac510 # 6 instructions; loads
spin main 8b1164 8b1178 # 6 instructions; loads
spin main 8c04c8 8c04dc # 6 instructions; loads
spin main 8c0614 8c0628 # 6 instructions; loads
spin main 8c6b04 8c6b0c # 3 instructions; loads
spin main 8c6b14 8c6b18 # 2 instructions; loads
spin main 8c6b60 8c6b68 # 3 instructions; loads
spin main 8db878 8db88c # 6 instructions; loads
spin main 8dbd38 8dbd4c # 6 instructions; loads
spin main 938098 9380ac # 6 instructions; loads
spin main 93a2f0 93a304 # 6 instructions; loads
spin main 93a508 93a51c # 6 instructions; loads
spin main 93a684 93a698 # 6 instructions; loads
spin main 93b870 93b884 # 6 instructions; loads
spin main 93bab8 93bacc # 6 instructions; loads
spin main 93cab8 93cacc # 6 instructions; loads
spin main 93cd18 93cd2c # 6 instructions; loads
spin main 942d9c 942db0 # 6 instructions; loads
spin main 9436c8 9436dc # 6 instructions; loads
spin main 94400c 944020 # 6 instructions; loads
spin main 94421c 94438c # 6 instructions; loads
spin main 947ce8 947cfc # 6 instructions; loads
spin main 948124 948140 # 8 instructions; loads
spin main 94c13c 94c150 # 6 instructions; loads
spin main 9518d4 9518e8 # 6 instructions; loads
spin main 972e48 972e5c # 6 instructions; loads
spin main 972f44 972f58 # 6 instructions; loads
spin main 973038 97304c # 6 instructions; loads
spin main 97312c 973140 # 6 instructions; loads
spin main 9733fc 973410 # 6 instructions; loads
spin main 974e2c 974e34 # 3 instructions; loads
spin main 974e3c 974e40 # 2 instructions; loads
spin main 974e68 974e70 # 3 instructions; loads
spin main 98810c 988128 # 8 instructions; loads
spin main 996614 996628 # 6 instructions; loads
spin main 999330 999344 # 6 instructions; loads
spin main 9995f0 999604 # 6 instructions; loads
spin main 99b4c4 99b4d8 # 6 instructions; loads
spin main 99b918 99b92c # 6 instructions; loads
spin main 99bd6c 99bd80 # 6 instructions; loads
spin main 99c0d4 99c0e8 # 6 instructions; loads
spin main 99c320 99c334 # 6 instructions; loads
spin main 99d994 99d9a8 # 6 instructions; loads
spin main 9a0318 9a032c # 6 instructions; loads
spin main 9a0490 9a04a4 # 6 instructions; loads
spin main 9a0608 9a061c # 6 instructions; loads
spin main 9a0784 9a0798 # 6 instructions; loads
spin main 9a0900 9a0914 # 6 instructions; loads
spin main 9a0a8c 9a0aa0 # 6 instructions; loads
spin main 9aa844 9aa858 # 6 instructions; loads
spin main 9c7e10 9c7e24 # 6 instructions; loads
spin main 9c7fc8 9c7fdc # 6 instructions; loads
spin main 9c8188 9c819c # 6 instructions; loads
spin main 9d2550 9d2564 # 6 instructions; loads
spin main 9d2ab8 9d2acc # 6 instructions; loads
spin main 9d2ae0 9d2af4 # 6 instructions; loads
spin main 9dd078 9dd08c # 6 instructions; loads
spin main 9deb00 9deb14 # 6 instructions; loads
spin main 9ec4ec 9ec500 # 6 instructions; loads
spin main 9ecbac 9ecbc0 # 6 instructions; loads
spin main a0139c a013b0 # 6 instructions; loads
spin main a099a8 a099bc # 6 instructions; loads
spin main a10f08 a10f1c # 6 instructions; loads
spin main a10f58 a10f6c # 6 instructions; loads
spin main a11284 a11298 # 6 instructions; loads
spin main a16678 a1668c # 6 instructions; loads
spin main a1683c a16850 # 6 instructions; loads
spin main a168f4 a16908 # 6 instructions; loads
spin main a16a14 a16a28 # 6 instructions; loads
spin main a16b00 a16b14 # 6 instructions; loads
spin main a17d70 a17d84 # 6 instructions; loads
spin main a18570 a18584 # 6 instructions; loads
spin main a1db34 a1db48 # 6 instructions; loads
spin main a1ddec a1de00 # 6 instructions; loads
spin main a1e1f8 a1e20c # 6 instructions; loads
spin main a1e464 a1e478 # 6 instructions; loads
spin main a1e5b8 a1e6bc # 6 instructions; loads
spin main a1eff4 a1f008 # 6 instructions; loads
spin main a1f25c a1f270 # 6 instructions; loads
spin main a20084 a20098 # 6 instructions; loads
spin main a200bc a200d0 # 6 instructions; loads
spin main a3aea0 a3aeb4 # 6 instructions; loads
spin main a3b1a8 a3b1bc # 6 instructions; loads
spin main a3b450 a3b464 # 6 instructions; loads
spin main a3b6f0 a3b704 # 6 instructions; loads
spin main a3bfcc a3bfe0 # 6 instructions; loads
spin main a3c2d0 a3c2e4 # 6 instructions; loads
spin main a3c584 a3c598 # 6 instructions; loads
spin main a3c5f0 a3c604 # 6 instructions; loads
spin main a3d8e4 a3d8f8 # 6 instructions; loads
spin main a3db78 a3db8c # 6 instructions; loads
spin main a3dd14 a3dd28 # 6 instructions; loads
spin main a3de28 a3de3c # 6 instructions; loads
spin main a3dfdc a3dff0 # 6 instructions; loads
spin main a3e0cc a3e0e0 # 6 instructions; loads
spin main a3e244 a3e258 # 6 instructions; loads
spin main a3e2fc a3e310 # 6 instructions; loads
spin main a3e3b4 a3e3c8 # 6 instructions; loads
spin main a3e46c a3e480 # 6 instructions; loads
spin main a3e530 a3e544 # 6 instructions; loads
spin main a3e644 a3e658 # 6 instructions; loads
spin main a3e750 a3e764 # 6 instructions; loads
spin main a3e924 a3e938 # 6 instructions; loads
spin main a3ea70 a3eb04 # 6 instructions; loads
spin main a40848 a4085c # 6 instructions; loads
spin main a40874 a40888 # 6 instructions; loads
spin main a41834 a41848 # 6 instructions; loads
spin main a42444 a42458 # 6 instructions; loads
spin main a43398 a433ac # 6 instructions; loads
spin main a4470c a44720 # 6 instructions; loads
spin main a44a04 a44a18 # 6 instructions; loads
spin main a44cc4 a44cd8 # 6 instructions; loads
spin main a44f9c a44fb0 # 6 instructions; loads
spin main a45264 a45278 # 6 instructions; loads
spin main a4552c a45540 # 6 instructions; loads
spin main a4559c a455b0 # 6 instructions; loads
spin main a4b33c a4b350 # 6 instructions; loads
spin main a4b5a8 a4b5bc # 6 instructions; loads
spin main a4b734 a4b748 # 6 instructions; loads
spin main a4b8bc a4b8d0 # 6 instructions; loads
spin main a4bb90 a4bba4 # 6 instructions; loads
spin main a4c260 a4c274 # 6 instructions; loads
spin main a4c2c4 a4c2d8 # 6 instructions; loads
spin main a4c888 a4c89c # 6 instructions; loads
spin main a4ce64 a4ce78 # 6 instructions; loads
spin main a4ce90 a4cea4 # 6 instructions; loads
spin main a4dd1c a4dd30 # 6 instructions; loads
spin main a4e07c a4e090 # 6 instructions; loads
spin main a4e0f0 a4e104 # 6 instructions; loads
spin main a500a0 a500b4 # 6 instructions; loads
spin main a50194 a501a8 # 6 instructions; loads
spin main a501d8 a501ec # 6 instructions; loads
spin main a503e8 a503fc # 6 instructions; loads
spin main a508a0 a508b4 # 6 instructions; loads
spin main a508f0 a50904 # 6 instructions; loads
spin main a52a6c a52a80 # 6 instructions; loads
spin main a52b88 a52b9c # 6 instructions; loads
spin main a52bb4 a52bc8 # 6 instructions; loads
spin main a52c04 a52c18 # 6 instructions; loads
spin main a52cf0 a52d04 # 6 instructions; loads
spin main a53020 a53034 # 6 instructions; loads
spin main a54554 a54568 # 6 instructions; loads
spin main a54f0c a54f20 # 6 instructions; loads
spin main a551bc a551d0 # 6 instructions; loads
spin main a5561c a55630 # 6 instructions; loads
spin main a55640 a55654 # 6 instructions; loads
spin main a58374 a58388 # 6 instructions; loads
spin main a5cd1c a5cd30 # 6 instructions; loads
spin main a5d71c a5d730 # 6 instructions; loads
spin main a5d754 a5d768 # 6 instructions; loads
spin main a5f61c a5f630 # 6 instructions; loads
spin main a61eb0 a61ec4 # 6 instructions; loads
spin main a666fc a66710 # 6 instructions; loads
spin main a6b0f4 a6b108 # 6 instructions; loads
spin main a6d59c a6d5b0 # 6 instructions; loads
spin main a86458 a8646c # 6 instructions; loads
spin main a865dc a865f0 # 6 instructions; loads
spin main a9a618 a9a62c # 6 instructions; loads
spin main a9e5f4 a9e608 # 6 instructions; loads
spin main a9e978 a9e98c # 6 instructions; loads
spin main a9fb24 a9fb38 # 6 instructions; loads
spin main aa93ec aa9400 # 6 instructions; loads
spin main aaa450 aaa464 # 6 instructions; loads
spin main aaa91c aaa930 # 6 instructions; loads
spin main aace80 aace94 # 6 instructions; loads
spin main aad104 aad118 # 6 instructions; loads
spin main aad1d0 aad1e4 # 6 instructions; loads
spin main ab16d4 ab16e8 # 6 instructions; loads
spin main ab18b0 ab18c4 # 6 instructions; loads
spin main ab1ab4 ab1ac8 # 6 instructions; loads
spin main ab1ae8 ab1afc # 6 instructions; loads
spin main ab20d0 ab20e4 # 6 instructions; loads
spin main abb028 abb03c # 6 instructions; loads
spin main abf730 abf744 # 6 instructions; loads
spin main abfbdc abfbf0 # 6 instructions; loads
spin main ac5d0c ac5d20 # 6 instructions; loads
spin main ac5f14 ac5f28 # 6 instructions; loads
spin main ac67a8 ac67bc # 6 instructions; loads
spin main ac8b48 ac8b5c # 6 instructions; loads
spin main ac8e2c ac8e40 # 6 instructions; loads
spin main acd9b0 acd9c4 # 6 instructions; loads
spin main aceedc aceef0 # 6 instructions; loads
spin main ad0654 ad0668 # 6 instructions; loads
spin main ad843c ad8450 # 6 instructions; loads
spin main ae3c90 ae3ca4 # 6 instructions; loads
spin main ae4510 ae4524 # 6 instructions; loads
spin main ae51e8 ae51fc # 6 instructions; loads
spin main ae521c ae5230 # 6 instructions; loads
spin main ae8bc4 ae8bd8 # 6 instructions; loads
spin main aee5cc aee5e0 # 6 instructions; loads
spin main aee8d8 aee8ec # 6 instructions; loads
spin main af4dd0 af4de4 # 6 instructions; loads
spin main af4df8 af4e0c # 6 instructions; loads
spin main af88fc af8910 # 6 instructions; loads
spin main aff3dc aff3f0 # 6 instructions; loads
spin main affbd0 affbe4 # 6 instructions; loads
spin main b09474 b09488 # 6 instructions; loads
spin main b0de70 b0de84 # 6 instructions; loads
spin main b14958 b1496c # 6 instructions; loads
spin main b17ecc b17ee0 # 6 instructions; loads
spin main b1b8b0 b1b8c4 # 6 instructions; loads
spin main b1c15c b1c170 # 6 instructions; loads
spin main b1c4a8 b1c4bc # 6 instructions; loads
spin main b1c6e0 b1c6f4 # 6 instructions; loads
spin main b1c7d4 b1c7e8 # 6 instructions; loads
spin main b1eb20 b1eb34 # 6 instructions; loads
spin main b1fac4 b1fad8 # 6 instructions; loads
spin main b213cc b213e0 # 6 instructions; loads
spin main b21730 b21744 # 6 instructions; loads
spin main b219c8 b219dc # 6 instructions; loads
spin main b21c24 b21c38 # 6 instructions; loads
spin main b23b6c b23b80 # 6 instructions; loads
spin main b26a14 b26a28 # 6 instructions; loads
spin main b30f80 b30f94 # 6 instructions; loads
spin main b3199c b319b0 # 6 instructions; loads
spin main b31e9c b31eb0 # 6 instructions; loads
spin main b324fc b32510 # 6 instructions; loads
spin main b33bd8 b33bec # 6 instructions; loads
spin main b4084c b40860 # 6 instructions; loads
spin main b434fc b43510 # 6 instructions; loads
spin main b43b3c b43b50 # 6 instructions; loads
spin main b43f90 b43fa4 # 6 instructions; loads
spin main b4c470 b4c484 # 6 instructions; loads
spin main b55f24 b55f38 # 6 instructions; loads
spin main b56270 b56284 # 6 instructions; loads
spin main b5c624 b5c638 # 6 instructions; loads
spin main b5cb38 b5cb4c # 6 instructions; loads
spin main b5d0f8 b5d10c # 6 instructions; loads
spin main b5d81c b5d830 # 6 instructions; loads
spin main b6d590 b6d5a4 # 6 instructions; loads
spin main bad0dc bad0f0 # 6 instructions; loads
spin main bd06f0 bd0704 # 6 instructions; loads
spin main c009d4 c009e8 # 6 instructions; loads
spin main c0d404 c0d4f0 # 8 instructions; loads
spin main c14b3c c14b50 # 6 instructions; loads
spin main c242f4 c24308 # 6 instructions; loads
spin main c2a370 c2a384 # 6 instructions; loads
spin main c31338 c3134c # 6 instructions; loads
spin main c31ecc c31ee0 # 6 instructions; loads
spin main c4495c c44970 # 6 instructions; loads
spin main c44a8c c44aa0 # 6 instructions; loads
spin main c45e30 c45e44 # 6 instructions; loads
spin main c52710 c52724 # 6 instructions; loads
spin main c684a8 c684bc # 6 instructions; loads
spin main c6862c c68640 # 6 instructions; loads
spin main c68658 c6866c # 6 instructions; loads
spin main c855e4 c855f8 # 6 instructions; loads
spin main c8724c c87260 # 6 instructions; loads
spin main c87278 c8728c # 6 instructions; loads
spin main c9af88 c9af9c # 6 instructions; loads
spin main c9b218 c9b22c # 6 instructions; loads
spin main ca174c ca1760 # 6 instructions; loads
spin main cb609c cb6144 # 6 instructions; loads
spin main cd0568 cd057c # 6 instructions; loads
spin main ce095c ce0970 # 6 instructions; loads
spin main ce9f88 ce9f9c # 6 instructions; loads
spin main cea378 cea38c # 6 instructions; loads
spin main cea4a8 cea4bc # 6 instructions; loads
spin main cea6dc cea6f0 # 6 instructions; loads
spin main cea7a4 cea7b8 # 6 instructions; loads
spin main cea868 cea8f8 # 6 instructions; loads
spin main cea908 cea998 # 6 instructions; loads
spin main cea9a8 cea9c0 # 7 instructions; loads
spin main cebb5c cebb70 # 6 instructions; loads
spin main cebc40 cebc54 # 6 instructions; loads
spin main cebec4 cebed8 # 6 instructions; loads
spin main cec920 cec934 # 6 instructions; loads
spin main cecdc0 cecdd4 # 6 instructions; loads
spin main cecf38 cecfc0 # 6 instructions; loads
spin main cecfd4 ced05c # 6 instructions; loads
spin main ced078 ced104 # 6 instructions; loads
spin main ced114 ced1a0 # 6 instructions; loads
spin main ced1ac ced234 # 6 instructions; loads
spin main ced240 ced2c8 # 6 instructions; loads
spin main ceeef8 ceef0c # 6 instructions; loads
spin main cefa48 cefa5c # 6 instructions; loads
spin main d0adc8 d0addc # 6 instructions; loads
spin main d14f78 d14f8c # 6 instructions; loads
spin main d15240 d15254 # 6 instructions; loads
spin main d186dc d186f0 # 6 instructions; loads
spin main d1b400 d1b414 # 6 instructions; loads
spin main d1c4bc d1c4d0 # 6 instructions; loads
spin main d204e4 d204f8 # 6 instructions; loads
spin main d21a70 d21a84 # 6 instructions; loads
spin main d22ba8 d22bbc # 6 instructions; loads
spin main d33ae0 d33af4 # 6 instructions; loads
spin main d34268 d3427c # 6 instructions; loads
spin main d40fb4 d40fc8 # 6 instructions; loads
spin main d448d0 d448e4 # 6 instructions; loads
spin main d4504c d45060 # 6 instructions; loads
spin main d460ec d46100 # 6 instructions; loads
spin main d478b8 d478cc # 6 instructions; loads
spin main d480b0 d480c4 # 6 instructions; loads
spin main d4b6c4 d4b6d8 # 6 instructions; loads
spin main d54af0 d54b04 # 6 instructions; loads
spin main d577dc d577f0 # 6 instructions; loads
spin main d7449c d744b0 # 6 instructions; loads
spin main d74bc0 d74bd4 # 6 instructions; loads
spin main d74c70 d74c84 # 6 instructions; loads
spin main d74d48 d74d5c # 6 instructions; loads
spin main d775c0 d775d4 # 6 instructions; loads
spin main d7846c d78480 # 6 instructions; loads
spin main d792b8 d7938c # 6 instructions; loads
spin main d79898 d798ac # 6 instructions; loads
spin main d82cfc d82d10 # 6 instructions; loads
spin main d86904 d86918 # 6 instructions; loads
spin main d88eec d88f00 # 6 instructions; loads
spin main d8a8c0 d8a8d4 # 6 instructions; loads
spin main d8bc68 d8bc7c # 6 instructions; loads
spin main d8d144 d8d158 # 6 instructions; loads
spin main d8d50c d8d520 # 6 instructions; loads
spin main da05c4 da05d8 # 6 instructions; loads
spin main da1410 da1424 # 6 instructions; loads
spin main da46c0 da46d4 # 6 instructions; loads
spin main da471c da4730 # 6 instructions; loads
spin main da4898 da48ac # 6 instructions; loads
spin main da6f94 da6fa8 # 6 instructions; loads
spin main da7040 da7054 # 6 instructions; loads
spin main da70d4 da70e8 # 6 instructions; loads
spin main dab860 dab874 # 6 instructions; loads
spin main dab9c4 dab9d8 # 6 instructions; loads
spin main daf8f0 daf904 # 6 instructions; loads
spin main db014c db0160 # 6 instructions; loads
spin main db04c8 db04dc # 6 instructions; loads
spin main db071c db0730 # 6 instructions; loads
spin main db1e1c db1e30 # 6 instructions; loads
spin main e19994 e199a8 # 6 instructions; loads
spin main e19e54 e19e68 # 6 instructions; loads
spin main e1ae08 e1ae1c # 6 instructions; loads
spin main e1d7fc e1d810 # 6 instructions; loads
spin main e1ea1c e1ea30 # 6 instructions; loads
spin main e1f2d0 e1f2e4 # 6 instructions; loads
spin main e1f5b4 e1f5c8 # 6 instructions; loads
spin main e1f5fc e1f610 # 6 instructions; loads
spin main e1ffe4 e1fff8 # 6 instructions; loads
spin main e22330 e22344 # 6 instructions; loads
spin main e22704 e22718 # 6 instructions; loads
spin main e229bc e229d0 # 6 instructions; loads
spin main e22f2c e22f40 # 6 instructions; loads
spin main e23374 e23388 # 6 instructions; loads
spin main e23668 e2367c # 6 instructions; loads
spin main e26f44 e26f58 # 6 instructions; loads
spin main e27080 e27094 # 6 instructions; loads
spin main e27430 e27444 # 6 instructions; loads
spin main e280ac e280c0 # 6 instructions; loads
spin main e281b8 e281cc # 6 instructions; loads
spin main e28e78 e28e8c # 6 instructions; loads
spin main e29bc8 e29bdc # 6 instructions; loads
spin main e2a3a4 e2a3b8 # 6 instructions; loads
spin main e2a960 e2a974 # 6 instructions; loads
spin main e2d3b8 e2d3cc # 6 instructions; loads
spin main e2defc e2df10 # 6 instructions; loads
spin main e2eb5c e2eb70 # 6 instructions; loads
spin main e2ed08 e2ed1c # 6 instructions; loads
spin main e309b0 e309c4 # 6 instructions; loads
spin main e30c60 e30c74 # 6 instructions; loads
spin main e31a1c e31a30 # 6 instructions; loads
spin main e33398 e333ac # 6 instructions; loads
spin main e34d10 e34d24 # 6 instructions; loads
spin main e35060 e35074 # 6 instructions; loads
spin main e35af8 e35b0c # 6 instructions; loads
spin main ec09cc ec09e0 # 6 instructions; loads
spin main ecd874 ecd888 # 6 instructions; loads
spin main ee3648 ee365c # 6 instructions; loads
spin main ee3fa4 ee3fb8 # 6 instructions; loads
spin main f39bc0 f39bd4 # 6 instructions; loads
spin main f39cd8 f39cec # 6 instructions; loads
spin main 10997cc 10997e0 # 6 instructions; loads
spin main 1099b9c 1099bb0 # 6 instructions; loads
spin main 109ce5c 109ce70 # 6 instructions; loads
spin main 109d20c 109d220 # 6 instructions; loads
spin main 109dc8c 109dca0 # 6 instructions; loads
spin main 109e4d4 109e4e8 # 6 instructions; loads
spin main 109efd8 109efec # 6 instructions; loads
spin main 10a52e4 10a52f8 # 6 instructions; loads
spin main 111b2c4 111b2cc # 3 instructions; loads
spin main 1144cc0 1144ce0 1144cf0 # 13 instructions; loads
spin main 1144d40 1144d68 1144d78 # 15 instructions; loads
spin main 1144db0 1144dd8 1144de8 # 15 instructions; loads
spin main 12c2d00 12c2d14 # 6 instructions; loads
spin main 1861cb8 1861ccc # 6 instructions; loads
spin main 187ce28 187ce3c # 6 instructions; loads
spin main 195af84 195af98 # 6 instructions; loads
spin main 197a160 197a174 # 6 instructions; loads
spin main 1995314 1995328 # 6 instructions; loads
spin main 1b079c4 1b079d8 # 6 instructions; loads
spin main 1b09ac8 1b09adc # 6 instructions; loads
spin main 1b19108 1b1911c # 6 instructions; loads
spin main 1b1b8d8 1b1b8ec # 6 instructions; loads
spin main 1b4ad40 1b4ad54 # 6 instructions; loads
spin main 1b4d308 1b4d31c # 6 instructions; loads
spin main 1b8016c 1b80180 # 6 instructions; loads
spin main 1b87780 1b87794 # 6 instructions; loads
spin main 1ba10c0 1ba10d4 # 6 instructions; loads
spin main 1bb1b98 1bb1bac # 6 instructions; loads
spin main 1bc4578 1bc458c # 6 instructions; loads
spin main 1bc4678 1bc468c # 6 instructions; loads
spin main 1bc57d8 1bc57ec # 6 instructions; loads
spin main 1bc5938 1bc594c # 6 instructions; loads
spin main 1bf0a54 1bf0a68 # 6 instructions; loads
spin main 1bf41bc 1bf41d0 # 6 instructions; loads
spin main 1bf7cb8 1bf7ccc # 6 instructions; loads
spin main 1c1df28 1c1df3c # 6 instructions; loads
spin main 1c4cf40 1c4cf54 # 6 instructions; loads
spin main 1d21008 1d2101c # 6 instructions; loads
spin main 1d96ea4 1d96eb8 # 6 instructions; loads
spin main 1edc4d8 1edc4e8 # 5 instructions; loads
spin main 1f55a94 1f55aa8 # 6 instructions; loads
spin main 1f57098 1f570ac # 6 instructions; loads
spin main 1f8dcb4 1f8dcbc # 3 instructions; loads
spin main 1f8dcc4 1f8dcc8 # 2 instructions; loads
spin main 1f8dd64 1f8dd6c # 3 instructions; loads
spin main 1f8de34 1f8de3c # 3 instructions; loads
spin main 1f8de44 1f8de48 # 2 instructions; loads
spin main 1f8ded8 1f8dee0 # 3 instructions; loads
spin main 1fa0dd4 1fa0ddc # 3 instructions; loads
spin main 1fa0de4 1fa0de8 # 2 instructions; loads
spin main 1fa0e0c 1fa0e14 # 3 instructions; loads
spin main 1fa0e44 1fa0e4c # 3 instructions; loads
spin main 1fa0e54 1fa0e58 # 2 instructions; loads
spin main 1fa0e80 1fa0e88 # 3 instructions; loads
spin main 1fcd71c 1fcd724 # 3 instructions; loads
spin main 1fcd72c 1fcd730 # 2 instructions; loads
spin main 1fcd754 1fcd75c # 3 instructions; loads
spin main 224cdbc 224cdd0 # 6 instructions; loads
spin main 224ce44 224ce58 # 6 instructions; loads
spin main 2437524 2437570 # 20 instructions; loads
spin main 24799dc 24799e8 # 4 instructions; loads
spin main 281d710 281d718 # 3 instructions; loads
spin main 281d720 281d724 # 2 instructions; loads
spin main 281d758 281d760 # 3 instructions; loads
spin main 281d808 281d810 # 3 instructions; loads
spin main 281d818 281d81c # 2 instructions; loads
spin main 2857518 2857540 # 3 instructions; loads
spin main 28604d0 28604f8 # 11 instructions; loads
spin main 2860868 2860894 # 12 instructions; loads
spin main 28608a8 28608c4 # 8 instructions; loads
spin main 288a380 288a388 # 3 instructions; loads
spin main 288a390 288a394 # 2 instructions; loads
spin main 288a3ac 288a3b4 # 3 instructions; loads
spin main 288a3c8 288a3d0 # 3 instructions; loads
spin main 288a3d8 288a3dc # 2 instructions; loads
spin main 288a464 288a46c # 3 instructions; loads
spin main 289bca0 289bcb8 # 7 instructions; loads
spin main 29094cc 2909514 # 3 instructions; loads
spin main 290e8a0 290e8c0 # 4 instructions; loads
spin main 290e980 290e9a0 # 4 instructions; loads
spin main 2917ccc 2917ccc 2917cd4 # 3 instructions; loads
spin main 2a88d64 2a88d6c # 3 instructions; loads
spin main 2a88d74 2a88d78 # 2 instructions; loads
spin main 2a88de4 2a88dec # 3 instructions; loads
spin main 2a89ba4 2a89bac # 3 instructions; loads
spin main 2a89bb4 2a89bb8 # 2 instructions; loads
spin main 2a89c24 2a89c2c # 3 instructions; loads
spin main 2a8a108 2a8a110 # 3 instructions; loads
spin main 2a8a118 2a8a11c # 2 instructions; loads
spin main 2a8a1dc 2a8a1e4 # 3 instructions; loads
spin main 2a8a864 2a8a86c # 3 instructions; loads
spin main 2a8a874 2a8a878 # 2 instructions; loads
spin main 2a8a8d4 2a8a8dc # 3 instructions; loads
spin main 2a8a918 2a8a920 # 3 instructions; loads
spin main 2a8a928 2a8a92c # 2 instructions; loads
spin main 2a8a954 2a8a95c # 3 instructions; loads
spin main 2a8a9a4 2a8a9ac # 3 instructions; loads
spin main 2a8a9b4 2a8a9b8 # 2 instructions; loads
spin main 2a8aac8 2a8aad0 # 3 instructions; loads
spin main 2a8aee8 2a8aef0 # 3 instructions; loads
spin main 2a8aef8 2a8aefc # 2 instructions; loads
spin main 2a8af68 2a8af70 # 3 instructions; loads
spin main 2a8afc0 2a8afc8 # 3 instructions; loads
spin main 2a8afd0 2a8afd4 # 2 instructions; loads
spin main 2a8aff8 2a8b000 # 3 instructions; loads
spin main 2a8b738 2a8b740 # 3 instructions; loads
spin main 2a8b748 2a8b74c # 2 instructions; loads
spin main 2a8b7a0 2a8b7a8 # 3 instructions; loads
spin main 2a8b890 2a8b898 # 3 instructions; loads
spin main 2a8b8a0 2a8b8a4 # 2 instructions; loads
spin main 2a8b940 2a8b948 # 3 instructions; loads
spin main 2a8b980 2a8b988 # 3 instructions; loads
spin main 2a8b990 2a8b994 # 2 instructions; loads
spin main 2a8b9ec 2a8b9f4 # 3 instructions; loads
spin main 2a8bb48 2a8bb50 # 3 instructions; loads
spin main 2a8bb58 2a8bb5c # 2 instructions; loads
spin main 2a8bbf8 2a8bc00 # 3 instructions; loads
spin main 2a8bc2c 2a8bc34 # 3 instructions; loads
spin main 2a8bc3c 2a8bc40 # 2 instructions; loads
spin main 2a8bc7c 2a8bc84 # 3 instructions; loads
spin main 2a8ce78 2a8ce80 # 3 instructions; loads
spin main 2a8ce88 2a8ce8c # 2 instructions; loads
spin main 2a8cee0 2a8cee8 # 3 instructions; loads
spin main 2a8cf24 2a8cf2c # 3 instructions; loads
spin main 2a8cf34 2a8cf38 # 2 instructions; loads
spin main 2a8d070 2a8d078 # 3 instructions; loads
spin main 2a8d0b0 2a8d0b8 # 3 instructions; loads
spin main 2a8d0c0 2a8d0c4 # 2 instructions; loads
spin main 2a8d1d0 2a8d1d8 # 3 instructions; loads
spin main 2a8e670 2a8e678 # 3 instructions; loads
spin main 2a8e680 2a8e684 # 2 instructions; loads
spin main 2a8e6f8 2a8e700 # 3 instructions; loads
spin main 2a8e728 2a8e730 # 3 instructions; loads
spin main 2a8e738 2a8e73c # 2 instructions; loads
spin main 2a8e804 2a8e80c # 3 instructions; loads
spin main 2a8f44c 2a8f454 # 3 instructions; loads
spin main 2a8f45c 2a8f460 # 2 instructions; loads
spin main 2a8f4e0 2a8f4e8 # 3 instructions; loads
spin main 2a8f51c 2a8f524 # 3 instructions; loads
spin main 2a8f52c 2a8f530 # 2 instructions; loads
spin main 2a8f580 2a8f588 # 3 instructions; loads
spin main 2a92710 2a92718 # 3 instructions; loads
spin main 2a92720 2a92724 # 2 instructions; loads
spin main 2a92740 2a92748 # 3 instructions; loads
spin main 2ac7fb8 2ac7fc4 2ac800c 2ac8028 # 29 instructions; loads
spin main 2b0e760 2b0e848 # 7 instructions; loads
spin subsdk0 2060 2074 # 6 instructions; loads
spin subsdk0 27804 27818 2787c 278c4 # 23 instructions; stc
spin subsdk0 baf78 bb020 bb028 # 12 instructions; loads
spin subsdk0 bb118 bb1c0 bb1c8 # 12 instructions; loads
spin subsdk0 be334 be348 # 6 instructions; loads
spin subsdk0 1bfbd4 1bfbe0 # 4 instructions; loads
spin subsdk0 1c1588 1c159c # 6 instructions; loads
spin subsdk0 1c4a78 1c4a94 1c4aa0 # 11 instructions; loads
spin subsdk0 1c4e54 1c4e60 # 4 instructions; loads
spin sdk 2d3654 2d3668 # 6 instructions; loads
spin sdk 443864 443884 # 9 instructions; loads
spin sdk 541e54 541f98 # 32 instructions; loads
+39 -3
View File
@@ -6,6 +6,8 @@ Lifted code cannot be byte-patched when the game runs, so a patch is applied whe
set <name> <env> <default> a patch set: a run-time switch <env>=0/1, <default> when it is unset
site <set> <module> <address> <original> <replacement> [<replacement> ...]
spin <module> <head> <back-edge> [<back-edge> ...]
<address> is a module offset (hex), <original> the instruction word the module has there (checked; a mismatch stops
the generator), each <replacement> an instruction word (hex) or `@page:x<n>`, which is `adrp x<n>, <patch page>`
encoded for the site's address. The patch page is the first 4 KiB page after main's image (layout.py leaves the rest
@@ -16,6 +18,11 @@ The replacement words are lifted at the site's address in place of the original
words must not branch except a final `bl` (lifted with the site's return address); the original must not be a branch
other than `bl`. So the function's control flow, labels and jump tables are the original's. The generator writes
patches.h (set names, switches, the page address) next to layout.h for the runtime.
A `spin` line names a spin wait found by tools/spin_waits.py: a loop with head <head> that only another thread can end,
and the direct branches back to it (module offsets). Each back-edge (checked: a b, b.cond, cbz / cbnz or tbz / tbnz to
<head>) is lifted as `rt_spin_gate(c, <head>); goto <head>`, which keeps every register and only adds time
(runtime/kernel.c kern_spin_gate).
"""
from pathlib import Path
@@ -37,10 +44,15 @@ def adrp(pc, target, rd):
class Table:
"""sets: [(name, env, default)]; sites: {module: {offset: (set index, [word | ('page', reg)], original)}}; page."""
def __init__(self, sets=(), sites=None, page=0):
def __init__(self, sets=(), sites=None, page=0, spins=None):
self.sets = list(sets)
self.sites = sites or {}
self.page = page
self.spins = spins or {} # {module: {back-edge offset: head offset}}
def spins_for(self, name, base):
"""{absolute back-edge address: absolute head address}."""
return {base + b: base + h for b, h in self.spins.get(name, {}).items()}
def for_module(self, name, base):
"""{absolute address: (set index, [words])} with @page resolved."""
@@ -53,7 +65,7 @@ class Table:
def load(path, mods):
"""Table from a patch file; mods is layout() output [(name, base, size)]."""
sets, index, sites = [], {}, {}
sets, index, sites, spins = [], {}, {}, {}
bases = {n: (b, s) for n, b, s in mods}
for no, raw in enumerate(Path(path).read_text().splitlines(), 1):
f = raw.split('#', 1)[0].split()
@@ -81,6 +93,15 @@ def load(path, mods):
if off in mod:
raise PatchError(f'{where}: {f[2]}+{off:#x} patched twice')
mod[off] = (index[f[1]], repl, orig)
elif f[0] == 'spin' and len(f) >= 4:
if f[1] not in bases:
raise PatchError(f'{where}: module {f[1]} not in the layout')
mod, head = spins.setdefault(f[1], {}), int(f[2], 16)
for b in f[3:]:
b = int(b, 16)
if b in mod:
raise PatchError(f'{where}: {f[1]}+{b:#x} is a back-edge twice')
mod[b] = head
else:
raise PatchError(f'{where}: cannot parse {raw!r}')
base, size = bases['main'][0], bases['main'][1]
@@ -88,7 +109,7 @@ def load(path, mods):
nxt = min((b for _, b, _ in mods if b > base), default=None)
if nxt is not None and page + PAGE > nxt:
raise PatchError(f'no room for the patch page after main ({page:#x})')
return Table(sets, sites, page)
return Table(sets, sites, page, spins)
def check(table, mod, name):
@@ -100,6 +121,21 @@ def check(table, mod, name):
have = mod.word(a)
if have != want:
raise PatchError(f'{name}+{off:#x}: module has {have:08x}, the patch expects {want:08x}')
for b, head in table.spins.get(name, {}).items():
a = mod.base + b
if not mod.in_text(a) or branch_target(mod.word(a), a) != mod.base + head:
raise PatchError(f'{name}+{b:#x}: not a direct branch to the spin wait head {name}+{head:#x}')
def branch_target(w, a):
"""Target of the direct branch w at a (b, b.cond, cbz / cbnz, tbz / tbnz), or None."""
if w >> 26 == 0x05:
return a + ((((w & 0x3FFFFFF) ^ 0x2000000) - 0x2000000) << 2)
if w & 0xFF000010 == 0x54000000 or w & 0x7E000000 == 0x34000000:
return a + ((((w >> 5) & 0x7FFFF) ^ 0x40000) - 0x40000 << 2)
if w & 0x7E000000 == 0x36000000:
return a + ((((w >> 5) & 0x3FFF) ^ 0x2000) - 0x2000 << 2)
return None
def header_text(table, marker):
+1 -1
View File
@@ -45,7 +45,7 @@ static const char *const known[] = {
"RENDER_SCALE", "REPLAY_ASYNC",
"REPLAY_CHECK", "RESOLVE_CHECK", "ROMFS", "ROMFS_INDEX", "ROMFS_MMAP", "ROMFS_MODS", "ROMFS_PATCHES",
"ROMFS_PROOF_DIR", "ROMFS_VERIFY", "RUMBLE", "RUMBLE_CURVE", "RUMBLE_STRENGTH", "RUMBLE_TRIGGERS", "SHADER_CACHE",
"SHADER_MEMO", "SHARED_FONTS", "SHARPNESS", "SHOTS", "SHOTS_DIR", "SHOTS_FULL", "SPEED_PROBE", "SPLIT_DRAWS", "SWKBD_ANSWER",
"SHADER_MEMO", "SHARED_FONTS", "SHARPNESS", "SHOTS", "SHOTS_DIR", "SHOTS_FULL", "SPEED_PROBE", "SPIN", "SPIN_HANDOFF_US", "SPLIT_DRAWS", "SWKBD_ANSWER",
"SWKBD_TEST", "TEST_PREPARE_SHADERS", "TEX_ALIAS", "TEX_MEMO", "TIMER_1MS", "TRACE", "UPSCALER", "VK_DYN_VERTEX", "VK_NO_FLOAT64",
"VK_PRESENT", "VK_SSBO_ALIGN", "VK_SUBGROUP", "VK_SUBGROUP_PIN", "VK_VALIDATION", "VOLUME", "VS_OUTS",
"WINDOW_SIZE", "XLATE", "XLATE_ID", "XLATE_PROCS",
+1
View File
@@ -35,6 +35,7 @@ typedef void (*GuestFn)(Cpu *);
// ---- runtime services (runtime/*.c)
void rt_dispatch(Cpu *c); // call function at c->pc
void rt_spin_gate(Cpu *c, uint64_t head); // a pass of a spin wait loop (kernel.c, recomp/patches.py `spin`)
void rt_svc(Cpu *c, uint32_t imm, uint64_t pc);
void rt_brk(Cpu *c, uint32_t imm, uint64_t pc) __attribute__((noreturn));
void rt_udf(Cpu *c, uint64_t pc) __attribute__((noreturn));
+53
View File
@@ -91,6 +91,7 @@ struct RtThread {
uint32_t waker; // the thread whose signal ended the last wait (0: a host thread or a timeout)
uint64_t wake_at, grant_at; // when a wait was signalled and a core granted, until the thread runs again
uint64_t lw_ns, lw_n, lw_max, lg_ns, lg_n, lg_max, sl_n, sl_req, sl_act; // those latencies; SleepThread asked/took
uint64_t sp_n, sp_ho, sp_site; // spin wait passes and core handoffs, the last loop head (the thread writes them)
RtThread *target; // as a core waiter: the owner core_kick asked to give its core up for it (holding G)
// TOTK_ASYNC_PREEMPT (holding G)
HANDLE hthr; // the host thread, for SuspendThread / Get/SetThreadContext; open while it may own a core
@@ -927,6 +928,50 @@ void kern_core_back(int *away) {
*away = 0;
}
// ---- spin waits (recomp/patches.py `spin` lines, found by tools/spin_waits.py)
// Adapted from MacNativeGames games/totk/runtime/threads.c runtime_spin_wait @ a038e6b and nxnative dm/host/hle_thread.c
// dm_spin_wait @ 6d34984 (MIT, Copyright (c) 2026 MacNativeGames contributors, Copyright (c) 2026 seedds).
// A pass of a guest loop that polls memory until another thread changes it. On the Switch it fills only its own core,
// where a better thread pinned there preempts it; here it holds a virtual core and a host core, and pollers that take a
// lock on every pass hand its cache line between their host cores so the thread whose item it is rarely gets it
// (nxnative 6d34984, Breath of the Wild's job queue). Every pass pauses the host core once. A wait is a run of passes
// through the same loop at most SPIN_GAP_NS apart; once one has lasted TOTK_SPIN_HANDOFF_US (default 50) and a thread
// waits for a virtual core, each pass gives the core to the waiter, whatever its priority, yields the host CPU and
// takes a core again. Shorter waits keep the core: a lock held for a moment would otherwise make the next pass wait
// for another thread's next SVC (MacNativeGames). TOTK_SPIN=0 keeps the core always (the gate's own cost only).
#define SPIN_GAP_NS 20000ull
static int g_spin_on = -1;
static uint64_t g_spin_handoff_ns;
static _Thread_local uint64_t sw_head, sw_t0, sw_last;
void rt_spin_gate(Cpu *c, uint64_t head) {
(void)c;
YieldProcessor();
RtThread *t = tcur;
if (!t) return;
if (g_spin_on < 0) {
const char *e = cfg_get("TOTK_SPIN_HANDOFF_US");
g_spin_handoff_ns = (uint64_t)(e && *e ? atoll(e) : 50) * 1000;
g_spin_on = !(cfg_get("TOTK_SPIN") && !cfg_bool("TOTK_SPIN"));
}
t->sp_n++;
t->sp_site = head;
uint64_t now = kern_now_ns();
if (head != sw_head || now - sw_last > SPIN_GAP_NS) { // a new wait
sw_head = head;
sw_t0 = now;
}
sw_last = now;
if (!g_spin_on || t->cur_core < 0 || now - sw_t0 < g_spin_handoff_ns ||
!__atomic_load_n(&g_core_wait, __ATOMIC_RELAXED)) // a racy look: a waiter missed now is seen at the next pass
return;
t->sp_ho++;
int away = kern_core_away();
SwitchToThread();
kern_core_back(&away);
sw_last = kern_now_ns();
}
// A pending preempt request, at an SVC or an indirect call. The core goes over only if a better thread still waits
// for it, so core_put grants it to a waiter better than t; a stale request (that waiter got another core) is dropped.
void kern_checkpoint(void) {
@@ -1010,6 +1055,7 @@ void kern_sched_report(uint64_t frame) {
uint32_t h;
int prio, render;
uint64_t mask, entry, ns[S_N], nblk, npre, cpu, lw_ns, lw_n, lw_max, lg_ns, lg_n, lg_max, sl_n, sl_req, sl_act;
uint64_t sp_n, sp_ho, sp_site;
} Row;
Row rows[REP_N + 1];
WaitRec rw[2][4] = {0}; // the render and the main thread's longest waits
@@ -1061,6 +1107,7 @@ void kern_sched_report(uint64_t frame) {
r->lw_ns = t->lw_ns, r->lw_n = t->lw_n, r->lw_max = t->lw_max;
r->lg_ns = t->lg_ns, r->lg_n = t->lg_n, r->lg_max = t->lg_max;
r->sl_n = t->sl_n, r->sl_req = t->sl_req, r->sl_act = t->sl_act;
r->sp_n = t->sp_n, r->sp_ho = t->sp_ho, r->sp_site = t->sp_site;
r->cpu = 0;
HANDLE th = t->tid ? OpenThread(THREAD_QUERY_LIMITED_INFORMATION, FALSE, t->tid) : NULL;
FILETIME a, b, k, u;
@@ -1088,6 +1135,7 @@ void kern_sched_report(uint64_t frame) {
memset(t->st_ns, 0, sizeof t->st_ns);
t->nblk = t->npre = 0;
t->lw_ns = t->lw_n = t->lw_max = t->lg_ns = t->lg_n = t->lg_max = t->sl_n = t->sl_req = t->sl_act = 0;
t->sp_n = t->sp_ho = 0; // racy against the thread's own increments: a few passes may be lost
}
memset(g_rw, 0, sizeof g_rw);
memset(g_mw, 0, sizeof g_mw);
@@ -1115,6 +1163,11 @@ void kern_sched_report(uint64_t frame) {
r->lw_max / 1e3, (unsigned long long)r->lw_n, r->lg_n ? r->lg_ns / 1e3 / r->lg_n : 0.0, r->lg_max / 1e3,
(unsigned long long)r->lg_n, (unsigned long long)r->sl_n, r->sl_n ? r->sl_req / 1e3 / r->sl_n : 0.0,
r->sl_n ? r->sl_act / 1e3 / r->sl_n : 0.0);
if (r->sp_n) {
ldr_describe(r->sp_site, d, sizeof d);
rt_log("sched: %#x spin wait passes %llu, core handoffs %llu, last at %s", r->h,
(unsigned long long)r->sp_n, (unsigned long long)r->sp_ho, d);
}
}
for (int k = 0; k < 2; k++)
for (int j = 0; j < 4 && rw[k][j].ns; j++) {
+24 -7
View File
@@ -10,7 +10,11 @@ PC reaches the sentinel. A case is skipped when Unicorn faults, writes outside t
mapped read-only), leaves the function, or runs longer than --steps instructions. Compares X0-X30, SP, NZCV, V0-V31
and the scratch buffer.
With --patches, the spin waits of the table (recomp/patches.py `spin`) are emitted with their gates, and functions
that hold one come first (a quarter of the picks at most); a case whose loop does not leave runs into --steps.
Usage: func.py [--exefs DIR] [--modules main,subsdk0,sdk] [--functions N] [--cases K] [--seed S] [--jobs J]
[--patches FILE]
"""
import argparse
import os
@@ -29,6 +33,7 @@ from unicorn import arm64_const as A
from common import BUF, BUF_SIZE, MSYS_BIN, ROOT, Emu, compiler, diff_state, rand_fpcr, rand_v, rand_x, run_harness
import gen
import patches
from layout import layout
from module import Module
@@ -60,8 +65,9 @@ def simd_mask(w):
return ((w & 0x0E000000) == 0x0E000000) | (((w & 0x0A000000) == 0x08000000) & (((w >> 26) & 1) == 1))
def pick_functions(name, mod, count, r):
"""[(entry, end, tags)] of up to count leaf functions of mod, plus the Emitter that will emit them."""
def pick_functions(name, mod, count, r, spins=None):
"""[(entry, end, tags)] of up to count leaf functions of mod, plus the Emitter that will emit them. spins: {spin
wait back-edge: head}, emitted with gates."""
starts, _ = gen.discover(mod)
w = mod.words
ends = np.append(starts[1:], len(w))
@@ -78,18 +84,26 @@ def pick_functions(name, mod, count, r):
rest = [int(i) for i in cand if not has_br[i]]
r.shuffle(with_br)
r.shuffle(rest)
emitter = gen.Emitter(mod, set((mod.lo + starts * 4).tolist()))
spins = spins or {}
gated = np.searchsorted(mod.lo + starts * 4, np.array(sorted(spins), dtype=np.int64), side='right') - 1
with_spin = sorted({int(i) for i in gated} & set(cand.tolist()))
r.shuffle(with_spin)
emitter = gen.Emitter(mod, set((mod.lo + starts * 4).tolist()), None, spins)
picks, tags_seen = [], Counter()
# Functions with a br first (jump tables, fallbacks), at most a quarter of the picks.
for pool, quota in ((with_br, count // 4), (rest, count)):
# Functions with a spin wait first, then with a br (jump tables, fallbacks), at most a quarter of the picks each.
for pool, quota in ((with_spin, count // 4), (with_br, count // 4), (rest, count)):
taken = 0
for i in pool:
if len(picks) >= count or taken >= quota:
break
entry, end = mod.lo + int(starts[i]) * 4, mod.lo + int(ends[i]) * 4
if any(e == entry for e, _, _ in picks):
continue
tags = check_function(emitter, entry, end)
if tags is None:
continue
if any(spins.get(x) is not None for x in range(entry, end, 4)):
tags.add('spin_gate')
picks.append((entry, end, tags))
tags_seen.update(tags)
taken += 1
@@ -241,6 +255,7 @@ def main():
ap.add_argument('--seed', type=int, default=1)
ap.add_argument('--jobs', type=int, default=os.cpu_count() or 4)
ap.add_argument('--show', type=int, default=20)
ap.add_argument('--patches', type=Path, help='patch table whose spin waits are emitted with their gates')
ap.add_argument('--cflags', default='-march=x86-64-v3' if platform.machine().lower() in ('amd64', 'x86_64') else '')
args = ap.parse_args()
r = random.Random(args.seed)
@@ -250,14 +265,16 @@ def main():
work = ROOT / 'build' / 'test' / 'func'
work.mkdir(parents=True, exist_ok=True)
images, emitted, tags = [], [], []
for name, base, _ in layout(args.exefs):
mods = layout(args.exefs)
table = patches.load(args.patches, mods) if args.patches else patches.Table()
for name, base, _ in mods:
if name not in want:
continue
mod = Module(name, args.exefs / name, base, 'c')
img = work / f'{name}.img'
img.write_bytes(mod.image)
images.append((base, img, mod.image))
picks, emitter = pick_functions(name, mod, args.functions, r)
picks, emitter = pick_functions(name, mod, args.functions, r, table.spins_for(name, base))
for entry, end, t in picks:
emitted.append((name, entry, end, emitter))
tags.append(t)
+1
View File
@@ -20,6 +20,7 @@ extern int ntests;
#define BUF_SIZE 0x40000
void rt_dispatch(Cpu *c) { (void)c; }
void rt_spin_gate(Cpu *c, uint64_t head) { (void)c; (void)head; }
void rt_svc(Cpu *c, uint32_t imm, uint64_t pc) { (void)c; (void)imm; (void)pc; }
void rt_brk(Cpu *c, uint32_t imm, uint64_t pc) { (void)c; (void)imm; (void)pc; abort(); }
void rt_udf(Cpu *c, uint64_t pc) { (void)c; (void)pc; abort(); }
+80
View File
@@ -0,0 +1,80 @@
# Adapted from nxnative dm/tools/tests/test_spin_waits.py @ 6d34984 (MIT, Copyright (c) 2026 seedds).
"""tools/spin_waits.py on hand-assembled AArch64 loops, without game files.
Run: .venv/Scripts/python tests/spin_waits_test.py
"""
import struct
import sys
import unittest
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / 'tools'))
from spin_waits import Search # noqa: E402
# A job queue poll (the shape of Breath of the Wild's main+0xef6354): take the queue's spin lock, look whether the wait
# is over, release the lock, again.
# 0x00 T: cbz x20, X 0x2c str w12, [x20, #0x100] 0x50 ldr w13, [x21, #0x90]
# 0x04 str w11, [x20, #0x100] 0x30 ldrb w14, [x21, #0x98] 0x54 sub w8, w13, w25
# 0x08 L0: ldr w14, [x9] 0x34 cmp w0, #0 0x58 add w15, w8, w25
# 0x0c cmp w14, #1 0x38 ccmp w14, #0, #4, ne 0x5c str w15, [x21, #0x94]
# 0x10 b.eq L0 0x3c ldr w25, [x21, #0x94] 0x60 cset w13, hs
# 0x14 L1: ldaxr w14, [x9] 0x40 ccmp w25, #0, #0, ne 0x64 b U
# 0x18 cbz w14, L2 0x44 cset w14, gt 0x68 C: clrex
# 0x1c clrex 0x48 cmp w14, #1 0x6c U: ldxr w15, [x9] / cmp w15, #1 / b.ne C
# 0x20 b L1 0x4c b.ne U 0x78 stlxr w15, wzr, [x9] / cbnz w15, U
# 0x24 L2: stxr w14, w10, [x9] / cbnz w14, L1 0x80 cbz w14, T 0x84 X: ret
# 0x50-0x64: the wait is over, take an item, store the new cursor, release and leave.
POLL = [0xb4000434, 0xb901028b, 0xb940012e, 0x710005df, 0x54ffffc0, 0x885ffd2e, 0x3400006e, 0xd5033f5f, 0x17fffffd,
0x880e7d2a, 0x35ffff6e, 0xb901028c, 0x394262ae, 0x7100001f, 0x7a4019c4, 0xb94096b9, 0x7a401b20, 0x1a9fd7ee,
0x710005df, 0x54000101, 0xb94092ad, 0x4b1901a8, 0x0b19010f, 0xb90096af, 0x1a9f37ed, 0x14000002, 0xd5033f5f,
0x885f7d2f, 0x710005ff, 0x54ffffa1, 0x880ffd3f, 0x35ffff8f, 0x34fffc0e, 0xd65f03c0]
def region(words, T, bes):
img = struct.pack('<' + 'I' * len(words), *words) + bytes(64)
return Search(img, 4 * len(words), set()).region(T, bes)
def patched(**at):
w = list(POLL)
for off, word in at.items():
w[int(off[1:], 16) // 4] = word
return w
class SpinWaits(unittest.TestCase):
def test_lock_poll_is_a_wait(self):
g = region(POLL, 0, [0x80])
self.assertIsNotNone(g)
self.assertEqual(g['valid'], {0x80})
self.assertNotIn(0x5c, g['R']) # the path that takes an item stores a new cursor: not part of the wait
self.assertTrue(set(g['kinds']) >= {'acq', 'rel', 'tst', 'stc'})
def test_found_by_the_scan(self):
self.assertIn(0, {g['T'] for g in Search(struct.pack('<' + 'I' * len(POLL), *POLL), 4 * len(POLL), set()).all()})
def test_patch_site_inside(self): # a site of the patch table in the region keeps it out
img = struct.pack('<' + 'I' * len(POLL), *POLL) + bytes(64)
self.assertIsNone(Search(img, 4 * len(POLL), {0x3c}).region(0, [0x80]))
def test_store_of_a_changing_value(self): # the wait path stores w14, which the pass writes
self.assertIsNone(region(patched(o2c=0xb901028e), 0, [0x80]))
def test_lock_not_released(self): # the wait path skips the release (b.ne U -> b.ne to the back-edge)
self.assertIsNone(region(patched(o4c=0x540001a1), 0, [0x80]))
def test_nothing_polled(self): # str xzr, [x8]; b back: stores of a constant and no load
self.assertIsNone(region([0xf900011f, 0x17ffffff], 0, [4]))
def test_plain_test_loop(self): # ldr w8, [x0]; cbz w8, back
g = region([0xb9400008, 0x34ffffe8], 0, [4])
self.assertIsNotNone(g)
self.assertEqual(g['valid'], {4})
def test_counted_loop(self): # ldr w8, [x0]; subs w1, w1, #1; b.ne back: a counter, it leaves by itself
self.assertIsNone(region([0xb9400008, 0x71000421, 0x54ffffc1], 0, [8]))
if __name__ == '__main__':
unittest.main()
+431
View File
@@ -0,0 +1,431 @@
# Adapted from nxnative dm/tools/patch_nso.py @ 6d34984 (MIT, Copyright (c) 2026 seedds): the spin wait search
# ("Spin waits": spin_rw, spin_kind, spin_rmw, spin_lock, spin_store, spin_quick, spin_region, spin_region1).
"""Find the spin waits of the ExeFS modules and print them as `spin` lines of a patch table (recomp/patches.py).
Usage: spin_waits.py --exefs build/extracted/v143/exefs --patches recomp/patches-v143.txt [--modules main,subsdk0,sdk]
A guest loop that polls memory until another thread changes it fills only its own core on the Switch, where a better
thread pinned there preempts it. Here it holds one of the three virtual cores (runtime/kernel.c) and a host core, and
when the poll takes and releases a lock on every pass, two pollers hand the lock's cache line between their cores so
that the thread whose item it is rarely wins its exclusive store (nxnative 6d34984: Breath of the Wild's job queue,
main+0xef62dc, CPU frames of 30-210 ms every 1-10 s). The generator sends the back-edges of such loops through
rt_spin_gate (runtime/kernel.c kern_spin_gate), which slows the poll down and hands the virtual core to a waiting
thread once the loop has polled for a while.
A loop counts only when it provably cannot leave by itself. From its head T every path back to T (the region R,
within SPIN_WIN bytes after T) runs loads, register and flag arithmetic, direct branches and barriers; no call, SVC,
system register or event wait; nothing live at T is written in R. Allowed besides: an exclusive add of a constant
that every path back to T undoes on the same address, a spin lock taken and released on the same address on every
path, a test loop on a word inside R, and at most SPIN_STORES stores of registers R never writes (fixed values to
fixed addresses, so the passes repeat after a few). Sites of the patch table are kept out of regions.
Runs on the development machine (capstone); the table it prints is checked in, so the installer's generator needs
no disassembler.
"""
import argparse
import re
import struct
import sys
from pathlib import Path
from capstone import CS_ARCH_ARM64, CS_MODE_ARM, Cs
from capstone.arm64 import ARM64_OP_IMM, ARM64_OP_MEM, ARM64_OP_REG
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / 'recomp'))
import patches # noqa: E402
from layout import layout # noqa: E402
from nso import Nso # noqa: E402
SPIN_WIN = 512 # bytes from a backward branch back to its target
SPIN_TOPS = {0x16, 0x17, 0x54, 0x34, 0x35, 0xB4, 0xB5, 0x36, 0x37, 0xB6, 0xB7} # b, b.cond, cbz/cbnz, tbz/tbnz
SPIN_PATHS, SPIN_STEPS, SPIN_STORES = 256, 4096, 4 # complete paths back to T; search steps; stores in a region
SPIN_LSE = ('ldadd', 'ldclr', 'ldeor', 'ldset', 'ldsmax', 'ldsmin', 'ldumax', 'ldumin')
SPIN_BAD = {'bl', 'blr', 'br', 'ret', 'eret', 'svc', 'hvc', 'smc', 'brk', 'hlt', 'udf', 'mrs', 'msr', 'sys', 'sysl',
'wfe', 'wfi', 'sev', 'sevl', 'clrex', 'dc', 'ic', 'at', 'tlbi', 'drps', 'dcps1', 'dcps2', 'dcps3', 'blraa',
'blrab', 'blraaz', 'blrabz', 'braa', 'brab', 'braaz', 'brabz', 'retaa', 'retab', 'eretaa', 'eretab'}
# Words that end every path through them by their encoding alone: bl; br / blr / ret; svc / brk; stores (immediate,
# unscaled, pre / post-index, register offset, vector); stp / stnp; LSE atomics. Exclusive stores and pre / post-index
# loads are left to the full check.
SPIN_STOP = ((0xFC000000, 0x94000000), (0xFE000000, 0xD6000000), (0xFF000000, 0xD4000000), (0x3FC00000, 0x39000000),
(0x3FC00000, 0x3D000000), (0x3FC00000, 0x3D800000), (0x3FE00000, 0x38000000), (0x3FE00C00, 0x38200800),
(0x3FE00000, 0x3C000000), (0x3FE00000, 0x3C800000), (0x3A400000, 0x28000000), (0x3F200C00, 0x38200000))
class SpinNo(Exception):
pass
def norm(n):
"""w / x views as x<n>, vector views as v<n>, zero registers as None."""
n = {'fp': 'x29', 'lr': 'x30', 'wsp': 'sp'}.get(n, n)
if n in ('wzr', 'xzr'):
return None
m = re.fullmatch(r'[wx](\d+)', n)
if m:
return 'x' + m.group(1)
m = re.fullmatch(r'[bhsdqv](\d+)', n)
return 'v' + m.group(1) if m else n
class Search:
"""The spin waits of one module image. touched: image offsets no region may contain (patch sites)."""
def __init__(self, img, text_end, touched):
self.img, self.text_end, self.touched = img, text_end, touched
self.md = Cs(CS_ARCH_ARM64, CS_MODE_ARM)
self.md.detail = True
self.dec = {}
def ins(self, a):
if a not in self.dec:
self.dec[a] = next(self.md.disasm(bytes(self.img[a:a + 4]), a), None) if 0 <= a < self.text_end else None
return self.dec[a]
def word(self, a):
return struct.unpack_from('<I', self.img, a)[0]
def candidates(self):
"""{loop head: [backward branches to it]}, branches at most SPIN_WIN bytes back."""
cand = {}
for o in range(0, self.text_end, 4):
w = self.word(o)
t = w >> 24
if t not in SPIN_TOPS:
continue
if t in (0x16, 0x17):
d = ((w & 0x3FFFFFF) - (1 << 26)) * 4
elif t & 0x7E == 0x36:
d = (((w >> 5) & 0x3FFF) - (1 << 14)) * 4 if w & 0x40000 else 4
elif t == 0x54:
d = (((w >> 5) & 0x7FFFF) - (1 << 19)) * 4 if w & 0x800000 and not w & 0x10 else 4
else:
d = (((w >> 5) & 0x7FFFF) - (1 << 19)) * 4 if w & 0x800000 else 4
if -SPIN_WIN <= d <= 0:
cand.setdefault(o + d, []).append(o)
return cand
@staticmethod
def rw(ins):
"""(registers read, registers written). Capstone lists a compare's first operand as written and the flags as
read by cbz / tbz, and leaves out the destination of adds, so every register operand counts as well: operand 0
written and the others read, or for a load all of them written."""
m = ins.mnemonic
regs = [norm(ins.reg_name(o.reg)) for o in ins.operands if o.type == ARM64_OP_REG]
ops = set(regs) - {None}
if m in ('cbz', 'cbnz', 'tbz', 'tbnz'):
return ops, set()
if m.startswith('b.'):
return {'nzcv'}, set()
if m == 'b':
return set(), set()
if m in ('cmp', 'cmn', 'tst', 'fcmp', 'fcmpe'):
return ops, {'nzcv'}
if m in ('ccmp', 'ccmn', 'fccmp', 'fccmpe'):
return ops | {'nzcv'}, {'nzcv'}
r, w = ins.regs_access()
r = {norm(ins.reg_name(x)) for x in r} - {None}
w = {norm(ins.reg_name(x)) for x in w} - {None}
if m.startswith(('ld', 'prfm', 'prfum')):
return r, w | ops
return r | (set(regs[1:]) - {None}), w | (set(regs[:1]) - {None})
@staticmethod
def kind(ins):
"""'br' direct branch, 'pc' adr / adrp, 'ok' a load or register / flag arithmetic, None anything else."""
if ins is None:
return None
m = ins.mnemonic
if m in ('b', 'cbz', 'cbnz', 'tbz', 'tbnz') or m.startswith('b.'):
return 'br'
if m in ('adr', 'adrp'):
return 'pc'
if m in SPIN_BAD or m.startswith(('st', 'cas', 'swp') + SPIN_LSE):
return None
mem = any(o.type == ARM64_OP_MEM for o in ins.operands)
if m.startswith(('ld', 'prfm', 'prfum')):
return 'ok' if mem else None # no memory operand: a pc-relative literal load
return None if mem else 'ok'
def rmw(self, a):
"""ld(a)xr wA,[xN]; add|sub wB,wA,#k; st(l)xr wS,wB,[xN]; cbnz wS,<the load> at a -> (xN, +-k, registers
written, the four instructions), or None."""
l = [self.ins(a + 4 * i) for i in range(4)]
if (None in l or l[0].mnemonic not in ('ldxr', 'ldaxr') or l[1].mnemonic not in ('add', 'sub')
or l[2].mnemonic not in ('stxr', 'stlxr') or l[3].mnemonic != 'cbnz'):
return None
r = lambda x, i: x.reg_name(x.operands[i].reg)
if len(l[1].operands) != 3 or l[1].operands[2].type != ARM64_OP_IMM or 'lsl' in l[1].op_str:
return None
base = l[0].operands[1].mem
if base.disp or base.index or l[2].operands[2].mem.base != base.base or l[2].operands[2].mem.disp:
return None
if r(l[1], 1) != r(l[0], 0) or r(l[2], 1) != r(l[1], 0) or r(l[3], 0) != r(l[2], 0) or l[3].operands[1].imm != a:
return None
k = l[1].operands[2].imm * (1 if l[1].mnemonic == 'add' else -1)
return norm(l[0].reg_name(base.base)), k, {norm(r(l[0], 0)), norm(r(l[1], 0)), norm(r(l[2], 0))} - {None}, l
def lock(self, a):
"""An exclusive spin lock sequence or a test loop entered at a -> (kind, xN, its instructions, how many come
before a, how many from a on, registers read, registers written):
'acq' ld(a)xr wA,[xN]; cbz wA,+16; clrex; b <the load>; st(l)xr wS,wK,[xN]; cbnz wS,<the load>
'rel' clrex; ld(a)xr wA,[xN]; cmp wA,#k; b.ne <the clrex>; st(l)xr wS,wzr,[xN]; cbnz wS,<the load>
(entered at the load), or stlr wzr,[xN]
'tst' ldr|ldrb|ldrh wA,[xN{,#imm}]; cmp wA,#k; b.eq|b.ne <the load>"""
l = [self.ins(a + 4 * i) for i in range(6)]
if l[0] is None:
return None
r = lambda x, i: x.reg_name(x.operands[i].reg)
plain = lambda x, i: x.operands[i].type == ARM64_OP_MEM and not x.operands[i].mem.index and not x.operands[i].mem.disp
m0 = l[0].mnemonic
if m0 in ('ldxr', 'ldaxr') and None not in l and r(l[0], 0).startswith('w') and plain(l[0], 1):
base = l[0].operands[1].mem.base
bn = norm(l[0].reg_name(base))
if (l[1].mnemonic == 'cbz' and r(l[1], 0) == r(l[0], 0) and l[1].operands[1].imm == a + 16
and l[2].mnemonic == 'clrex' and l[3].mnemonic == 'b' and l[3].operands[0].imm == a
and l[4].mnemonic in ('stxr', 'stlxr') and plain(l[4], 2) and l[4].operands[2].mem.base == base
and r(l[4], 1) not in ('wzr', 'xzr')
and l[5].mnemonic == 'cbnz' and r(l[5], 0) == r(l[4], 0) and l[5].operands[1].imm == a):
return 'acq', bn, l, 0, 6, {bn, norm(r(l[4], 1))}, {norm(r(l[0], 0)), norm(r(l[4], 0))}
p = self.ins(a - 4)
if (p is not None and p.mnemonic == 'clrex' and l[1].mnemonic == 'cmp' and r(l[1], 0) == r(l[0], 0)
and l[1].operands[1].type == ARM64_OP_IMM and l[2].mnemonic == 'b.ne'
and l[2].operands[0].imm == a - 4 and l[3].mnemonic in ('stxr', 'stlxr') and r(l[3], 1) == 'wzr'
and plain(l[3], 2) and l[3].operands[2].mem.base == base and l[4].mnemonic == 'cbnz'
and r(l[4], 0) == r(l[3], 0) and l[4].operands[1].imm == a):
return 'rel', bn, [p] + l[:5], 1, 5, {bn}, {norm(r(l[0], 0)), norm(r(l[3], 0)), 'nzcv'}
if m0 == 'stlr' and len(l[0].operands) == 2 and r(l[0], 0) in ('wzr', 'xzr') and plain(l[0], 1):
return 'rel', norm(l[0].reg_name(l[0].operands[1].mem.base)), l[:1], 0, 1, {norm(l[0].reg_name(l[0].operands[1].mem.base))}, set()
if (m0 in ('ldr', 'ldrb', 'ldrh') and None not in l[:3] and len(l[0].operands) == 2 and r(l[0], 0).startswith('w')
and l[0].operands[1].type == ARM64_OP_MEM and not l[0].operands[1].mem.index and not l[0].writeback
and l[1].mnemonic == 'cmp' and r(l[1], 0) == r(l[0], 0) and l[1].operands[1].type == ARM64_OP_IMM
and l[2].mnemonic in ('b.eq', 'b.ne') and l[2].operands[0].imm == a):
bn = norm(l[0].reg_name(l[0].operands[1].mem.base))
return 'tst', bn, l[:3], 0, 3, {bn}, {norm(r(l[0], 0)), 'nzcv'}
return None
@staticmethod
def store(ins):
"""str / strb / strh / stur / sturb / sturh of a w register or zr to [xN{,#imm}] (no writeback, no register
offset) -> (value register or None for zr, base register), or None."""
if (ins is None or ins.mnemonic not in ('str', 'strb', 'strh', 'stur', 'sturb', 'sturh') or ins.writeback
or len(ins.operands) != 2):
return None
v, o = ins.operands
if v.type != ARM64_OP_REG or o.type != ARM64_OP_MEM or o.mem.index:
return None
vn = ins.reg_name(v.reg)
if not (vn.startswith('w') or vn == 'xzr'):
return None
return norm(vn), norm(ins.reg_name(o.mem.base))
def quick(self, T, hi):
"""A back-edge to T can be reached from T without passing a word of SPIN_STOP (only such heads get the full
check, which decodes)."""
seen, todo = set(), [T]
while todo:
a = todo.pop()
if a in seen or not T <= a <= hi:
continue
seen.add(a)
w = self.word(a)
t = w >> 24
if 0x14 <= t <= 0x17:
succ = (a + (((w & 0x3FFFFFF) ^ 0x2000000) - 0x2000000) * 4,)
elif t == 0x54 or t & 0x7E == 0x34:
succ = (a + ((((w >> 5) & 0x7FFFF) ^ 0x40000) - 0x40000) * 4, a + 4)
elif t & 0x7E == 0x36:
succ = (a + ((((w >> 5) & 0x3FFF) ^ 0x2000) - 0x2000) * 4, a + 4)
elif any(w & m == v for m, v in SPIN_STOP) and not (
w & 0xBFC00000 in (0xB9000000, 0x39000000, 0x79000000)
or w & 0xBFE00C00 in (0xB8000000, 0x38000000, 0x78000000)):
continue # str / strb / strh (immediate, unscaled) may store the same on every pass
else:
succ = (a + 4,)
if T in succ:
return True
todo.extend(succ)
return False
def region(self, T, bes):
"""The spin wait with head T (bes: the backward branches to T) -> dict, or None. A store whose value or
address a pass changes is no part of a region: the paths through it are dropped and the region is found again
without them. The region without stores is taken instead when the wider one does not cover its back-edges."""
ban, g = set(), None
for _ in range(8):
g = self.region1(T, bes, ban, True)
if not isinstance(g, set):
break
ban |= g
old = self.region1(T, bes, set(), False)
return g if isinstance(g, dict) and (not old or old['valid'] <= g['valid']) else old
def region1(self, T, bes, ban, stores):
hi = max(bes)
if not self.quick(T, hi):
return None
nodes, back, bad, inner = {}, set(), set(), set()
todo = [T]
while todo:
a = todo.pop()
if a in nodes or a in bad:
continue
if a in ban:
bad.add(a)
continue
rmw = self.rmw(a) if a + 12 <= hi and self.word(a) & 0x3FE00000 == 0x08400000 else None # ldxr / ldaxr
lk = None if rmw else self.lock(a)
if lk and lk[0] == 'tst' and a == T:
lk = None # the region's own test loop
if rmw:
n = {'kind': 'rmw', 'base': rmw[0], 'k': rmw[1], 'ins': rmw[3], 'uses': {rmw[0]}, 'defs': rmw[2],
'succ': [a + 16]}
elif lk:
n = {'kind': lk[0], 'base': lk[1], 'k': {'acq': 1, 'rel': -1, 'tst': 0}[lk[0]], 'ins': lk[2],
'pre': lk[3], 'uses': lk[5], 'defs': lk[6], 'succ': [a + 4 * lk[4]]}
elif stores and self.store(self.ins(a)):
x = self.ins(a)
st = self.store(x)
n = {'kind': 'stc', 'st': st, 'ins': [x], 'uses': {st[1]} | ({st[0]} - {None}), 'defs': set(),
'succ': [a + 4]}
else:
x = self.ins(a)
k = self.kind(x)
if k is None:
bad.add(a)
continue
if k == 'br':
t = x.operands[-1].imm
succ = [t] if x.mnemonic == 'b' else [t, a + 4]
else:
succ = [a + 4]
n = {'kind': k, 'ins': [x], 'succ': succ}
pre = n.get('pre', 0)
if any(a + 4 * (i - pre) in self.touched for i in range(len(n['ins']))):
bad.add(a)
continue
nodes[a] = n
if n['kind'] == 'rmw':
inner |= {a + 4, a + 8, a + 12}
if n['kind'] in ('acq', 'rel', 'tst'):
inner |= {a + 4 * (i - pre) for i in range(len(n['ins']))} - {a}
for s in n['succ']:
if s == T:
back.add(a)
elif T < s <= hi:
todo.append(s)
if not back or inner & set(nodes) or any(s in inner for n in nodes.values() for s in n['succ']):
return None
def prune(ends):
keep, more = set(ends), True
while more:
more = False
for a, n in nodes.items():
if a not in keep and any(s in keep and s != T for s in n['succ']):
keep.add(a)
more = True
return keep
R = prune(back)
for a in R:
if 'uses' not in nodes[a]:
nodes[a]['uses'], nodes[a]['defs'] = self.rw(nodes[a]['ins'][0])
# Every path from T to a back-edge: no inner cycle, and the exclusive adds on each address (a register between
# two writes to it) sum to 0; a lock is taken at most once and released after it.
bad_back, cnt = set(), [0, 0]
def walk(a, onpath, ver, delta):
cnt[1] += 1
if cnt[1] > SPIN_STEPS:
raise SpinNo
n = nodes[a]
if n['kind'] in ('rmw', 'acq', 'rel'):
key = (n['kind'] != 'rmw', n['base'], ver.get(n['base'], 0))
delta = dict(delta)
delta[key] = delta.get(key, 0) + n['k']
if n['kind'] != 'rmw' and not 0 <= delta[key] <= 1:
raise SpinNo
if n['defs']:
ver = dict(ver)
ver.update({r: ver.get(r, 0) + 1 for r in n['defs']})
for s in n['succ']:
if s == T:
cnt[0] += 1
if cnt[0] > SPIN_PATHS:
raise SpinNo
if any(delta.values()):
bad_back.add(a)
elif s in R:
if s in onpath:
raise SpinNo
walk(s, onpath | {s}, ver, delta)
try:
walk(T, {T}, {}, {})
except (SpinNo, RecursionError):
return None
valid = back - bad_back
if not valid:
return None
R = prune(valid)
# No state carried from one pass to the next: nothing live at T is written in R.
live, more = {a: set() for a in R}, True
while more:
more = False
for a in sorted(R, reverse=True):
n, out = nodes[a], set()
for s in n['succ']:
if s == T:
out |= live[T] if a in valid else set()
elif s in R:
out |= live[s]
new = n['uses'] | (out - n['defs'])
if new != live[a]:
live[a] = new
more = True
defs = set().union(*(nodes[a]['defs'] for a in R))
if any(nodes[a]['kind'] == 'stc' for a in R) and not any(
nodes[a]['kind'] in ('rmw', 'acq', 'rel', 'tst') or nodes[a]['ins'][0].mnemonic.startswith('ld')
for a in R):
return None # stores and nothing polled
vary = {a for a in R if nodes[a]['kind'] == 'stc' and nodes[a]['uses'] & defs}
if vary:
return vary
if sum(nodes[a]['kind'] == 'stc' for a in R) > SPIN_STORES:
return None
if live[T] & defs:
return None
kinds = sorted({nodes[a]['kind'] for a in R} & {'rmw', 'acq', 'rel', 'tst', 'stc'})
return {'T': T, 'R': sorted(R), 'valid': valid, 'size': sum(len(nodes[a]['ins']) for a in R), 'kinds': kinds}
def all(self):
return [g for g in (self.region(T, bes) for T, bes in sorted(self.candidates().items())) if g]
def main():
ap = argparse.ArgumentParser(description=__doc__.splitlines()[0])
ap.add_argument('--exefs', type=Path, required=True)
ap.add_argument('--patches', type=Path, help='patch table whose sites stay out of regions')
ap.add_argument('--modules', default='main,subsdk0,sdk')
args = ap.parse_args()
sys.setrecursionlimit(20000)
mods = layout(args.exefs)
table = patches.load(args.patches, mods) if args.patches else patches.Table()
for name in args.modules.split(','):
n = Nso(str(args.exefs / name))
img = bytes(n.image)
touched = set(table.sites.get(name, {}))
found = Search(img, n.text[0] + n.text[1], touched).all()
print(f'# {name}: {len(found)} spin waits')
for g in found:
bes = ' '.join(f'{b:x}' for b in sorted(g['valid']))
what = ', '.join(g['kinds']) or 'loads'
print(f'spin {name} {g["T"]:x} {bes} # {g["size"]} instructions; {what}')
print(f'{name}: {len(found)} spin waits', file=sys.stderr)
return 0
if __name__ == '__main__':
sys.exit(main())