kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

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'