x64_win_tail_sret.sh (1989B)
1 #!/usr/bin/env bash 2 # Structural x86_64-windows tail+sret check. 3 # 4 # A realized tail call returning an indirect aggregate has no explicit result 5 # local at O1, but Win64 still requires the hidden sret destination in rcx. 6 # The tail site must forward the caller's saved sret pointer before jumping. 7 set -euo pipefail 8 9 ROOT="$(cd "$(dirname "$0")/../.." && pwd)" 10 KIT="${KIT:-$ROOT/build/kit}" 11 WORK="$ROOT/build/test/opt/x64_win_tail_sret" 12 mkdir -p "$WORK" 13 14 fail() { 15 printf 'x64-win-tail-sret check FAILED: %s\n' "$1" >&2 16 if [ -n "${2:-}" ] && [ -f "$2" ]; then 17 sed 's/^/ | /' "$2" >&2 18 fi 19 exit 1 20 } 21 22 slice_asm_func() { 23 local src="$1" func="$2" out="$3" 24 awk -v name="$func" ' 25 $0 == name ":" { in_fn = 1; print; next } 26 /^[A-Za-z_.$][A-Za-z0-9_.$]*:/ { if (in_fn) in_fn = 0 } 27 in_fn { print } 28 ' "$src" > "$out" 29 } 30 31 check_case() { 32 local name="$1" src="$2" 33 local asm="$WORK/$name.s" 34 local body="$WORK/$name.forward.s" 35 36 "$KIT" cc -S -O1 -target x86_64-windows "$src" -o "$asm" \ 37 > "$WORK/$name.cc.out" 2> "$WORK/$name.cc.err" 38 slice_asm_func "$asm" forward "$body" 39 40 if grep -Eq '\bcallq?[[:space:]]+make\b' "$body"; then 41 fail "$name used a normal call to make" "$body" 42 fi 43 if ! grep -Eq '^[[:space:]]*jmp[[:space:]]+make\b' "$body"; then 44 fail "$name did not emit a sibling jump to make" "$body" 45 fi 46 if ! awk ' 47 /^[[:space:]]*movq[[:space:]]+-[0-9]+[(]%rbp[)],[[:space:]]*%rcx[[:space:]]*$/ { 48 reloaded = 1 49 next 50 } 51 reloaded && /^[[:space:]]*jmp[[:space:]]+make[[:space:]]*$/ { 52 found = 1 53 exit 0 54 } 55 /^[[:space:]]*jmp[[:space:]]+make[[:space:]]*$/ { 56 found = 1 57 exit 1 58 } 59 END { if (!found) exit 1 } 60 ' "$body"; then 61 fail "$name did not reload saved sret pointer into rcx before tail jump" \ 62 "$body" 63 fi 64 } 65 66 check_case 36_musttail_sret "$ROOT/test/toy/cases/36_musttail_sret.toy" 67 check_case 37_tail_sret "$ROOT/test/toy/cases/37_tail_sret.toy" 68 69 printf 'x64-win-tail-sret: ok\n'