NAME=arm64 unknown indirect exit is not proof of noreturn
FILE=bins/mach0/WheresMyBrowser
ARGS=-a arm -b 64
CMDS=<<EOF
aaaa
afij @ 0x100023174~{0.noreturn}
abj @ 0x1000231a4~{0.size}
afij @ 0x100022ae0~{0.realsz}
afij @ 0x100022ae0~{0.ninstrs}
pi 1 @ 0x1000231b4
EOF
EXPECT=<<EOF
false
20
496
124
br x2
EOF
RUN

NAME=arm64 computed BR keeps reachable epilogue and returning callers
FILE=bins/mach0/BatteryLife.arm_64.1
ARGS=-a arm -b 64
CMDS=<<EOF
aaaa
afij @ 0x100013adc~{0.noreturn}
abj @ 0x100013f88~{0.jump}
afij @ 0x100013fe0~{0.realsz}
afij @ 0x100013fe0~{0.ninstrs}
afij @ 0x1000149d4~{0.realsz}
afij @ 0x1000149d4~{0.ninstrs}
EOF
EXPECT=<<EOF
false
4295049116
120
30
344
86
EOF
RUN

NAME=arm64 computed BR recovery does not depend on anal.jmptbl
FILE=bins/mach0/BatteryLife.arm_64.1
ARGS=-a arm -b 64
CMDS=<<EOF
e anal.jmptbl=false
af @ 0x100013adc
afij @ 0x100013adc~{0.realsz}
abj @ 0x100013f88~{0.size}
abj @ 0x100013f88~{0.jump}
pi 1 @ 0x100013f98
EOF
EXPECT=<<EOF
1236
36
4295049116
br x4
EOF
RUN

NAME=arm64 unresolved BR still terminates with anal.jmptbl disabled
FILE=bins/mach0/ls-m1
ARGS=-a arm -b 64
CMDS=<<EOF
e anal.jmptbl=false
af
abj @ 0x100003c44~{0.size}
abj @ 0x100003c44~{0.ninstr}
ab @ 0x100003c44~jump
pi 1 @ 0x100003c60
EOF
EXPECT=<<EOF
32
8
br x16
EOF
RUN

NAME=arm64 switch keeps case0 after BR and its inclusive last case
FILE=bins/mach0/ls-m1
ARGS=-a arm -b 64
CMDS=<<EOF
af
ab @ 0x100003c44~cases
?v case.0x100003c60.0
?v case.0x100003c60.91
abj @ 0x100003c64~{0.size}
EOF
EXPECT=<<EOF
cases: 92
0x100003c64
0x100003cf4
16
EOF
RUN

NAME=arm64 later LDP does not change the table element width
FILE=bins/mach0/Alamofire-stripped
ARGS=-a arm -b 64
CMDS=<<EOF
af @ 0xf93c
afij @ 0xf93c~{0.realsz}
CC. @ 0xfa80
?v case.0xfa80.0
abj @ 0xfa84~{0.size}
pi 2 @ 0xfa7c
EOF
EXPECT=<<EOF
1068
switch table (8 cases) at 0xfd68
0xfa84
16
ldp x24, x23, [var_80h]
br x8
EOF
RUN

NAME=arm64 unsigned byte table entries are scaled without sign extension
FILE=bins/elf/ls-toybox
ARGS=-a arm -b 64
CMDS=<<EOF
af @ 0x3e168
CC. @ 0x3e278
p8 5 @ 0x23c50
?v case.0x3e278.0
?v case.0x3e278.2
pi 3 @ 0x3e270
EOF
EXPECT=<<EOF
switch table (5 cases) at 0x23c50
009195998a
0x3e27c
0x3e4d0
ldrb w11, [x9, x8]
add x10, x10, x11, lsl 2
br x10
EOF
RUN

# Mutations below use the write cache, never modifying the testbins fixture.
NAME=arm64 partial table retains the expected bound
FILE=bins/mach0/ls-m1
ARGS=-a arm -b 64
CMDS=<<EOF
e io.cache=true
wx 01000000 @ 0x1000047a4
af
abj @ 0x100003c44~{0.switch_op.amount}
ab @ 0x100003c44~cases
?v case.0x100003c60.0
EOF
EXPECT=<<EOF
92
cases: 91
0x100003c64
EOF
RUN

NAME=arm64 MOV aliases and reused table registers retain switch cases
FILE=bins/mach0/ired-arm64
ARGS=-a arm -b 64
CMDS=<<EOF
af @ 0x100005864
af @ 0x100006400
afij @ 0x100005864~{0.realsz}
CC. @ 0x100005934
?v case.0x100005934.0
afij @ 0x100006400~{0.realsz}
CC. @ 0x10000687c
?v case.0x10000687c.0
EOF
EXPECT=<<EOF
1328
switch table (20 cases) at 0x100005d94
0x100005938
3532
switch table (81 cases) at 0x10000732c
0x100006880
EOF
RUN

NAME=arm64 spilled table address and SXTH dispatch keep the full switch
FILE=bins/elf/switch-hello-world.elf
ARGS=-a arm -b 64
CMDS=<<EOF
af @ 0x16e9c
CC. @ 0x17174
?v case.0x17174.7
abj @ 0x17178~{0.size}
EOF
EXPECT=<<EOF
switch table (91 cases) at 0x2a55c
0x17178
60
EOF
RUN

NAME=arm64 selected index is not bounded by an unrelated CMP
FILE=bins/mach0/SwiftAsynciOS
ARGS=-a arm -b 64
CMDS=<<EOF
af @ 0x1000069e4
afij @ 0x1000069e4~{0.realsz}
ab @ 0x100006a0c~cases
ab @ 0x100006a2c~cases
?v case.0x100006a20.1
?v case.0x100006a40.1
EOF
EXPECT=<<EOF
140
cases: 5
cases: 5
0x100006a24
0x100006a44
EOF
RUN

NAME=arm64 shared switch destination keeps every case label
FILE=bins/mach0/ls-m1
ARGS=-a arm -b 64
CMDS=<<EOF
e io.cache=true
wx 0c0000000c000000 @ 0x100004638
af
abj @ 0x100003c44~{0.switch_op.amount}
ab @ 0x100003c44~cases
?v case.0x100003c60.0
?v case.0x100003c60.1
EOF
EXPECT=<<EOF
92
cases: 92
0x100003c64
0x100003c64
EOF
RUN
