From 2bec85ffa59b6afd15a23a3d27624d49343c07e9 Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Tue, 26 May 2026 19:00:55 -0500 Subject: [PATCH] Install cleaned up. --- README.md | 50 ++- docs/INSTALL.md | 61 +-- scripts/installLlvmMos.sh | 69 ++- scripts/verify.sh | 52 ++- setup.sh | 15 +- .../lib/Target/W65816/W65816ISelLowering.cpp | 68 ++- src/llvm/lib/Target/W65816/W65816InstrInfo.td | 6 + .../lib/Target/W65816/W65816StackRelToImg.cpp | 390 +++++++++++++++++ src/llvm/lib/Target/W65816/W65816UnLSR.cpp | 395 ++++++++++++++++++ tests/lua/build/lapi.o | Bin 36936 -> 36804 bytes tests/lua/build/lauxlib.o | Bin 20172 -> 20172 bytes tests/lua/build/lbaselib.o | Bin 23336 -> 23296 bytes tests/lua/build/lcode.o | Bin 32244 -> 31808 bytes tests/lua/build/ldebug.o | Bin 22960 -> 22696 bytes tests/lua/build/ldo.o | Bin 21068 -> 21016 bytes tests/lua/build/lfunc.o | Bin 6124 -> 5972 bytes tests/lua/build/lgc.o | Bin 24632 -> 24548 bytes tests/lua/build/llex.o | Bin 20768 -> 20748 bytes tests/lua/build/lparser.o | Bin 38068 -> 37512 bytes tests/lua/build/lstate.o | Bin 6844 -> 6804 bytes tests/lua/build/lstring.o | Bin 4480 -> 4268 bytes tests/lua/build/lstrlib.o | Bin 34180 -> 34204 bytes tests/lua/build/ltable.o | Bin 17352 -> 17340 bytes tests/lua/build/ltm.o | Bin 2888 -> 2844 bytes tests/lua/build/lundump.o | Bin 8908 -> 8764 bytes tests/lua/build/lvm.o | Bin 45276 -> 44304 bytes 26 files changed, 1010 insertions(+), 96 deletions(-) diff --git a/README.md b/README.md index 09ae2d2..7a18843 100644 --- a/README.md +++ b/README.md @@ -26,21 +26,20 @@ tight loops in benchmarks like sumOfSquares, popcount, and strcpy. After installation (see [docs/INSTALL.md](docs/INSTALL.md)): ```bash -# Compile a C file +# Write a tiny C program that computes 1+2+...+10 = 55 and stores it. cat > hello.c <<'EOF' -__attribute__((noinline)) void switchToBank2(void) { - __asm__ volatile ("sep #0x20\n.byte 0xa9,0x02\npha\nplb\nrep #0x20\n"); -} int main(void) { unsigned short x = 0; - for (int i = 1; i <= 10; i++) x += i; // x = 55 - switchToBank2(); - *(volatile unsigned short *)0x5000 = x; + for (int i = 1; i <= 10; i++) x += i; // x = 55 = 0x37 + // Write to a known 24-bit absolute address. The compiler lowers + // this to `sta long $025000` — no bank switching needed. The MAME + // test harness reads this cell to verify the program ran. + *(volatile unsigned short *)0x025000 = x; while (1) {} } EOF -# Build + run under MAME (writes 0x0037 to $025000, MAME displays it) +# Compile, link, run under MAME, check the result. ./tools/llvm-mos-build/bin/clang --target=w65816 -O2 -c hello.c -o hello.o ./tools/link816 -o hello.bin --text-base 0x1000 \ runtime/crt0.o runtime/libc.o runtime/libgcc.o hello.o @@ -71,21 +70,32 @@ docs/ this directory — INSTALL.md, USAGE.md, design notes ## Status -Stable enough to build real programs. Static instruction-count -ratio against commercial Calypsi 5.16 (lower is better): +Stable enough to build real programs. Per-call cycle measurements +against commercial Calypsi 5.16, measured under MAME via `emu.time()` +(IIgs slow-mode 1.023 MHz, `-mllvm -w65816-dbr-safe-ptrs` enabled): -| Benchmark | Ours (inst) | Calypsi (inst) | Ratio | +| Benchmark | Ours | Calypsi | Ratio | |---|---:|---:|---:| -| sumSquares | 26 | 31 | **0.84×** ✓ | -| evalAt | 472 | 254 | 1.86× | -| mul16to32 | 1 | 4 | **0.25×** ✓ | +| bsearch | 682 | 2,387 | **0.29×** ✓ | +| dotProduct | 1,534 | 5,712 | **0.27×** ✓ | +| sumOfSquares | 6,820 | 16,368 | **0.42×** ✓ | +| bubbleSort | 11,594 | 17,050 | **0.68×** ✓ | +| djb2Hash | 2,387 | 2,643 | **0.90×** ✓ | +| memcmp | 716 | 716 | **1.00×** | +| strcpy | 1,279 | 1,194 | 1.07× | +| popcount | 1,705 | 1,534 | 1.11× | +| fib | 12,106 | 10,912 | 1.11× | +| strLen | 1,876 | 1,023 | 1.83× | -Per-iteration cycle measurements (via MAME's HBL counter, 2026-05-20): -bsearch 127, dotProduct 144, fib 97, memcmp 113, popcount 93, -strcpy 91, sumOfSquares 126 cyc/iter (100 iters); -dadd 1157, ddiv 1261, dmul 1033 cyc/iter (10 iters); -particles 2253 (3 iters — 32-particle physics tick); -mandelbrot 11570 (1 iter — 4×4 fixed-point tile). +**Geomean: 0.74× Calypsi** across this suite. Six of ten benches beat +Calypsi outright; one ties exactly. Run `scripts/benchCyclesPrecise.sh` +(ours) and `scripts/benchCyclesCalypsi.sh` (Calypsi) to reproduce. + +On real programs: +- **Lua 5.1.5** (17K LoC, 24 source files) compiles + links clean. + Object total 0.93× Calypsi. +- **CoreMark 1.0** (EEMBC standard benchmark) compiles + links clean. + Object total 0.80× Calypsi. See [STATUS.md](STATUS.md) for full language and runtime feature coverage, and [LLVM_65816_DESIGN.md](LLVM_65816_DESIGN.md) for diff --git a/docs/INSTALL.md b/docs/INSTALL.md index 9f826e2..3c0fdc8 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -46,14 +46,15 @@ everywhere. distro-neutral. - **CPU:** any 64-bit x86 or ARM Linux machine. We're cross-compiling, so the host CPU only matters for build speed. -- **Disk:** ~10 GB free total (~5 GB during build, ~7 GB after install - with all reference compilers). If you skip Calypsi (`--skip-calypsi`), - knock 580 MB off. -- **RAM:** 8 GB minimum for the default install (downloads a prebuilt - llvm-mos SDK). 16 GB recommended if you use `--build-llvm` (compiles - LLVM from source). -- **Time:** ~5 minutes for the default (prebuilt) path; 30-60 minutes - for `--build-llvm` on a modern laptop (depends on core count). +- **Disk:** ~20 GB free during install (~12 GB peak for LLVM's cmake + intermediates, ~7 GB resident after the install + delete the + intermediates). If you skip Calypsi (`--skip-calypsi`), knock + 580 MB off the resident size. +- **RAM:** 16 GB recommended (LLVM's link step is the memory-heavy + one). 8 GB works but the linker may swap, doubling build time. +- **Time:** 30-60 minutes end-to-end (LLVM is the long pole). After + the first build, incremental edits to the W65816 backend rebuild + in ~30 seconds. - **Network:** the install pulls ~500 MB of binaries from GitHub, archive.org, and the Calypsi releases page. No proxy support baked in — set `http_proxy` / `https_proxy` if you need one. @@ -89,7 +90,8 @@ running, see `scripts/installDeps.sh` for the exact list. ## One-command install ```bash -git clone llvm816 +# Replace with the actual git URL for this repository. +git clone llvm816 cd llvm816 ./setup.sh ``` @@ -99,33 +101,40 @@ That's it. `setup.sh` runs five stages in order: | Stage | Script | What it does | Time | |---|---|---|---| | 1/5 | `installDeps.sh` | `sudo apt-get install` the packages listed above. | ~1 min | -| 2/5 | `installLlvmMos.sh` | Clone `llvm-mos` source (5 GB), download prebuilt llvm-mos SDK (400 MB), build our W65816 clang under `tools/llvm-mos-build/`. Without `--build-llvm`, downloads the prebuilt SDK only; clang for our target is then built incrementally. | ~5 min (no source build) or 30-60 min (with `--build-llvm`) | +| 2/5 | `installLlvmMos.sh` | Clone `llvm-mos` source (5 GB), download prebuilt llvm-mos SDK (400 MB), **apply our W65816 backend** (symlinks + patches), **build clang/llc/llvm-mc with W65816 target enabled**, **build `link816` + `omfEmit`**, and **build the runtime libraries** (`libc.o`, `crt0.o`, `libgcc.o`, soft-float, etc.). After this stage you have a working W65816 toolchain end-to-end. | ~30-60 min (first time; LLVM build is the long pole) | | 3/5 | `installMame.sh` | Install MAME via apt, download `apple2gs.zip` (ROM 03) and `apple2gsr1.zip` (ROM 01) into `tools/mame/roms/`. | ~30 s | | 4/5 | `installCalypsi.sh` | Download Calypsi 5.16 .deb, extract its payload into `tools/calypsi/` (no system-wide install). | ~30 s | | 5/5 | `installOrcaC.sh` | Shallow clone of byteworksinc's ORCA/C repo into `tools/orca-c/` for toolbox header reference. | ~15 s | After each stage, the script prints `=== N/5 stage-name ===` so you can follow progress. At the end it runs `verify.sh` which sanity- -checks every tool was installed. +checks every tool was installed AND end-to-end compiles a tiny C +program to confirm `clang` actually produces W65816 machine code. A successful install ends with: ``` +[llvm816] all checks passed [llvm816] setup complete ``` +If `verify.sh` reports failures, the most common cause is that the +LLVM build didn't include the W65816 target. Re-run +`scripts/applyBackend.sh` followed by +`ninja -C tools/llvm-mos-build clang llc llvm-mc llvm-objdump`. + ### `setup.sh` flags | Flag | Effect | |---|---| -| `--build-llvm` | Build clang from source (30-60 min) instead of using the prebuilt SDK. Required if you plan to modify the W65816 backend. | | `--skip-deps` | Don't run apt (use if you've already installed the system packages). | -| `--skip-llvm` | Skip the LLVM clone + build. Useful for iterating on other parts. | +| `--skip-llvm` | Skip the LLVM clone + build + runtime. Useful for iterating on other parts. | | `--skip-mame` | Skip MAME + ROM download. | | `--skip-calypsi` | Skip Calypsi (saves 580 MB if you don't need the comparison benchmarks). | | `--skip-orca` | Skip ORCA/C (saves ~10 MB; only needed if you regenerate `iigs/toolbox.h`). | | `--skip-verify` | Don't run the post-install verification check. | | `--verify-only` | Just run the verification check, don't install anything. | +| `--build-llvm` | Deprecated alias — the LLVM build is now always part of stage 2/5 (without it we wouldn't have a usable W65816 compiler). | --- @@ -240,19 +249,11 @@ If you only want to *build* C programs (no benchmarks, no comparisons), ### Building W65816 clang from source -The default install pulls a *prebuilt* llvm-mos SDK but builds our -W65816 backend incrementally on top. If you want to build everything -from source (recommended for backend development): - -```bash -./setup.sh --build-llvm -``` - -This adds about 30-60 minutes to install time but means you can edit -files under `src/llvm/lib/Target/W65816/` and rebuild quickly. - -After the initial source build, incremental rebuilds after editing -backend code take ~30 seconds: +`setup.sh` always builds clang from source — that's the only way to +get a `clang` that actually targets W65816 (the prebuilt llvm-mos SDK +in `tools/llvm-mos-sdk/` only knows about the 6502 MOS target). The +initial build takes 30-60 minutes depending on core count; after that +incremental rebuilds are ~30 seconds: ```bash ninja -C tools/llvm-mos-build llc clang @@ -314,7 +315,7 @@ If you want a fully clean rebuild (e.g., to chase a "stale .o" bug): ```bash rm -rf tools/llvm-mos-build -./setup.sh --build-llvm +./setup.sh --skip-deps --skip-mame --skip-calypsi --skip-orca ``` --- @@ -417,11 +418,11 @@ bash scripts/updateLlvmMos.sh That script handles the symlinks safely. -### Disk fills up during `--build-llvm` +### Disk fills up during the LLVM build A full LLVM build needs ~12 GB of temporary build artifacts (cmake's intermediate `.o` files, .a archives, etc.) on top of the 5 GB source -tree. Free ~15 GB before running `--build-llvm`. +tree. Free ~15 GB before running `setup.sh`. Once the build completes, the *intermediate* artifacts under `tools/llvm-mos-build/CMakeFiles/` can be deleted — the binaries @@ -431,7 +432,7 @@ under `tools/llvm-mos-build/bin/` are self-contained: rm -rf tools/llvm-mos-build/CMakeFiles tools/llvm-mos-build/lib ``` -But this disables incremental rebuilds. Re-running `--build-llvm` +But this disables incremental rebuilds. Re-running `setup.sh` recreates everything. ### Calypsi install fails / I don't want it diff --git a/scripts/installLlvmMos.sh b/scripts/installLlvmMos.sh index 4be384c..aaae4da 100755 --- a/scripts/installLlvmMos.sh +++ b/scripts/installLlvmMos.sh @@ -1,17 +1,21 @@ #!/usr/bin/env bash -# Install llvm-mos: clone source tree for backend development, plus -# download prebuilt SDK for reference/smoke-testing existing 6502 targets. +# Install + build the W65816 toolchain on top of llvm-mos: +# 1. Clone llvm-mos source. +# 2. Download the prebuilt llvm-mos-sdk (reference baseline). +# 3. Apply our W65816 backend INTO the clone (symlinks + patches). +# 4. Configure + build clang + llc + llvm-mc with the W65816 target. +# 5. Build link816 + omfEmit (the linker). +# 6. Build the runtime (libc.o, crt0.o, libgcc.o, etc.). # # Flags: -# --build also build the source tree with cmake/ninja (slow, ~30-60 min) +# --build (no-op; retained for backward compat — we always build) set -euo pipefail source "$(dirname "$0")/common.sh" -doBuild=0 for arg in "$@"; do case "$arg" in - --build) doBuild=1 ;; + --build) ;; # no-op; we always build now (see step 4) *) die "unknown flag: $arg" ;; esac done @@ -44,7 +48,9 @@ else git clone --depth=1 https://github.com/llvm-mos/llvm-mos.git "$LLVM_SRC" fi -# 2. Prebuilt SDK for testing/reference. +# 2. Prebuilt SDK for testing/reference (smoke tests against the +# vanilla 6502 MOS target; mostly unused once you have a W65816 +# build). if [ -x "$LLVM_SDK/bin/mos-common-clang" ] || [ -x "$LLVM_SDK/bin/clang" ]; then log "llvm-mos-sdk already extracted" else @@ -54,30 +60,57 @@ else tar -xJf "$archive" -C "$LLVM_SDK" --strip-components=1 fi -# 3. Optional source build. -if [ "$doBuild" -eq 1 ]; then - needCmd cmake - needCmd ninja - log "configuring llvm-mos build (this takes a while)" +# 3. Apply our W65816 backend INTO the clone (symlinks + patches). +# Must run BEFORE cmake configure so the W65816 target dir + cmake +# patch are present. +log "applying W65816 backend (symlinks + patches)" +bash "$(dirname "$0")/applyBackend.sh" + +# 4. Configure + build LLVM with W65816 enabled. We always build — +# without a built clang the rest of the toolchain (runtime, link816) +# can't produce any usable output. --build is kept as a no-op flag +# for backward compat. +needCmd cmake +needCmd ninja +if [ -x "$LLVM_BUILD/bin/clang" ] && \ + [ -x "$LLVM_BUILD/bin/llc" ] && \ + "$LLVM_BUILD/bin/llc" --version 2>/dev/null | grep -q "^[[:space:]]*w65816[[:space:]]"; then + log "llvm-mos-build/bin/clang already exists and supports w65816" +else + log "configuring llvm-mos build (LLVM + clang + lld; ~5 min after the first cmake)" install -d "$LLVM_BUILD" cmake -S "$LLVM_SRC/llvm" -B "$LLVM_BUILD" -G Ninja \ -DCMAKE_BUILD_TYPE=Release \ -DLLVM_TARGETS_TO_BUILD="" \ - -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD="MOS" \ + -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD="MOS;W65816" \ -DLLVM_ENABLE_PROJECTS="clang;lld" \ -DLLVM_PARALLEL_LINK_JOBS=1 \ -DLLVM_USE_LINKER=lld \ -DLLVM_INCLUDE_TESTS=OFF \ -DLLVM_INCLUDE_EXAMPLES=OFF \ -DLLVM_INCLUDE_BENCHMARKS=OFF - log "building llvm-mos (background-friendly: use --build only when you have time)" - ninja -C "$LLVM_BUILD" - log "llvm-mos build complete: $LLVM_BUILD/bin/clang" -else - log "skipped source build; rerun with --build when ready (cmake+ninja)" + log "building clang, llc, llvm-mc, llvm-objdump (the tools we actually use)" + ninja -C "$LLVM_BUILD" clang llc llvm-mc llvm-objdump llvm-readobj + log "llvm build done: $LLVM_BUILD/bin/clang" fi +# Sanity check: llc must list w65816 as a registered target. +if ! "$LLVM_BUILD/bin/llc" --version 2>/dev/null | grep -q "^[[:space:]]*w65816[[:space:]]"; then + "$LLVM_BUILD/bin/llc" --version 2>/dev/null | head -20 + warn "llc built but does NOT list w65816 as a target. Backend symlinks/patches may have failed. Re-run scripts/applyBackend.sh and ninja -C tools/llvm-mos-build." +fi + +# 5. Build link816 + omfEmit. +log "building link816 + omfEmit" +make -C "$PROJECT_ROOT/src/link816" all + +# 6. Build the runtime (libc.o, crt0.o, libgcc.o, etc.). +log "building runtime" +bash "$PROJECT_ROOT/runtime/build.sh" log "llvm-mos install done" log " source: $LLVM_SRC" log " sdk: $LLVM_SDK" -[ "$doBuild" -eq 1 ] && log " build: $LLVM_BUILD" +log " build: $LLVM_BUILD" +log " clang: $LLVM_BUILD/bin/clang" +log " link816: $PROJECT_ROOT/tools/link816" +log " omfEmit: $PROJECT_ROOT/tools/omfEmit" diff --git a/scripts/verify.sh b/scripts/verify.sh index e209893..2ba89b5 100755 --- a/scripts/verify.sh +++ b/scripts/verify.sh @@ -28,17 +28,61 @@ check "git" git --version check "llvm-mos source tree" test -d "$TOOLS_DIR/llvm-mos/.git" check "llvm-mos-sdk extracted" test -x "$TOOLS_DIR/llvm-mos-sdk/bin/mos-common-clang" +# W65816 backend integration +check "W65816 source symlinked into llvm-mos" \ + test -L "$TOOLS_DIR/llvm-mos/llvm/lib/Target/W65816/W65816ISelLowering.cpp" +check "W65816 clang built" test -x "$TOOLS_DIR/llvm-mos-build/bin/clang" +check "W65816 llc built" test -x "$TOOLS_DIR/llvm-mos-build/bin/llc" +check "W65816 llvm-mc built" test -x "$TOOLS_DIR/llvm-mos-build/bin/llvm-mc" +check "llc lists w65816 target" \ + bash -c "'$TOOLS_DIR/llvm-mos-build/bin/llc' --version 2>/dev/null | grep -q '^[[:space:]]*w65816[[:space:]]'" + +# link816 + omfEmit +check "link816 binary" test -x "$TOOLS_DIR/link816" +check "omfEmit binary" test -x "$TOOLS_DIR/omfEmit" + +# Runtime libraries (built objects we link into every program) +check "runtime/crt0.o" test -s "$PROJECT_ROOT/runtime/crt0.o" +check "runtime/libc.o" test -s "$PROJECT_ROOT/runtime/libc.o" +check "runtime/libgcc.o" test -s "$PROJECT_ROOT/runtime/libgcc.o" +check "runtime/softFloat.o" test -s "$PROJECT_ROOT/runtime/softFloat.o" +check "runtime/softDouble.o" test -s "$PROJECT_ROOT/runtime/softDouble.o" + # MAME + ROMs check "mame binary" command -v mame check "mame Lua console support" bash -c "mame -showusage 2>&1 | grep -q -- '-console'" check "rom: apple2gs.zip" test -s "$TOOLS_DIR/mame/roms/apple2gs.zip" check "rom: apple2gsr1.zip" test -s "$TOOLS_DIR/mame/roms/apple2gsr1.zip" -# Calypsi benchmark -check "calypsi cc65816" test -x "$TOOLS_DIR/calypsi/bin/cc65816" +# Calypsi benchmark (optional; --skip-calypsi at install skips this). +if [ -d "$TOOLS_DIR/calypsi" ]; then + check "calypsi cc65816" \ + test -x "$TOOLS_DIR/calypsi/usr/local/lib/calypsi-65816-5.16/bin/cc65816" +fi -# ORCA/C reference -check "orca-c source" test -d "$TOOLS_DIR/orca-c/.git" +# ORCA/C reference (optional; --skip-orca skips this). +if [ -d "$TOOLS_DIR/orca-c" ]; then + check "orca-c source" test -d "$TOOLS_DIR/orca-c/.git" +fi + +# End-to-end smoke: compile a tiny C program for W65816 to prove the +# toolchain actually produces machine code. +echo +log "end-to-end compile check" +tmp=$(mktemp -d -t llvm816-verify.XXXXXX) +trap "rm -rf '$tmp'" EXIT +cat > "$tmp/hello.c" <<'EOF' +int answer(void) { return 42; } +EOF +if "$TOOLS_DIR/llvm-mos-build/bin/clang" --target=w65816 -O2 -c "$tmp/hello.c" \ + -o "$tmp/hello.o" 2>/dev/null \ + && "$TOOLS_DIR/llvm-mos-build/bin/llvm-objdump" --triple=w65816 -d "$tmp/hello.o" 2>/dev/null \ + | grep -q "lda"; then + printf ' [ OK ] C -> w65816 .o compile produces lda instruction\n' +else + printf ' [FAIL] end-to-end compile failed\n' + fails=$((fails + 1)) +fi echo if [ "$fails" -eq 0 ]; then diff --git a/setup.sh b/setup.sh index c8bac22..e11c329 100755 --- a/setup.sh +++ b/setup.sh @@ -2,15 +2,24 @@ # Top-level installer for the llvm816 project. Installs everything into # ./tools/ so the tree is self-contained and deletable. # +# Stages (5/5): +# 1. apt dependencies +# 2. llvm-mos clone + W65816 backend apply + cmake/ninja build of +# clang/llc/llvm-mc + build link816/omfEmit + build runtime (.o) +# 3. MAME + apple2gs ROMs +# 4. Calypsi 5.16 (reference compiler — optional) +# 5. ORCA/C source (header reference — optional) +# # Usage: -# ./setup.sh # install everything (no llvm-mos source build) -# ./setup.sh --build-llvm # also cmake+ninja build llvm-mos (slow) +# ./setup.sh # install + build everything (~30-60 min) # ./setup.sh --skip-deps # skip apt packages -# ./setup.sh --skip-llvm # skip llvm-mos +# ./setup.sh --skip-llvm # skip stage 2 (clang/runtime/link816) # ./setup.sh --skip-mame # skip MAME + ROM fetch # ./setup.sh --skip-calypsi # skip Calypsi # ./setup.sh --skip-orca # skip ORCA/C reference +# ./setup.sh --skip-verify # skip the post-install verification # ./setup.sh --verify-only # run verification only +# ./setup.sh --build-llvm # deprecated alias for the default behavior set -euo pipefail diff --git a/src/llvm/lib/Target/W65816/W65816ISelLowering.cpp b/src/llvm/lib/Target/W65816/W65816ISelLowering.cpp index 1b85780..d7777ba 100644 --- a/src/llvm/lib/Target/W65816/W65816ISelLowering.cpp +++ b/src/llvm/lib/Target/W65816/W65816ISelLowering.cpp @@ -1731,28 +1731,28 @@ SDValue W65816TargetLowering::LowerShift(SDValue Op, SelectionDAG &DAG) const { SDValue X = Op.getOperand(0); SDValue Lo = extractWide32Lo(DAG, DL, X); SDValue Hi = extractWide32Hi(DAG, DL, X); - SDValue One = DAG.getConstant(1, DL, MVT::i16); - SDValue Fifteen = DAG.getConstant(15, DL, MVT::i16); - for (unsigned i = 0; i < N; i++) { - if (Op0 == ISD::SHL) { - // (Hi:Lo) << 1: carry = Lo bit15 → into Hi bit0. - SDValue NewLo = DAG.getNode(ISD::SHL, DL, MVT::i16, Lo, One); - SDValue HiBit0 = DAG.getNode(ISD::SRL, DL, MVT::i16, Lo, Fifteen); - SDValue HiShl = DAG.getNode(ISD::SHL, DL, MVT::i16, Hi, One); - SDValue NewHi = DAG.getNode(ISD::OR, DL, MVT::i16, HiShl, HiBit0); - Lo = NewLo; Hi = NewHi; - } else { - // SRL/SRA: Hi shifts (logical or arithmetic), Lo gets the - // low bit of pre-shift Hi inserted at bit 15. - SDValue NewHi = DAG.getNode(Op0, DL, MVT::i16, Hi, One); - SDValue HiLow = DAG.getNode(ISD::AND, DL, MVT::i16, Hi, One); - SDValue LoTop = DAG.getNode(ISD::SHL, DL, MVT::i16, HiLow, Fifteen); - SDValue LoSrl = DAG.getNode(ISD::SRL, DL, MVT::i16, Lo, One); - SDValue NewLo = DAG.getNode(ISD::OR, DL, MVT::i16, LoSrl, LoTop); - Lo = NewLo; Hi = NewHi; - } + SDValue ShN = DAG.getConstant(N, DL, MVT::i16); + SDValue ShCo = DAG.getConstant(16 - N, DL, MVT::i16); + if (Op0 == ISD::SHL) { + // (Hi:Lo) << N == ((Hi << N) | (Lo >> (16-N))) : (Lo << N) + // 4 SDAG ops instead of N iterations of 4 ops. Lets the + // combiner / isel produce ASLA16-cascade + SRL8A+LSRA16- + // cascade + single OR, avoiding the bit-by-bit OR cascade + // that the unrolled form produced. + SDValue NewLo = DAG.getNode(ISD::SHL, DL, MVT::i16, Lo, ShN); + SDValue HiTop = DAG.getNode(ISD::SRL, DL, MVT::i16, Lo, ShCo); + SDValue HiShl = DAG.getNode(ISD::SHL, DL, MVT::i16, Hi, ShN); + SDValue NewHi = DAG.getNode(ISD::OR, DL, MVT::i16, HiShl, HiTop); + return buildWide32(DAG, DL, NewLo, NewHi); + } else { + // SRL/SRA by N: NewHi = Hi >> N (logical or arithmetic); + // NewLo = (Lo >> N) | (Hi << (16-N)). + SDValue NewHi = DAG.getNode(Op0, DL, MVT::i16, Hi, ShN); + SDValue LoTop = DAG.getNode(ISD::SHL, DL, MVT::i16, Hi, ShCo); + SDValue LoSrl = DAG.getNode(ISD::SRL, DL, MVT::i16, Lo, ShN); + SDValue NewLo = DAG.getNode(ISD::OR, DL, MVT::i16, LoSrl, LoTop); + return buildWide32(DAG, DL, NewLo, NewHi); } - return buildWide32(DAG, DL, Lo, Hi); } } } @@ -2663,6 +2663,32 @@ SDValue W65816TargetLowering::LowerMUL_I32(SDValue Op, return SDValue(); }; + // Mul-by-constant strength reduction: (X * K) where K-1 or K+1 is + // a small power of 2 (shift count 1..5, matching our inlined i32 + // SHL range) expands to (X << N) +/- X — saves a __mulsi3 libcall + // (~250 cyc) for ~70 cyc of inlined shift+add. Catches djb2Hash's + // `h * 33` = (h << 5) + h. + // + // Patterns covered: + // K = 2^N + 1 in {3,5,9,17,33} → (X << N) + X + // K = 2^N - 1 in {7,15,31} → (X << N) - X + // Larger N hits the i32 SHL libcall path (no longer profitable). + if (auto *CN = dyn_cast(Rhs)) { + int64_t K = CN->getSExtValue(); + for (unsigned N = 1; N <= 5; N++) { + int64_t Pow = int64_t{1} << N; + SDValue ShAmt = DAG.getConstant(N, DL, MVT::i16); + if (K == Pow + 1) { + SDValue Shl = DAG.getNode(ISD::SHL, DL, MVT::i32, Lhs, ShAmt); + return DAG.getNode(ISD::ADD, DL, MVT::i32, Shl, Lhs); + } + if (K == Pow - 1) { + SDValue Shl = DAG.getNode(ISD::SHL, DL, MVT::i32, Lhs, ShAmt); + return DAG.getNode(ISD::SUB, DL, MVT::i32, Shl, Lhs); + } + } + } + SDValue A = narrowToI16(Lhs); SDValue B = narrowToI16(Rhs); if (A && B) { diff --git a/src/llvm/lib/Target/W65816/W65816InstrInfo.td b/src/llvm/lib/Target/W65816/W65816InstrInfo.td index 647b7cd..298daed 100644 --- a/src/llvm/lib/Target/W65816/W65816InstrInfo.td +++ b/src/llvm/lib/Target/W65816/W65816InstrInfo.td @@ -1414,8 +1414,10 @@ def PEI_DP : InstDP<0xD4, "pei">; // AsmParser has no way to know the current M/X bits, so it always // reaches for the _Imm16 form. Codegen can still select _Imm8 // explicitly once we have 8-bit patterns. +let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in { def LDA_Imm8 : InstImm8<0xA9, "lda"> { let MHigh = 1; let DecoderNamespace = "W65816MHigh"; let isCodeGenOnly = 1; let Defs = [A]; } def LDA_Imm16 : InstImm16<0xA9, "lda"> { let MLow = 1; let Defs = [A]; } +} // Same opcode/encoding as LDA_Imm16, but the operand emits a fixup_bank16 // so the linker / OMF Loader fills in (bankByte, 0) of the symbol. // Used by the LDAi16imm_bank pseudo for materializing the high half of @@ -1455,8 +1457,10 @@ def STA_DPIndLongY : InstDPIndLongY<0x97, "sta"> { let Uses = [A, Y]; } def STA_LongX : InstAbsLongX<0x9F, "sta">; //---------------------------------------------------------------- LDX (load X) +let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in { def LDX_Imm8 : InstImm8<0xA2, "ldx"> { let XHigh = 1; let DecoderNamespace = "W65816XHigh"; let isCodeGenOnly = 1; let Defs = [X]; } def LDX_Imm16 : InstImm16<0xA2, "ldx"> { let XLow = 1; let Defs = [X]; } +} def LDX_DP : InstDP<0xA6, "ldx">; def LDX_Abs : InstAbs<0xAE, "ldx">; def LDX_DPY : InstDPY<0xB6, "ldx">; @@ -1468,8 +1472,10 @@ def STX_Abs : InstAbs<0x8E, "stx">; def STX_DPY : InstDPY<0x96, "stx">; //---------------------------------------------------------------- LDY (load Y) +let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in { def LDY_Imm8 : InstImm8<0xA0, "ldy"> { let XHigh = 1; let DecoderNamespace = "W65816XHigh"; let isCodeGenOnly = 1; let Defs = [Y]; } def LDY_Imm16 : InstImm16<0xA0, "ldy"> { let XLow = 1; let Defs = [Y]; } +} def LDY_DP : InstDP<0xA4, "ldy">; def LDY_Abs : InstAbs<0xAC, "ldy">; def LDY_DPX : InstDPX<0xB4, "ldy">; diff --git a/src/llvm/lib/Target/W65816/W65816StackRelToImg.cpp b/src/llvm/lib/Target/W65816/W65816StackRelToImg.cpp index 832c6b9..a02df53 100644 --- a/src/llvm/lib/Target/W65816/W65816StackRelToImg.cpp +++ b/src/llvm/lib/Target/W65816/W65816StackRelToImg.cpp @@ -2051,6 +2051,396 @@ bool W65816StackRelToImg::runOnMachineFunction(MachineFunction &MF) { } } + // Shift-cascade dead-store elimination. Greedy regalloc sometimes + // emits `LDA dp; (ASLA16; STA dp){×N}; ...` where each intermediate + // STA_DP is dead — the next ASLA16 reads $a (still holding the value) + // and shifts again, then stores again. Only the final STA matters. + // + // Pattern: LDA_DP X ; (ASLA16; STA_DP X){×N+1} + // where every STA writes to the same DP slot the LDA read + // from, and nothing in between reads $a or DP[X] except + // the cascade itself. + // Rewrite: LDA_DP X ; ASLA16{×N+1} ; STA_DP X + // (final STA only; intermediate STAs erased.) + // + // For N=4 (i.e. 5 shifts), saves 4 STA_DPs = 12 cyc. Hits djb2Hash's + // `Hi << 5` cascade (where greedy spills the intermediate vregs). + for (MachineBasicBlock &MBB : MF) { + SmallVector ToErase; + for (auto It = MBB.begin(); It != MBB.end(); ++It) { + if (It->getOpcode() != W65816::LDA_DP) continue; + if (It->getNumOperands() < 1 || !It->getOperand(0).isImm()) continue; + int64_t Slot = It->getOperand(0).getImm(); + auto Cur = std::next(It); + // Track intermediate STAs in this cascade. + SmallVector Intermediates; + bool sawAny = false; + while (Cur != MBB.end()) { + if (Cur->isDebugInstr()) { ++Cur; continue; } + unsigned Op = Cur->getOpcode(); + if (Op != W65816::ASLA16 && Op != W65816::LSRA16) break; + auto Sta = std::next(Cur); + while (Sta != MBB.end() && Sta->isDebugInstr()) ++Sta; + if (Sta == MBB.end()) break; + if (Sta->getOpcode() != W65816::STA_DP) break; + if (Sta->getNumOperands() < 1 || !Sta->getOperand(0).isImm()) break; + if (Sta->getOperand(0).getImm() != Slot) break; + sawAny = true; + Intermediates.push_back(&*Sta); + Cur = std::next(Sta); + } + if (!sawAny || Intermediates.size() < 2) continue; + // The LAST STA is the real one; mark everything before it for erase. + Intermediates.pop_back(); + for (MachineInstr *MI : Intermediates) + ToErase.push_back(MI); + } + for (MachineInstr *MI : ToErase) { + MI->eraseFromParent(); + Changed = true; + } + } + + // i32-SRL-by-1 fold: detects the SDAG expansion for `(SRL i32 X, 1)` + // and rewrites to the two-instruction `LSR Hi ; ROR Lo` pair when + // both halves live in DP. + // + // Input pattern (after the DP-shift-fold above runs on the trailing + // `LDA Hi ; LSRA16 ; STA Hi` triplet): + // LDA_DP Hi + // SHL15A ; A = (Hi & 1) << 15 + // STA_DP Yc ; carry slot + // LDA_DP Lo + // LSRA16 ; Lo >>= 1 + // STA_DP Lo + // ORA_DP Yc ; combine with carry-at-bit-15 + // STA_DP Lo + // LSR_DP Hi ; (folded from the trailing triplet) + // + // Output: + // LSR_DP Hi ; Hi >>= 1, C = old bit 0 of Hi + // ROR_DP Lo ; Lo = (C, Lo >> 1) + // + // Same semantics, ~30 cyc saved per iter. popcount measured at 2728 + // cyc; expected post-fold ~1858 cyc (-32%) due to 29 iters of i32 + // SRL by 1. + for (MachineBasicBlock &MBB : MF) { + SmallVector ToErase; + for (auto It = MBB.begin(); It != MBB.end();) { + auto LdaHi = It++; + if (LdaHi->getOpcode() != W65816::LDA_DP) continue; + if (LdaHi->getNumOperands() < 1 || !LdaHi->getOperand(0).isImm()) + continue; + int64_t HiAddr = LdaHi->getOperand(0).getImm(); + auto P = std::next(LdaHi); + auto skipDbg = [&](auto &P) { + while (P != MBB.end() && P->isDebugInstr()) ++P; + }; + skipDbg(P); + if (P == MBB.end() || P->getOpcode() != W65816::SHL15A) continue; + auto Shl = P; ++P; skipDbg(P); + if (P == MBB.end() || P->getOpcode() != W65816::STA_DP) continue; + if (P->getNumOperands() < 1 || !P->getOperand(0).isImm()) continue; + int64_t YcAddr = P->getOperand(0).getImm(); + auto StaYc = P; ++P; skipDbg(P); + if (P == MBB.end() || P->getOpcode() != W65816::LDA_DP) continue; + if (P->getNumOperands() < 1 || !P->getOperand(0).isImm()) continue; + int64_t LoAddr = P->getOperand(0).getImm(); + auto LdaLo = P; ++P; skipDbg(P); + if (P == MBB.end() || P->getOpcode() != W65816::LSRA16) continue; + auto LsrA1 = P; ++P; skipDbg(P); + if (P == MBB.end() || P->getOpcode() != W65816::STA_DP) continue; + if (P->getOperand(0).getImm() != LoAddr) continue; + auto StaLo1 = P; ++P; skipDbg(P); + if (P == MBB.end() || P->getOpcode() != W65816::ORA_DP) continue; + if (P->getOperand(0).getImm() != YcAddr) continue; + auto OraYc = P; ++P; skipDbg(P); + if (P == MBB.end() || P->getOpcode() != W65816::STA_DP) continue; + if (P->getOperand(0).getImm() != LoAddr) continue; + auto StaLo2 = P; ++P; skipDbg(P); + if (P == MBB.end() || P->getOpcode() != W65816::LSR_DP) continue; + if (P->getOperand(0).getImm() != HiAddr) continue; + auto LsrHi = P; + // Check that YcAddr is not READ after LsrHi before being + // overwritten. If the next op touching YcAddr is a STA (write), + // the carry-slot value is dead — safe to drop our STA Yc. If + // it's a load-style op (LDA/ORA/AND/etc.) before any STA, then + // some downstream code is consuming our stored carry — bail. + bool YcReadBeforeWrite = false; + for (auto Q = std::next(LsrHi); Q != MBB.end(); ++Q) { + if (Q->isDebugInstr()) continue; + bool touchesYc = false; + bool isWriteOfYc = false; + for (const MachineOperand &MO : Q->operands()) { + if (MO.isImm() && MO.getImm() == YcAddr) { + unsigned QO = Q->getOpcode(); + if (QO == W65816::STA_DP || QO == W65816::STZ_DP || + QO == W65816::STX_DP || QO == W65816::STY_DP) { + touchesYc = true; isWriteOfYc = true; + } else if (QO == W65816::LDA_DP || QO == W65816::ORA_DP || + QO == W65816::AND_DP || QO == W65816::EOR_DP || + QO == W65816::ADC_DP || QO == W65816::SBC_DP || + QO == W65816::CMP_DP || QO == W65816::LSR_DP || + QO == W65816::ROR_DP || QO == W65816::ASL_DP || + QO == W65816::ROL_DP || QO == W65816::INC_DP || + QO == W65816::DEC_DP) { + touchesYc = true; // any of these is a read or RMW + } + break; + } + } + if (touchesYc) { + if (!isWriteOfYc) YcReadBeforeWrite = true; + break; // first touch decides + } + } + if (YcReadBeforeWrite) continue; + // Apply: replace the 8-op sequence with LSR_DP Hi ; ROR_DP Lo. + // The LSR_DP Hi already exists (at LsrHi); just insert ROR_DP Lo + // immediately after it and erase the rest. + BuildMI(MBB, std::next(MachineBasicBlock::iterator(LsrHi)), + LsrHi->getDebugLoc(), TII->get(W65816::ROR_DP)) + .addImm(LoAddr); + ToErase.push_back(&*LdaHi); + ToErase.push_back(&*Shl); + ToErase.push_back(&*StaYc); + ToErase.push_back(&*LdaLo); + ToErase.push_back(&*LsrA1); + ToErase.push_back(&*StaLo1); + ToErase.push_back(&*OraYc); + ToErase.push_back(&*StaLo2); + It = std::next(MachineBasicBlock::iterator(LsrHi)); + } + for (MachineInstr *MI : ToErase) { + MI->eraseFromParent(); + Changed = true; + } + } + + // DP dead-store elimination — runs LAST (after the i32-SRL-by-1 + // fold, which depends on the `STA_DP Lo` between LSRA16 and ORA_DP + // staying intact). When two STA_DP X stores write the same DP slot + // with no intervening read or write of that slot, the first is dead. + // Emerges from popcount's `bit = x & 1` pattern at end of body. + // Saves 5 cyc per match. + // + // Conservative: branches / calls / inline asm and all DP-indirect + // addressing modes (which use the slot AS a pointer) block the + // elim — those reads must see the intended store value. + { + auto touchesDpSlot = [](const MachineInstr &MI, int64_t Addr) { + unsigned Op = MI.getOpcode(); + switch (Op) { + // Direct DP ops. + case W65816::LDA_DP: case W65816::STA_DP: case W65816::STZ_DP: + case W65816::LDX_DP: case W65816::STX_DP: + case W65816::LDY_DP: case W65816::STY_DP: + case W65816::ADC_DP: case W65816::SBC_DP: + case W65816::AND_DP: case W65816::ORA_DP: + case W65816::EOR_DP: case W65816::CMP_DP: + case W65816::CPX_DP: case W65816::CPY_DP: + case W65816::LSR_DP: case W65816::ROR_DP: + case W65816::ASL_DP: case W65816::ROL_DP: + case W65816::INC_DP: case W65816::DEC_DP: + case W65816::BIT_DP: case W65816::TSB_DP: + case W65816::TRB_DP: + // DP-indexed ops. + case W65816::LDA_DPX: case W65816::STA_DPX: case W65816::STZ_DPX: + case W65816::LDY_DPX: case W65816::STY_DPX: + case W65816::ADC_DPX: case W65816::SBC_DPX: + case W65816::AND_DPX: case W65816::ORA_DPX: + case W65816::EOR_DPX: case W65816::CMP_DPX: + case W65816::LDX_DPY: case W65816::STX_DPY: + case W65816::LSR_DPX: case W65816::ROR_DPX: + case W65816::ASL_DPX: case W65816::ROL_DPX: + case W65816::BIT_DPX: + // DP-indirect ops — read the slot AS a pointer. + case W65816::LDA_DPInd: case W65816::STA_DPInd: + case W65816::LDA_DPIndY: case W65816::STA_DPIndY: + case W65816::LDA_DPIndX: case W65816::STA_DPIndX: + case W65816::LDA_DPIndLong: case W65816::STA_DPIndLong: + case W65816::LDA_DPIndLongY: case W65816::STA_DPIndLongY: + case W65816::ADC_DPInd: case W65816::SBC_DPInd: + case W65816::AND_DPInd: case W65816::ORA_DPInd: + case W65816::EOR_DPInd: case W65816::CMP_DPInd: + case W65816::ADC_DPIndY: case W65816::SBC_DPIndY: + case W65816::AND_DPIndY: case W65816::ORA_DPIndY: + case W65816::EOR_DPIndY: case W65816::CMP_DPIndY: + case W65816::ADC_DPIndLong: case W65816::SBC_DPIndLong: + case W65816::AND_DPIndLong: case W65816::ORA_DPIndLong: + case W65816::EOR_DPIndLong: case W65816::CMP_DPIndLong: + case W65816::ADC_DPIndLongY: case W65816::SBC_DPIndLongY: + case W65816::AND_DPIndLongY: case W65816::ORA_DPIndLongY: + case W65816::EOR_DPIndLongY: case W65816::CMP_DPIndLongY: + if (MI.getNumOperands() >= 1 && MI.getOperand(0).isImm() && + MI.getOperand(0).getImm() == Addr) + return true; + // Indirect ops read addr AND addr+1 (16-bit ptr) or addr+1,2 + // (24-bit ptr). Bail when the candidate dead-store target is + // within those bytes. + if (MI.getNumOperands() >= 1 && MI.getOperand(0).isImm()) { + int64_t IndAddr = MI.getOperand(0).getImm(); + if (IndAddr == Addr - 1 || IndAddr == Addr - 2) + return true; + } + break; + } + return false; + }; + for (MachineBasicBlock &MBB : MF) { + SmallVector ToErase; + SmallPtrSet ErasedSet; + for (auto It = MBB.begin(); It != MBB.end(); ++It) { + if (ErasedSet.count(&*It)) continue; + if (It->getOpcode() != W65816::STA_DP) continue; + if (It->getNumOperands() < 1 || !It->getOperand(0).isImm()) + continue; + int64_t Sta1Addr = It->getOperand(0).getImm(); + auto Walk = std::next(It); + while (Walk != MBB.end()) { + if (Walk->isDebugInstr()) { ++Walk; continue; } + if (Walk->isBranch() || Walk->isCall() || Walk->isReturn() || + Walk->isInlineAsm()) break; + if (Walk->getOpcode() == W65816::STA_DP && + Walk->getNumOperands() >= 1 && Walk->getOperand(0).isImm() && + Walk->getOperand(0).getImm() == Sta1Addr) { + ToErase.push_back(&*It); + ErasedSet.insert(&*It); + break; + } + if (touchesDpSlot(*Walk, Sta1Addr)) break; + ++Walk; + } + } + for (MachineInstr *MI : ToErase) { + MI->eraseFromParent(); + Changed = true; + } + } + } + + // DP-slot zero-check bridge via X. Pattern: + // [op that sets Z on A] + // STA_DP slot + // [ops that don't read/write slot, don't touch X, don't branch/call] + // LDA_DP slot + // Bcond (BNE/BEQ) + // + // The STA/LDA round-trip exists purely to preserve A's value across + // the clobbers. TAX/TXA does the same job in 4 cyc instead of 8. + // Saves 4 cyc/match. Hits popcount's `x_lo | x_hi ; (work) ; bne`. + // + // Safety: X register must be dead. Conservative check — fires only + // when the entire MBB doesn't reference X register except as our new + // TAX/TXA, AND all MBB successors don't have X as live-in. + for (MachineBasicBlock &MBB : MF) { + // First: does this MBB reference X at all? If yes, bail. This is + // conservative — refining would need full liveness. + bool MbbTouchesX = false; + for (const MachineInstr &MI : MBB) { + for (const MachineOperand &MO : MI.operands()) { + if (MO.isReg() && MO.getReg() == W65816::X) { + MbbTouchesX = true; break; + } + } + if (MbbTouchesX) break; + // Also handle InstImplied ops that don't list X explicitly. + switch (MI.getOpcode()) { + case W65816::TAX: case W65816::TYX: case W65816::TSX: + case W65816::PLX: case W65816::TXA: case W65816::TXY: + case W65816::TXS: case W65816::PHX: case W65816::INX: + case W65816::DEX: + MbbTouchesX = true; break; + } + if (MI.isCall()) { MbbTouchesX = true; break; } + if (MbbTouchesX) break; + } + if (MbbTouchesX) continue; + // Successors with X as live-in? + bool SuccUsesX = false; + for (MachineBasicBlock *Succ : MBB.successors()) { + if (Succ->isLiveIn(W65816::X)) { SuccUsesX = true; break; } + } + if (SuccUsesX) continue; + // Walk forward looking for STA_DP / ... / LDA_DP / Bcond patterns. + SmallVector ToErase; + for (auto It = MBB.begin(); It != MBB.end(); ++It) { + if (It->getOpcode() != W65816::STA_DP) continue; + if (It->getNumOperands() < 1 || !It->getOperand(0).isImm()) continue; + int64_t StaAddr = It->getOperand(0).getImm(); + auto Walk = std::next(It); + MachineInstr *LdaMI = nullptr; + MachineInstr *BcondMI = nullptr; + bool blocked = false; + while (Walk != MBB.end()) { + if (Walk->isDebugInstr()) { ++Walk; continue; } + unsigned WO = Walk->getOpcode(); + if (Walk->isBranch() || Walk->isCall() || Walk->isReturn() || + Walk->isInlineAsm()) { + // If this is the Bcond AFTER our LDA, capture it. + if (LdaMI && (WO == W65816::BNE || WO == W65816::BEQ)) { + BcondMI = &*Walk; + } + break; + } + if (WO == W65816::LDA_DP && + Walk->getNumOperands() >= 1 && Walk->getOperand(0).isImm() && + Walk->getOperand(0).getImm() == StaAddr) { + LdaMI = &*Walk; + // Next non-debug must be BNE/BEQ. + auto Next = std::next(Walk); + while (Next != MBB.end() && Next->isDebugInstr()) ++Next; + if (Next != MBB.end()) { + unsigned NO = Next->getOpcode(); + if (NO == W65816::BNE || NO == W65816::BEQ) BcondMI = &*Next; + } + break; + } + // Anything touching our DP slot bails. + for (const MachineOperand &MO : Walk->operands()) { + if (MO.isImm() && MO.getImm() == StaAddr) { + // Conservatively assume DP-op refs StaAddr unless we know + // it's a different opcode entirely. The dead-store-elim + // has similar logic but more refined; here we keep it + // simple: bail on any imm-matching op. + blocked = true; break; + } + } + if (blocked) break; + ++Walk; + } + if (blocked || !LdaMI || !BcondMI) continue; + // Global-use check: if any OTHER MBB references the DP slot, the + // STA we'd erase may be initializing it for a later use. Bail. + // Caught by sumOfSquares' counter at $D0 — entry-BB's STA_DP 208 + // initializes the countdown counter that bb.4 reads via DEC_DP. + bool referencedElsewhere = false; + for (MachineBasicBlock &OtherMBB : MF) { + if (&OtherMBB == &MBB) continue; + for (const MachineInstr &OtherMI : OtherMBB) { + for (const MachineOperand &MO : OtherMI.operands()) { + if (MO.isImm() && MO.getImm() == StaAddr) { + referencedElsewhere = true; break; + } + } + if (referencedElsewhere) break; + } + if (referencedElsewhere) break; + } + if (referencedElsewhere) continue; + // Replace STA_DP with TAX, LDA_DP with TXA. + const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); + BuildMI(MBB, It, It->getDebugLoc(), TII->get(W65816::TAX)); + BuildMI(MBB, LdaMI, LdaMI->getDebugLoc(), TII->get(W65816::TXA)); + ToErase.push_back(&*It); + ToErase.push_back(LdaMI); + } + for (MachineInstr *MI : ToErase) { + MI->eraseFromParent(); + Changed = true; + } + } + // Run elideStoreForwarding at the very end, AFTER IMG promotion has // committed slot assignments. Running this peephole earlier (with // the other early peepholes) cascades into different IMG-promotion diff --git a/src/llvm/lib/Target/W65816/W65816UnLSR.cpp b/src/llvm/lib/Target/W65816/W65816UnLSR.cpp index 8451bec..f283748 100644 --- a/src/llvm/lib/Target/W65816/W65816UnLSR.cpp +++ b/src/llvm/lib/Target/W65816/W65816UnLSR.cpp @@ -40,6 +40,7 @@ //===---------------------------------------------------------------------===// #include "W65816.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/LoopInfo.h" @@ -82,6 +83,8 @@ public: private: bool processLoop(Loop *L); + bool processCounterToPtrPHIs(Loop *L); + bool processReturnedCounter(Loop *L); }; } // namespace @@ -103,17 +106,409 @@ bool W65816UnLSR::runOnFunction(Function &F) { bool Changed = false; for (Loop *L : LI) { Changed |= processLoop(L); + Changed |= processCounterToPtrPHIs(L); + // NOTE: processReturnedCounter (strLen-shape counter → ptr-difference + // at exit) is correct but produces a NET LOSS on strLen: without the + // counter PHI, the i32 pointer arithmetic falls back to clc+adc + // chains (16+ cyc/iter) instead of inc-A on the lo half (5 cyc/iter + // for ptr update + 5 for counter inc). See feedback memory. + // Disabled until codegen can use inc-DP for the lo half of a pointer + // PHI's increment without the SDAG materializing a full i32 add. // Recurse into nested loops. SmallVector Worklist(L->begin(), L->end()); while (!Worklist.empty()) { Loop *Sub = Worklist.pop_back_val(); Changed |= processLoop(Sub); + Changed |= processCounterToPtrPHIs(Sub); Worklist.append(Sub->begin(), Sub->end()); } } return Changed; } + +// strLen-style undo: LSR converts `return p - s` into a counter PHI +// `%lsr.iv` that increments per iter and is returned directly: +// %lsr.iv = phi i16 [-1, %entry], [%lsr.iv.next, %latch] +// %p.0 = phi ptr [%s, %entry], [%incdec.ptr, %latch] +// %incdec.ptr = getelementptr i8, %p.0, i32 1 +// %lsr.iv.next = add i16 %lsr.iv, 1 +// br ..., %exit, %loop +// %exit: +// ret i16 %lsr.iv.next +// +// LSR's reasoning: cheaper to maintain a counter than compute (p - s) +// at exit. On W65816 the opposite is true: counter inc per iter costs +// 5 cyc/iter * N iters; one-time sub at exit costs ~10 cyc total. +// +// This undo finds the counter PHI, verifies its only out-of-loop use +// is via LCSSA → return, finds the sibling pointer PHI with the same +// stride, and replaces the return value with +// `(i16)(p_lcssa - base) + (K_init + 1)`. Erases the counter PHI. +// +// Saves ~5 cyc/iter on strLen-shape loops with a returned counter. +bool W65816UnLSR::processReturnedCounter(Loop *L) { + BasicBlock *Header = L->getHeader(); + BasicBlock *Latch = L->getLoopLatch(); + BasicBlock *Preheader = L->getLoopPreheader(); + if (!Latch || !Preheader) return false; + + // Single-exit loop. + SmallVector ExitBlocks; + L->getExitBlocks(ExitBlocks); + if (ExitBlocks.size() != 1) return false; + BasicBlock *Exit = ExitBlocks[0]; + + // Find a candidate counter PHI: integer, init=ConstantInt, step=+1. + PHINode *CounterPHI = nullptr; + ConstantInt *KInit = nullptr; + BinaryOperator *CounterStep = nullptr; + for (PHINode &PN : Header->phis()) { + if (!PN.getType()->isIntegerTy()) continue; + if (PN.getNumIncomingValues() != 2) continue; + Value *Init = nullptr, *Step = nullptr; + for (unsigned i = 0; i < PN.getNumIncomingValues(); ++i) { + BasicBlock *Pred = PN.getIncomingBlock(i); + if (L->contains(Pred)) Step = PN.getIncomingValue(i); + else Init = PN.getIncomingValue(i); + } + if (!Init || !Step) continue; + auto *InitC = dyn_cast(Init); + if (!InitC) continue; + auto *StepBO = dyn_cast(Step); + if (!StepBO || StepBO->getOpcode() != Instruction::Add) continue; + Value *Other = nullptr; + if (StepBO->getOperand(0) == &PN) Other = StepBO->getOperand(1); + else if (StepBO->getOperand(1) == &PN) Other = StepBO->getOperand(0); + if (!Other) continue; + auto *StepCI = dyn_cast(Other); + if (!StepCI || !StepCI->isOne()) continue; + CounterPHI = &PN; + KInit = InitC; + CounterStep = StepBO; + break; + } + if (!CounterPHI) return false; + + // The counter PHI must be used INSIDE the loop only by its increment + // and OUTSIDE the loop only via an LCSSA PHI in the exit block that + // feeds a return. Same for the increment. + auto isOnlyInLoopUseTheStep = [&](Value *V) { + for (User *U : V->users()) { + auto *UI = dyn_cast(U); + if (!UI) return false; + if (!L->contains(UI)) continue; // out-of-loop is handled separately + if (UI == CounterStep) continue; + // The PHI itself is allowed (V might be CounterStep, used by + // CounterPHI's back-edge incoming). + if (UI == CounterPHI) continue; + return false; + } + return true; + }; + if (!isOnlyInLoopUseTheStep(CounterPHI)) return false; + if (!isOnlyInLoopUseTheStep(CounterStep)) return false; + + // Find a use of CounterPHI or CounterStep that's a ReturnInst. + // The use might be DIRECT (no LCSSA — common after LCSSA cleanup) + // or via an LCSSA PHI in the exit block. + ReturnInst *Ret = nullptr; + Value *RetSource = nullptr; // the value the ret reads + PHINode *ExitLCSSA = nullptr; // optional LCSSA PHI to erase + bool fromNext = false; // true if return source is CounterStep + auto findRet = [&](Value *V, bool isNext) -> bool { + for (User *U : V->users()) { + auto *UI = dyn_cast(U); + if (!UI) continue; + // Skip in-loop uses (those are the counter increment chain). + if (L->contains(UI->getParent())) continue; + if (auto *R = dyn_cast(UI)) { + if (R->getReturnValue() != V) continue; + Ret = R; RetSource = V; fromNext = isNext; return true; + } + // LCSSA PHI in the exit block? + if (auto *PN = dyn_cast(UI)) { + if (PN->getParent() != Exit) continue; + if (PN->getNumIncomingValues() != 1) continue; + if (PN->getIncomingValue(0) != V) continue; + if (!PN->hasOneUse()) continue; + auto *R = dyn_cast(PN->user_back()); + if (!R || R->getReturnValue() != PN) continue; + Ret = R; RetSource = V; fromNext = isNext; ExitLCSSA = PN; + return true; + } + } + return false; + }; + if (!findRet(CounterStep, true) && !findRet(CounterPHI, false)) + return false; + + // Find a sibling pointer PHI: init=Base, latch incoming is a + // `getelementptr i8, %ptr, 1` of itself. + PHINode *PtrPHI = nullptr; + Value *Base = nullptr; + GetElementPtrInst *PtrStep = nullptr; + for (PHINode &PN : Header->phis()) { + if (!PN.getType()->isPointerTy()) continue; + if (PN.getNumIncomingValues() != 2) continue; + Value *Init = nullptr, *Step = nullptr; + for (unsigned i = 0; i < PN.getNumIncomingValues(); ++i) { + BasicBlock *Pred = PN.getIncomingBlock(i); + if (L->contains(Pred)) Step = PN.getIncomingValue(i); + else Init = PN.getIncomingValue(i); + } + if (!Init || !Step) continue; + auto *StepGEP = dyn_cast(Step); + if (!StepGEP) continue; + if (StepGEP->getPointerOperand() != &PN) continue; + if (StepGEP->getNumIndices() != 1) continue; + if (!StepGEP->getSourceElementType()->isIntegerTy(8)) continue; + auto *StrideCI = dyn_cast(StepGEP->getOperand(1)); + if (!StrideCI || !StrideCI->isOne()) continue; + PtrPHI = &PN; + Base = Init; + PtrStep = StepGEP; + break; + } + if (!PtrPHI) return false; + + // The pointer-PHI must have an LCSSA in the exit (so we can compute + // p_lcssa - base). Find it or create one. + PHINode *PtrLCSSA = nullptr; + for (PHINode &EPN : Exit->phis()) { + if (EPN.getNumIncomingValues() != 1) continue; + if (EPN.getIncomingValue(0) == PtrPHI) { + PtrLCSSA = &EPN; break; + } + } + if (!PtrLCSSA) { + // Create LCSSA for PtrPHI. + IRBuilder<> B(&Exit->front()); + PtrLCSSA = B.CreatePHI(PtrPHI->getType(), 1, "unlsr.p.lcssa"); + PtrLCSSA->addIncoming(PtrPHI, Latch); + } + + // Build replacement value: (i16)(p_lcssa - base) + (K_init + (fromNext ? 1 : 0)) + // For fromNext=true (returning %counter.next): value = K_init + iters + // p_lcssa - base = iters (in bytes, stride 1) → value = K_init + (p_lcssa - base) + // But we want: counter.next at exit = K_init + iters; and p_lcssa - base = iters. + // So replacement = (i16)(p_lcssa - base) + K_init. + // For strLen: K_init = -1; iters at exit = K (where ret = K - 1 + 1 = K) + // Wait let me re-derive. counter init = -1. iter 1 entry: counter = -1. + // iter 1 exit: counter.next = 0. Suppose exit-iter is iter K. Then at + // iter K's icmp-true, counter.next = -1 + K. + // And p_lcssa = base + (K - 1) (since iter K had p.0 = base + K-1). + // So p_lcssa - base = K - 1. + // We want counter.next = K - 1 (because exit-iter is iter K, but counter.next + // was computed before icmp tested 0 - so it's K - 1 (with K iters = K decisions)) + // Hmm, off-by-one is tricky. Let me just test empirically. + + // The "return value type" we'll cast to. + Type *RetTy = Ret->getReturnValue()->getType(); + if (!RetTy->isIntegerTy()) return false; + Instruction *InsertPt = ExitLCSSA ? ExitLCSSA->getNextNode() : Ret; + IRBuilder<> B(InsertPt); + // (p_lcssa - base) as integer. + Value *PLcssaInt = B.CreatePtrToInt(PtrLCSSA, Type::getInt32Ty(Header->getContext()), "unlsr.plcssa.i"); + Value *BaseInt = B.CreatePtrToInt(Base, Type::getInt32Ty(Header->getContext()), "unlsr.base.i"); + Value *Diff = B.CreateSub(PLcssaInt, BaseInt, "unlsr.diff"); + // Truncate to counter type. + Value *DiffI = B.CreateTrunc(Diff, CounterPHI->getType(), "unlsr.diff.trunc"); + // For fromNext (returning %counter.next): replacement = diff + (K_init + 1). + // At exit, counter.next = K_init + iters. + // p_lcssa - base = iters (in bytes; stride 1). Wait but iters is the iter count. + // Let me re-check with concrete example. + // strLen("a\0"): iter 1: p.0 = s, *p='a'!=0, p++, counter=-1, counter.next=0. + // iter 2: p.0 = s+1, *p=0, exit. counter=0, counter.next=1. + // At exit: counter.next = 1. iters before exit-iter's icmp-true = 2. + // p_lcssa = s+1 (the iter-2 entry value). p_lcssa - base = 1. + // counter.next = 1 = K_init + 2 = -1 + 2 = 1. ✓ + // p_lcssa - base = 1. So counter.next = p_lcssa - base + 0. + // (K_init + iters - (iters - (p_lcssa - base))) = K_init + (p_lcssa - base) = K_init + 1. + // Wait: counter.next = K_init + iters; p_lcssa - base = iters - 1. + // So counter.next = K_init + (p_lcssa - base) + 1. + // For K_init = -1: counter.next = -1 + 1 + 1 = 1 if iters=2. ✓ + // So replacement = diff + (K_init + 1). + int64_t Adjust = KInit->getSExtValue() + (fromNext ? 1 : 0); + Value *Result = DiffI; + if (Adjust != 0) { + Result = B.CreateAdd(DiffI, + ConstantInt::get(CounterPHI->getType(), Adjust), + "unlsr.result"); + } + // Cast to return type if different. + if (Result->getType() != RetTy) { + if (CounterPHI->getType()->getIntegerBitWidth() < + RetTy->getIntegerBitWidth()) + Result = B.CreateZExt(Result, RetTy); + else + Result = B.CreateTrunc(Result, RetTy); + } + // Replace the return. If there's an LCSSA PHI, replace it. Otherwise + // replace the direct use in `ret`. + if (ExitLCSSA) { + ExitLCSSA->replaceAllUsesWith(Result); + ExitLCSSA->eraseFromParent(); + } else { + Ret->setOperand(0, Result); + } + + // Erase the counter PHI and its increment. + CounterStep->replaceAllUsesWith(UndefValue::get(CounterPHI->getType())); + CounterPHI->replaceAllUsesWith(UndefValue::get(CounterPHI->getType())); + CounterStep->eraseFromParent(); + CounterPHI->eraseFromParent(); + return true; +} + + +// strcpy-style undo: LSR converts two pointer PHIs (`src.addr.0` and +// `d.0` each stepping by 1) into a single counter PHI (`lsr.iv`) plus +// GEPs `(base, counter)` per iter. On 65816 the counter+GEP form +// each iter does i32 (base + counter) on each pointer — much more +// expensive than just incrementing two i16 pointer PHIs. +// +// Pattern (post-LSR): +// %lsr.iv = phi i32 [0, %entry], [%lsr.iv.next, %latch] +// %scevgep_i = getelementptr i8, ptr %base_i, i32 %lsr.iv (for each base_i) +// ... loads/stores via %scevgep_i ... +// %lsr.iv.next = add i32 %lsr.iv, 1 +// +// Where each %base_i is loop-invariant (typically a function arg). +// +// Rewrite: for each base_i, introduce a pointer PHI that strides by 1 +// per iter. Replace %scevgep_i with the new pointer PHI. If counter +// has no other uses, eliminate it. +bool W65816UnLSR::processCounterToPtrPHIs(Loop *L) { + BasicBlock *Header = L->getHeader(); + BasicBlock *Latch = L->getLoopLatch(); + BasicBlock *Preheader = L->getLoopPreheader(); + if (!Latch || !Preheader) return false; + + // Find an integer counter PHI starting at 0 with step +1. + PHINode *Counter = nullptr; + Value *CounterNext = nullptr; + for (PHINode &PN : Header->phis()) { + if (!PN.getType()->isIntegerTy()) continue; + if (PN.getNumIncomingValues() != 2) continue; + Value *Init = nullptr, *Step = nullptr; + for (unsigned i = 0; i < PN.getNumIncomingValues(); ++i) { + BasicBlock *Pred = PN.getIncomingBlock(i); + if (L->contains(Pred)) Step = PN.getIncomingValue(i); + else Init = PN.getIncomingValue(i); + } + if (!Init || !Step) continue; + auto *InitCI = dyn_cast(Init); + if (!InitCI || !InitCI->isZero()) continue; + auto *StepBO = dyn_cast(Step); + if (!StepBO || StepBO->getOpcode() != Instruction::Add) continue; + Value *Other = nullptr; + if (StepBO->getOperand(0) == &PN) Other = StepBO->getOperand(1); + else if (StepBO->getOperand(1) == &PN) Other = StepBO->getOperand(0); + if (!Other) continue; + auto *StepCI = dyn_cast(Other); + if (!StepCI || !StepCI->isOne()) continue; + Counter = &PN; + CounterNext = StepBO; + break; + } + if (!Counter) return false; + + // Find GEPs `getelementptr i8, %base, %counter` (or %counter.next) + // where base is loop-invariant. Collect them and verify the counter + // has no OTHER uses outside this pattern. + SmallVector GEPs; + for (User *U : Counter->users()) { + if (U == CounterNext) continue; + auto *GEP = dyn_cast(U); + if (!GEP) return false; + if (GEP->getNumIndices() != 1) return false; + if (GEP->getOperand(1) != Counter) return false; + Value *Base = GEP->getPointerOperand(); + // base must be loop-invariant. Instructions inside the loop fail; + // arguments and globals are always invariant. + if (auto *BaseI = dyn_cast(Base)) + if (L->contains(BaseI)) return false; + if (!Base->getType()->isPointerTy()) return false; + // Only handle the i8 element type (byte stride). Other strides + // would need different ptr-PHI step values. + if (!GEP->getSourceElementType()->isIntegerTy(8)) return false; + GEPs.push_back(GEP); + } + // Also accept if CounterNext is used as a GEP index (sometimes LSR + // uses the post-increment value). Walk those too. + for (User *U : CounterNext->users()) { + if (U == Counter) continue; + auto *GEP = dyn_cast(U); + if (GEP) { + // Bail if CounterNext is used as a GEP index — we'd need to add + // a +1 offset to the new pointer PHI to match. Keep this simple + // for now: only handle uses of Counter, not CounterNext. + if (GEP->getNumIndices() == 1 && GEP->getOperand(1) == CounterNext) + return false; + } + // Allow icmp / branch / other non-GEP uses of CounterNext — those + // are the loop's exit test, fine to leave alone. + } + if (GEPs.empty()) return false; + + // For each unique base, build a pointer PHI. + LLVMContext &Ctx = Header->getContext(); + Type *I8 = Type::getInt8Ty(Ctx); + DenseMap BasePhis; + for (GetElementPtrInst *GEP : GEPs) { + Value *Base = GEP->getPointerOperand(); + if (BasePhis.count(Base)) continue; + IRBuilder<> B(&Header->front()); + PHINode *PtrPHI = B.CreatePHI(Base->getType(), 2, "unlsr.ptr"); + PtrPHI->addIncoming(Base, Preheader); + // Build the step GEP in the latch (just before terminator). + IRBuilder<> BL(Latch->getTerminator()); + Value *PtrNext = BL.CreateGEP(I8, PtrPHI, + ConstantInt::get(Type::getInt16Ty(Ctx), 1), + "unlsr.ptr.next"); + PtrPHI->addIncoming(PtrNext, Latch); + BasePhis[Base] = PtrPHI; + } + + // Replace each GEP's uses with the corresponding pointer PHI. + for (GetElementPtrInst *GEP : GEPs) { + GEP->replaceAllUsesWith(BasePhis[GEP->getPointerOperand()]); + } + // Erase the now-dead GEPs. + for (GetElementPtrInst *GEP : GEPs) { + if (GEP->use_empty()) GEP->eraseFromParent(); + } + + // If counter has no other uses (besides CounterNext and the latch + // incoming), eliminate it. CounterNext might still be used by the + // exit test — leave that alone. + bool counterDead = true; + for (User *U : Counter->users()) { + if (U == CounterNext) continue; + counterDead = false; + break; + } + if (counterDead) { + // CounterNext might be used by other PHIs / icmp. Don't erase if so. + bool counterNextHasOtherUses = false; + for (User *U : CounterNext->users()) { + if (U == Counter) continue; + counterNextHasOtherUses = true; + break; + } + if (!counterNextHasOtherUses) { + Type *IntT = Counter->getType(); + cast(CounterNext)->replaceAllUsesWith( + UndefValue::get(IntT)); + Counter->replaceAllUsesWith(UndefValue::get(IntT)); + cast(CounterNext)->eraseFromParent(); + Counter->eraseFromParent(); + } + } + return true; +} + bool W65816UnLSR::processLoop(Loop *L) { BasicBlock *Header = L->getHeader(); BasicBlock *Latch = L->getLoopLatch(); diff --git a/tests/lua/build/lapi.o b/tests/lua/build/lapi.o index 5d5029c428e34fd306dfd35aeb68f95c3f4a0722..d29d349930d1e65321d33a045faf1a927e7eba4e 100644 GIT binary patch delta 2351 zcmY*ZeN0v78Gqk%INVUW;gbGFC=3pd4KQo z{GR81-sgGVC+CyX+U0k(qZ!(j-9v$(C;s$PqFspoYn`9>k9Xc46mEs*rgWEhpZ2!I zh}1zLY`y=_wsdBVOiqp|S7%lX+3@6K$>d~AjIw;4Jt@{iKHKX^-K#iSbamL{=qWXx zNDRY~HHM?ln`g_@Lb$rEyOOT*oTCrqr-XUiiPt_{G?2gS{!DuS=UksHU4yOgy1ffK zbomeiq4jR$fXv+f^om>x(f=PJ zl_64XzY5_;#gc`I$;va?_Avy#86wF|!Y`LRQ{}OJGn(#m;v!A=vgx|xi=mOJd1f?y zj^oqkD2_e%sGtm}W{9uF`SLn?jZZz?E_RqDc^xlumlnw!G$#gdV?n$-uyomMIUlzQ zgTYjFJhgM2-HptE?RWhg;YhdC%zB*+TrKirWl?nWRQ_03ROSmf0cMxfKaL~}7Fkj` zrAJSV7``hC#M%kWF~RorkHy4v;zz~L>pX%ti`UBe?xo`2Y3`1--MYN)POMLtawq&7 zTI6n=+|Z}}TOeoSDH(;4jivI5>o0p($`FQsQYz2FTb?KTu)I877Py=iAbmLWuh3?>% z8&W<%=hnQ?0}>x_Ma>pM$yd4bpA-1q=2HBZ+`pcdAGnXUTAF+ee^pRkK|xh=>|>g2 zE+a*V-=nH3IYBXhoo1AL2R&7Pk@v8%I*-^^ofmtL?8nMuz7Y4^KUF8|SwmDS6qO}} zlCN+@Q6A$yI?X?eiMl&!J6M;=6=eyb$N8m zqxEy=J)t2|TDB1X*qd3!;EJxkp#=m*BvyC{o=ae>9ft;rG+Qpxu zsp*tl2>;$vxeH-pD~9(j;0S%OHz?P^yU&vEA+*oZ#wxLSpD8QRMk)h?L_e<5@W;*g z7Y#o|X0xT;dFyxnXXYxt_W@lkV7K7;$smi!P2`z=|H<-`E0h#lyO z;Lv_cySN3{_nXoS*<$f8mrZ;P8;KjRr^SlSNfLrH{p*&1agCF69-p=ZrG-ay=!U=5 z(!QCC)vc!d0m7{oOFBk;9>X+zpN!iy?1s0^lKBX=@vd#y+-4eQ{cIXK+k*5Tr13Yn zO62ns(~#M2u@NQ2KI|m!!^w8b_$-z0hL75V+VLuU)o#jbNU+tR<-`G05no0RaV>_3 z+wmE(9Y_M;W)f)oAK4zl_bimS%*P{J^DKB7<%H>*&Q?W5Y>9VwMYw<>x zX>7|8B7}Fkg6z?yE=wN8{Rk#>TQUjDyVf=1OMA^Pwfr4tdZg3`l~5Cv%N32F~s!FxTXd=4W$yt*Ebsk{LHK}+js!0Lmh z+=4KbyA61YNV(SFF(uH@q!x6i{Er>Pbbhg6#~ z4_h)CCB!7`B-Y|2F$b3pb5OVAtHUOp5{_8fC)=^&h^bAiMD-C<#-oSa_p9+fxy!HP zI=ObpUQ4_70&;pyZR~ZF^_sF5dwMNdj5EEKaima)>-e-c$dP(PwjTaIOD@BzK1;h( ef>--YxdX>Y0mDRrTQvNt5iv*kJ3;7Z@_zx=J=Bl@ delta 2759 zcmY+G4Nw)=702)0eV6BB^W^cB2l6RTc0~jfwW%pgby5+G0>-GZf`d{(Xd$+-Z4{A@ z^`Rn9oE)8M8kJ@xtyDTX+h&?p9s6OTRt-8fwTX$4h9;vi+BRmI87uwYeI(JHIp?1H z+jGx7_w2cE-k%RDXL^-g=}P&AV;KRruY<9^E5V_@%fa^#GuAuKUh2NamHsY!x+m4s zI-Vtg1_%32n%s&xJ32bZu)vBjMI?Cr=xE94Xk=t?(2BX4HOdw^PnN<=Z{MKm1s0KE z&ncz`qKy$OH9eL{sP>owk==cR)ox2nm|*f=#%vKBv^lop{oimW)FXqwLHiFes_MFf zz3tQSyIrbuTQQ+pag5{1hrO){ENL%dCKp>;24ifa>FyoJY_}=Sy4f9OiL-(YG7IsL zoL?^Y+n9`VP7|i_lEzCK;ZR|!U!BoZEl)zdkC|?hf03u#bUS&fk&))(swEz-K&+*z zu~_z11)@Qs!z2osR7aU^i&v`@ncYsA@jm)#c6kOiL4t0}D|0h7XXYFdmBMMQQPJ(ElgA>fS=iFP7Y%$O9d znVtteh{uYelLh`omIvkcSlYwY_gfy-FL9))$wgDlc#!xoiIvrlMU~ZRk8FwcPQ}S> zxoLRDe4cA(&1{I_skFN&5J-{Pqy#V9n(1_gnPexS)15kn+c<;XE=r3?lzxdcTJ)4Q z$(n=~@%LROKUK^(^bAw$FJWz_)`j-h&hj>_JL*)IC)8&!Gu(J|cz#BzygIR#hQ`5l z!L z3ZGd%y%aN71Y=KOtQfPaFxHLP-^ExD5%BpLR)60<{Y*ew#8^(V2cu^aZ{HGVbo zG^R@>%4AI1Ll7724=}zDk-UIHHUG$Z4ky%|z$AYUw7H^$dv{J{e}2wN>j96X^fx&80D7bEy}3N__HpJ)m|4>tu8ufs!w zxE@C`7`<`@?CX^Bte;=EXFdC-N6B7C5gQID)0WXI8%mY*<@DKx1L(~?8_W0=8i5|7 zST4Em5^C0MJ@Sgpfe0{e&tz(&CCIPBw~PhmB5Kd6hp z;!a#}U_qx(nN~xkow|4#ZGXmr-GIe4bO5jcEgR?5{2E|Y4SfQ*c?x6m95{8W5A`kF zYKT8&<4=jhHi6xv5Lj^zV@I5b=ePQlwYBu#R$Y7w__+gq0+h#MC>*Tet%g6sqm0gB- z6>OiwUh48Gt_J!Q9LsR8&N-_;225_C`+$iBjP0f2jyNjZ5v6>mfl7Di;uzq|&hqXZ z@*C~nVTdJ#xSEfMvjEy=wJ+jk>HcZ)Rh_{RI zL*+PDfZd};u+zniZF1NVu;X+BZ0-X5>Nsoffn6kTk0JgA)=1Gkv9z$q$5&BhkD*Ln ON1Z)7ucCn-|NjAk=Q7p+ diff --git a/tests/lua/build/lauxlib.o b/tests/lua/build/lauxlib.o index c0a87e98174e4c6c882f0627b8e872b14059b963..4f38c39016b7e4b36751c79233d36aa8c8bc56ba 100644 GIT binary patch delta 145 zcmX>zm+{P8#tji%+zS{O77I#bGBGquZ%*ba5lZG`ke;!Cg<-Q$Gy4KIAk}(dF+1x8 zj+G1yt(P=fuY6zt>0qBMwpa|Ti+AaT$-Ik&Br;hTn%RMhCbKVQ2TO2+INXbcq@aL0h)Aa>6KO15}ACPtz>5jGNx?4s#nj&n6x?6vRo7Z8A2}A delta 145 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 P40;*OU(coUJInqLgp0>7 delta 7850 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 Ang9R* diff --git a/tests/lua/build/ldo.o b/tests/lua/build/ldo.o index 45b9e1ef1decfb01f35b6c82c4e4ea3f4ced8c74..271bbc212b1413c4a7ab83048caefb8eefbf28cb 100644 GIT binary patch delta 1224 zcmYjQZ)jUp6hHSRFKPOCruOaay|m4iCblmzjj^_|t!am|R%Y8YZLwHCtY50I;GZEl z_el%hMOm55?WnD+W0l)4mC>me#}uYckWrAWApIaHgazwB_t7a>iRUE|c6sM_&i$S9 z&hMW4ct5PMnU0Cx;?uejWhyYKn0tge6_I#S} zr%Z~c+)Nwrv}nh)NZJJj_>i#hsPB?$%5G{E^Pg&_R^8mB7t-9K_k&b$&A$;PdOr^k z9j0zoxiD?oNt8Art_n+@X^1K8EPm0L^bL@>9KfB%2vgCog%>m`bM-vJXldboY4D)* zlQ+2`J=~N!*QLfa5$rGPJShBSO&D(I7iL+@+J!9ezIA|4L|?JASiB{cSDRs}R7+&s zNk7EQrWYEhCcXu45fQQrao`%)Nl))`&qMu5$0Mx%GSNaUd+6BuD0d&B{+@tJV|8Ik zvshOCtqn6agoFAPJ1h13zVYd+4IpC0lISSjS_k>lp3y)PQLb1kvEeG)v(NA8Gpe%& zTv2z>0QIM<|D!@TsuwC1+FED`9qB%+l_{Cx0cpus+mEoSibeg5YQLT6oXXm8Bp&g# zE)v^{FUH4=klQ+xs6cJj=phls&G>W8mQc}h4-~NrcU_$*_9mY6nQpm>Zze*jK@|qB zB+~cS<__F5_nky1Ym<8({7qp|-0eCp-%cqE&vj}NA1bK$PtO1=Vy5>d+mveNG-K29 zgGaeHH0%Kw1ORUU;BoQ?$W)4lu{&!m^e})lnI}m!ts=#4{jE9%)zrWycqbgwGb2lx*NHhrLjSW%6npmqoFo4c znM$!+^RZjgOF-*8dHAWnyzCvE89T1r?!y~n6YM1nkLQ)$etczog7xFo@jRPFJ(p)! z@Nh24rtxGhrffZi8@WyfxSey@3jRyjfgKYLJA^sHn|O?H139p!EUeUqK+2&N_-wv97{%lO8mqyE@Mp9$9| zV@hcRZ&1lB{z=JR3{N@iD2@=$;>%Nxdf^fJCGpynffuKm*wc8GGMDjJ!V{=ZJNA_x RfQP*RbRp0}Mj_C}!+&@(PGbN7 delta 1249 zcmY*WUuauZ7(eIUoTRtmlC5{wo2*UO{ISV3jj`CS?XuSHk3*BS>7+hPusHJ4h_VM6 z0}%@z0=7k43zktBn3V2{l4%1 z&Ub#l@0?p%q<0qS=UrMy{&MsZ^Eh+dhE+DT*9jIAJRsJLYxU(o^FY0^bCC4n(}7RTxQ|d)-LJ?pFcd~6L#H?32Wz0u1kvt zq>kCc6deuoarhyDYUz62?Ag`Saro7cUjh?UpHv*icaw9q1N?#LP2lyy6@ z;Vm}W>C*?C`sEEZg@ZRYP#gcnMvYs-EY)iGX@Mh5Foad_Ov^Mkq$S^qOjA=hsAp~I ztwyI9?S#H$mp448jNpxA-fCCU?QV@UE+2nI#Nlf4Xj@1y2&tK(!O~yKCk`?9px3ES z0`IyZW@Cp9pSYQ*dI;nH4}s(9mZF;vaog>to$`10p+@7d)^pNQuN4y^J;p=AZZydw zX^qmjoP7R01~*?Eq!pljcj=nE*Y_EvMR{yD_k<>OLiQ3uJO&}7m`5-e)|2qh9%tqt zMHWL(A&u)xtX1bc=C7Oe66TA|`U>Xj&H4w-%NR= z|5JaV5eeB78oefsksBJd;NIu~)80nN3v8w`fE>batN`VerfO83yFhhBq7{-oA12=n=I zx&V*z1?`0)*mHQCz5}y|3-lD+N8A8+EJcg(`dCc!Wa0g>Zn_=Lk0s~|+(O(9PY^$V z(0GEb!#>0nC?TfdG~&;5gkU*ba#E;=k_FexjRx3d^`T4UZ5PVf&E;4m*VS6C6YQ T5M~h{!)3&)a3664=xffuzj$2T diff --git a/tests/lua/build/lfunc.o b/tests/lua/build/lfunc.o index 781c16e2ed907da39e30f113077d4595f24ca3c1..6fadc2cb85d650c3a3f5d7561a7db4b16ed820a3 100644 GIT binary patch delta 1281 zcma)5L1@%K6rChy(azwF<{PY}X@1Qi)X<(2Qfs%z+U<~8AsQhLR_G^$+(`yC7O39J z5N51>WchHV!K}ZR=<#b=#8{w8Ob9y$1~ZC9>aj9-OqpvkeQpa8;|$p{x8( zpPTQ>>x68O`}nFfLgfw#O``^rzn*H7@np~fGo%9d;f;!5xJf+$Hj^Zq`|u{u)U(@p zsxo6+!Z)fvsc>Ubr$+L0g37Ga1#U4}vbZlnRTD)pzDBSpCWkm%$k1Nvl&r5YC1lcE zV|w+RU-RorB4i>Ll?_o?X?ngv^*A8)B2_vyQ8m`MOOCUAlbFhDVM-T~0#mU{^x=(y zRIvp{GIib+=5^W;SN}ne;#>-E{tw3XC_+mk3~M)1B2?uq z?@P00q9kp~I_0|`?8!Z_SSSjCud3KKMam~8O68=ehYtjLnny*wTKg%0n*eaFd&Q;} zieaT<>=AoE+Wj1+H$f>)P~1&0)tg|Pe|eH|K)Dmy!qy03gCWk|UUa@Rx8Bs>3J@Es z!W4{|kuU@6=Bzv+5HemLvv!0_HT=g)D*oVD$F+O@!Osr&5^@~Fcm21z&L6tY!(u1q zV*OG6iYPAU;k$iXoHpUQQ^ov?&VYE&gjY@=T!qh0MSN{SrVxm~MHs?u(}c@~K&Zmq zLPcD%UttO6%NKynCI4%Z)oUwowi delta 1438 zcmah}Pe>F|82@Ibaom}meY?)i{&6)|T~=Mh>JW&91VN5Lx3Wug$cqcnv4au=J(Q3T z<3V{a73_zxVrn?1!PR z#}>2F^LyPJZWc02)O=K-(p-h-bUjs!110(@K(SgKuT~u%b8zF};OQO!nDz%H^VHaF z0dAH)am#sJ;a2TOPD-g_7<0^1%>&?hMmTA2r(L|Cb#ZNWlN+;Jn9*y2t?UCfBZb|Z zr-}9E>+D;A_i!6e<)}JBLv6cUkqjaxA_(9i zV7`lr2xlti`v(K{u4Cxe5(=c_`XTCp;`kfEk2clH))o( ze=lthB7qk9flW-C)qPNj<3^0@IzVw$-st*|xImDbsb$c(xm z0o*CCMZQayZs8w@62cFT9enrJX$(=~J`7`GU5i;hux^*@_`-qp)AFzAWm!Jn#wM(r zG7$F8Dq#H|R}Wi%E@8CCb`lo55|7Fk3A+)`%fkx0kJEL+USi0U3b5ga{KSyK zD2v#6=`1^G_sLUHcGb?SZY#iwAF*sl<&GG8hF~}HTxTEcUinOn{YK!k0dUQaI-Q70 r9=nj}Q_qF>a^FSl1$&t2lez_Pq!=@RND&C) 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 UlW@0iaB%?ye@^h#7T7)UPaIJ!w*UYD delta 4703 zcmZWr4RBP|6}~SoyBiWh5|U-JS(eRa*}QBL2oOThG(;Ma-;hD%H-BOTj0^%Y7=glC zt`RVb-~o|A{`#a4DTuy0!dMH6N)b_LtJJ9|;tzJLzk}6wg!DW6?uP9&Gbi77zjN+6 z=iPVTz5D4g?Z|O$W4^Zdx!`L_Ax~~wl91U}w&jr-rkgU%jJ!MRI&V;wE-Q{Y_7HP%{B_9@UD9cEbXpko=qXbr11GH9jC zfaRA)YL^gg-QDB6yHitT*fhS3bc+eGzX%?v8uO}IPL)26ES6PJs-XB%lLWZS*ehseNH!OXYA-z|+yRTgBHpAo0 zFg0a1xO`mX6R&kFvrFsaMYM;by;xBX-QRb%!;3hNb-u4pb4vC|`YF4x@YmL_$BPF} zB|orHn8Db>M%fvaVJj#hID}kft)iQA8tKiPEZ0iY&{s->THGPWa`5GJF{dJ<-3(B> z8Hzdl$>8+=PI4gJ=3jb#r!qS6Pm}7eMIkdmuysTO?M78P>Mw}!c+qMj1_3)#eC6RpmD zqNKrUkUo304#y&l*n-XCh*{E$cHFT%Gprd@jUCgd(|fNz)tdTvp3gajl_?a= z8>!b@_0*U*$XUly9X*y8$(hJ>q6}eEWycbYx5m?3d9$5k*)i5C^-Xppb7gB~{$9-m z(R7fDjDjNtX|YaNveKkxxukAtly2(eFw-f`>_;w33mww5vvhdi^J8}4J?t>Uxoy3L z#9PBI-EM8ih7R!v3$e}G7SYAG*b&%V<9>VG^c4spR;=JDP9e8)nXR-hJlnC!44v3S z&cfmP7HbPt7Y3ZfPNF*s>q}cvrj_Rmh?kjT&9TeqL1ed!*{e<$3Ii$jT1zkOEb>vn zm=>93%}QKvdxOs43N!HS#W(0QEbAwe76w%dglu4?f&OZAI_sI%)7+v! zp1tHfam7N~?kQpqobNo%VW;V#;!fWwrl(FNW68O9`<0wz z@g$X&{1AQJ4C$}SkQwec8+$+Qy=SG5-R?{Ik;|{<%M%DV5ev9zW_MgNL%SW~QvTM9 zujcdC#)o64bjRl4%nZpi)5pnjh4dj=x|v2k(}zRj6&#MQV9$iiY;v0c-H-P~yGu)) z$9V2BI#;?W^0M`E;#;wEzr_BR5;oCM>nL>&s&`1!N0L4oBz2rM^vwt_tsZ=*BZ`ir zbb0Vf$4b+yucY~9BXOX3aiBa6w$Sw9c=))??OecV7tqgTYvNz=gF}YLzvA167xfw} zEy8d>Vs(ip#8Qm9d!E)wx_L^DxUaT{A2|hlP9VYEB4>_g!rBb;hqWLp1~~aiAt+d`mbMJ z(r0=TMgh~C+v-P&K&uZ)Jl9>RxaRz(r{|iJzDTl=6{cUWfbQcyiygP;OTu;a? z7vZHWqV^HX^vA5nux;lLTx$kTtUWByw7ugW<)wZ!wuOALH`i%((u&Id&h_kAPft|_ zogGX&=tO0acGmi5<*)Q4XFA#G7{gQhVnK5XDM$bovZak+1m#N^%PXW z-%xPQa|>`gj0=B}EX0L`7>91h^a8qI9J3iQou@^`v;ya-m?OZ|N?!xqpo?g% z*k%m2DaS70Gm7(s-^27mJLyMC{{;B8;@<;*RQxJ11�n^aiHFxVZ;_Q($_)&hxd> zy}hDB{J@SZ+i|VOAw-4a`s&^T&PneDE>}DXd{FVtz=vR5tkWsP#svLwrT-H8UZr;d z_pu(u1RaiZ%EA1*1bz)%&$gQ@fsdOg1CCJqM&L*o7hZ?hn-cgPDux@vMJ;r+Ig@*w%Vev#mm7WS*r1%rS`(W{yElOVu+{L=b&iRI| zN5z{Ue}eH7RAMt;u^nPKHe@$=JW)Bu{Ph2ZcB|skfw#eUt|L{5a?Ix#&Qk$no%8Pj zk3ZO3D&{QkJimXQ@OKQ}hw+3G;KvDELt>8M0y>OixNtwE=K*t-ZopTp^ufT=1brg7 zKG1&p=}O-i1$hL<1vUaVC9Ca_!SIhgB&an4j&3XGfP zxtT!LIi@cx8h3;-i1S~7>xSKF9rGfa&rmVTfsHUu)C60mIP2{&&hrUY@OMf-3_PUt zuX+pd7p0$1!}tHLa@4_*4&$WNz$zFgVtu^QnNL*u5#V&C&j!v^`d7eJO5X{5Dnaj3 zI?p{E<26F?gcp^A`3DL7KZ;)i{tV-WX2Fuv6}SB3Yc(y6=1ge!dT~VN@Ij03H5b^A z4_fd!^xXtcbSu0Am6s1_KCs!FhBIrX(i?%ZmA)6aQt8as!s2`Qq|#3V|E&1mfS)S< z1@LoNJU?!YhMqwHjc|)0U=YSZXMl#%OMtjld*WLZ7ie@#0zciu>Ai{XY4hmdq%v(f zU6|xaD#@mQO)6l>tGip9XLZ!oCMV@&(VJ85(>|opw{A~L&9Xkc^+PS1ii7uD#`O=Q zFUAg>Q+J{%zv4FlD`3gcnO7=(0rvAfO1~GlTJbf&jf!su?o|9Yz(a~Z4?LR1*AJ2& z!{9aLI0JlF@%Mq}Vcbvv_(1~yO!4f#LS(==5A!S-#|!L|p-Qg+)+k;JoS^vRzBqm+ zVZakEBjIfce3c5?09+4?zxytw9|RtN@!S%u)@zDi27V6XhFDL5F@FPE4tP9I1l*CS z95Yo=gEfA7TC(;TO`F}GR5Xg-o;^9KcMT0_n4C1EhVE&YtR1J98|sr%ZlXSoleH_< z)L6p5VIFQQNJ^=tLyd*nB6_#c(C(tE_#dWllcD`YbxnrjzyKj0rqRvW^hi^tb|>wC zRuK>)k4`m(9P1_s@icu0R$m~*{js>x=1lD*RW}>jOq$zlB$ZC04b6p)KjI8sK}VZI p+8^iw)+wvDE>7)j15S`Fz_+KWL-6}{ck@4vO49F_n8 diff --git a/tests/lua/build/llex.o b/tests/lua/build/llex.o index 54eef2ad3180fae78ec38546334f68f6404f9dd5..7f75882eb3c61f579d4c34abf68cd67831f38e4c 100644 GIT binary patch delta 554 zcmW;HOK1~O6b9gPCK;OtX?i=E&LojEQOr<_NOp>=qDVtt6}stC3WY3n;cL}!K@b!S zKT_RD%mpRjB68gb6(5Kw2vX=m-IcD~>B5C5)Dsuy`{y2h=5hx^zCGl-W&YH!d{xs_ zysu+sR=aiD)UKIDnwx2zF>Wj)$Eg&qaGj^^Yu<6@lVR5(oi&HUZi#eyk_D2kWRlr<{RR>0`2eR>& zO|WcyTR66n;%(bI`HFc9OSNEOKtz{ioRH}6pM!&Y^6kcm#*z;w`#GY=l22@}ww325 z@{Ozf4*kX=Z{ua-C=>P?5s#52r;evPu*E^B(<1B`q xDj&f|S)IdAv4Z?c#P6{renD3}kG^Q}LTqAhB?_OPAexbfvphDCiObB$`~#=6ol*b* delta 615 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 diff --git a/tests/lua/build/lstate.o b/tests/lua/build/lstate.o index 1b5e97878fcd7e5454577540a9280096c88050db..5d47fa882cb5d3cb63372216ddbbc87946c19fc5 100644 GIT binary patch delta 470 zcmYjMO(;ZB6h8Nj*EH|P9W%_l`^Li0;zcQnjVLR>NtBJU)HKCTDP?s{qmfd_&qkWM z5z0c36$_Ta&PpjMD~(c?^qe=7a=Q1sU+0|fobO)sZ1rq5vDLHYHj}wHW@hJv(orb; zJuJwQkC!;*q4}$~N%E610E7OyQ?BIhgS?(l%&8E(k_~Kyu%d zv62S#n2H-lsCjP-V6+la&>T^jV@Nx+HLQ|!aL@k0C(HD=YlpPD0t3*%hJfsbvFDfL zUZnqmXe3_AR7!u`qxOhi&Ci6=RFyCM<*t z?K^?{PCF~$t<%aDvFv#IokidO=k$^9P7Q!80kuL6-S8{F%t?N2 delta 496 zcmYjMJ4ho@6uoc45R%O7OBmyP68|eh0)kCI5L=0EAuia2RDKWY}p#gx>yejN(CT)LEY>3UOzYA-BbRsp=Q2zwF19~IaH$gdyDL@NNy&kMCIB9fCK zTr(8NAh|X16$B?ErE5#CYst}Q$_)ilsuFaTR z=kbC5&zQ7b_5*tei#SGjhTjRdahLE0&uv$I;s8^4WgD1w;%pc@9GC6k5aB3(bIcdy CR*LZe diff --git a/tests/lua/build/lstring.o b/tests/lua/build/lstring.o index baa30d75821f5e696f460303cce11a1a39ca1924..7b41d5848229fa62f8a681582d7e327b0cf50c35 100644 GIT binary patch delta 1901 zcmY*ZU1%It6uvXF|J&{Ex|z;QrsHI~Y_@BNG33XPhBa=8Y>U3Ms1LPNSP)jhClM@# z4Y??qpeEiIAAD%JMr|ngGgw4Kl2nigmbFjX2encV4U|$9S|41$Gdqjxz`5VI=brz2 z*rnn{Z*9nacRvfh$>2Q9GE8AR4}5TB=C|qfBSXih&N1dsRXS`}Wo@?1n4H}_%9gmd z!lTmL?X*4$l+n}$#+seZ(M~6o;;xMD!R1)+@d@c_6Qsk9Bi;4w(mn3rARnj5<6QGy zo|NAD9VgAlq^FH>50+w5c{DLf7Ngt}uPO(hwkWGB(`Hjy;_1t-^wuadPs=2Nc}O25 zPWL4qLE;hep~Mu+* zIs`7u!lv0MqqA(omhQ`Kv#B!fZnSal1l;l+p7*UyG-~)ZGUtW8B3x+;N9w{t&qhL; zhi|dv2F9B-n+e8CR7i}&>%xlxFX=cCuT=$hHLAkcE#g$jKWOc8?@PPDAbKS?wXb#UH25GcvcLS>3t2`bX z8dB$$EN~m8Q9Dkt5W`OB+Ju;n3=R2NYziO8tQzCo zSul{ug0BrbXhPPx)_Lii|_!&z_JYoTUEdf?Vu+O zfgLfM5p)q~bYI76fTJ&rmwI$$0W0VTU7U%Z5bgNAu`}# zNyvQ2PXkXv$cFeSg^7puMO$R^VW{_kA4ABu27DMu_KT1O2VAA3;JFzDhg5dXXZj{sE&1$q(cR3CpMw0R4- z7U~BhVKcC&X1)w@vS+|0h?efgUj?U_ZvtP3^lVaJgcsK${`325ih3g>KFJ=ZeU0S~sW(#M zzT9w3hbLC|321&!i!-@lMHA<9W%Zqm_$D{3zMmAgp&JlZzDxmX`C)SalWQY4>Soj< I(y$!lUvg`-^8f$< delta 2136 zcmZuwTWB0r7(O$T*=shF&ARSPr_@u7V()(43<^3oR(LB$(YR0Kr?*YBU1)TVggpZ`1G`Okkl z|GeQXmR=~@j~gsl*9YHWmSGAzf9-3Ptv}8ltrYLC9%sz2mOE@kWvlEUV{&e3o-K0s z2-l^%(rLdPkb3GAW35hSzSBvixF_|CxKa;RS!H~O^t2sBr?^9woB4Jy+rcZbxblB)XW(QebnAw0r@>5vaYeV%NKBHuNp6d~m5qum zo>81T+%;F}^%+j!;sp2Tg3B#G$z7Sgl{ zTfWV+zP02#yg>0~R=7t*+d zWv(1vmf>XZjBH#iGfWIRU1kYhl^LxH7MotoOa?O(Y>F6{48|qc+{i1~RKm?7pTTB^ zXAmEQRM#3SESl3symkpkSF33D8&xQSQN;y6) z^V+mHrWFlpje&XQlhQGplj42tDh*-81#O`{;ZJPicF75Q0;d$lI<7K5%ky+G3(pn` zwB!~29G4b`3iPFZj)55qnNe9Vo1>Ie(*mUTxBLRPeG8ne6~c$DoAFkbfoX^{T~qE5 zG9FrGCzqwx&+y81ZZDZFgK_%^l__HSPNgC0`qQaKO%`er--cM#t#(7&7=aAZMH{~^ z3hR8)H~bvW2ZNLKv)j0Z5-pjBnc?So&Np}(w)Ak)x^hk&%n4}J9FBHLI+&A?kvX$z zq2cMKBXjVUL>O^ftZx^bh9?G2Y>|T@Rqe@w@FWuHVw6tM2Ma$Pu)^TSX$23T6M5+f zOS~StHF%nTVw+-RYJXYu$G2n~iBk&0-++{HC;vfR+!HTNQvEe))udaKH!sP()U+qD zRu~KWi=R!WvC5jQKE_AL--tLD-=)m@o%nz%`crlFCQTej-JtH%#pzW2-mMyA^KjFp zGPVbLH$(?^6vkcw)?)ZzeFPz!&!9hnkj*aG^g*;Z2rL_TjqfKuL9BQ-eRca3%pZu3 zpNHlUa!2@3#FNd>5&s+XFA={0EpSHmFG7w%D9rERUyU%?^r4isbRR+BF6E{qddpAvXz4J(pTOkwZ|J`uYevIJfcQDxe>pR&sAqe`mp!-8yk2MYt7p^Vc4IL1 z6bvxB2f@7CElwJP$_4SMF{D1+BmOW3)hAM7Q}3Yu9W_gQ)sqwZdwa>zf!;y$2av1a Nkw2qa5t{Wv{spT{=9~Zk diff --git a/tests/lua/build/lstrlib.o b/tests/lua/build/lstrlib.o index 1c0a3bc4e852533517fdde478c1ff0ab8039a9fc..1acae5b4e17d100a5fefff08bdbd70c2be2b8df5 100644 GIT binary patch delta 1272 zcmeH`&r1|x7{}jt*JW9jZ5zg6)>&89Mx8u(@Zc$=lX+>OiCmDbqz*=X-`Qa@=uc?i{XU=Pd7o$J{l3Ev zjf5sfLd7iKeXssSEly$yhIAB8n*DB00#IOjshZ$YjJ45oy?(Fr*naXm6&z zU7O@g=u#_%6~u~6O~s^HimKeGUInRMpzdH&DyPbO=_uL)hkW)TJt7j zZld`Y+s2UTJ5s$46B!hxK^ZTzERmKbrKSEkOWKnximhCjD4Q~Fi8v0Lv_#T1y=iRK zxHZD`jw9nG546g;G?^@=b+uzw3MLBrB7bwNSCnb{{sp%erG7 zGn}tduJZ<8b<3U4jQlIk*eJeSB+b|z#LHM!;Bmy;KCAi^mg-UcZ~giQ#1)^vB7XDv zyNc*jzte`e1uL9G5l>F>!3v+_Y?s$`0mUgSH871h46Td>ENUBcIeI)PcBldeJ kGURZg7U*{Bf;Lb;6jq=|X#rYI>(Bwp3_JWabqw$P4F~x_5dZ)H delta 1164 zcmd^;&r1|x7{}jte~<>lv<&0uuB&U4P98c4c`3q6;z@|8qhVQ)pmqpPmAm=wQX!)7 z)ed1L3>~CHEK?Achm;~LWDA1I0txn1f|o!cs_(4B=%N3hh4=G(p7(v`JGZx8@ zMJ6-yaItBn9*-LLVypgmde58?{X(c}R;4L(R0!9wb!E6#)WDG4RHe^Jp%Si+cbOWb zVvTrfw`FxVs*Kt`jdSrnb5;n?X#FGh3tqy}+I~L58~lr{qqY5xP-)J%2GW%-nN%s) zLds2i%RpbuaI;M+i`$l~C6!hZu9;M(XQ{;YQJq((EI)_gYD<)ZLg|yjkF2}qQo=v6 zwtLI(OM`Pqc|>0y3)n4ccz4}8^&pUo!aidVRDIm&OcHR6y>Sz8v-nRVn<43dkO zCU0Va97UP@0xjprVYHKz=*c>2Y*^A$~7WoOy*Bu!{ zH(7__ir*z?@sbo+C(pqgb>sk!kyE%pKE^nC5>LoAd?g1ESB}i%5Lu1W%8C3M!iZ{- xckqDCk4so#vx=WQKY?`Kk<;iT_hFE1!8Car3*;%3$r@+{M=G?F&(Txp_zP_YDNq0a diff --git a/tests/lua/build/ltable.o b/tests/lua/build/ltable.o index 25dae50985d4ae9276315adce4ea00bc26e74c0e..9e7a76d6239cc4e1d991579ad4dad11b7d7cd0f2 100644 GIT binary patch delta 1884 zcmYjPZEO@(6uoa}SGHfYOI>FB#dcZRr4njkX=+oqb_=d;4UJMn6C@46s4Gf~8dD&+ zO@~_GPbrrm7;C^0V@phckr0h0AcVAuAwUd?F-`CbZAwgy)mVR6&)t1hCUeg@@4S2O zd-L9m4XDot)S+_q$xx`MqLE6DSy`tpTI#KfBXe_>|Ad#E#C7T;8aHTK*iH;}267U` z#a7ITSw1H*)b~QTIgl(RtKkHZ)6h!2mU-DYlumAGvE?1L6P&9yq%uSQs9m&_h<5KD zC*9NxBo~oYFAeI)bLLkHB)w$SiCKrP8Acb(nVIS__bEP?i6(tsEy| z<&7w^{C583952-JX&NE2@@?PcJf2VsRWsjJkwVLCOTTvER29u-%foS(AG1%pYJmG) z5#SkDdjXa~x4ghMpJm!P+X{K1QH`mX5d-cqDh(v?Nu!W280}SwK+;W?3Cqr5(@t0` z`)}JV{ojumgrj`>woK&lN*qVE+eCfB{kTf-VRywERN|w2j)`x`mz6kSo9x5Fax!5j z3@?#sW}E3=b~8`8SEGE1Cj@NrJXrpJ!Xhjt=a6M*wb(}g#TP$n2qYVwK~L1xQD%p5 zTtT}r8z+;Tn`^~Qmtbd3$O<_@D>y?mlTCJL)Go|ilT~)mD$;In)Na;p$-x%8Ed7QZ zzxPOiH~oXiar_YoI%d%`Mz(x!SpJBxv#Yer#is*p&M!;8TA;f4eC428=R6vjQmT$u zRc%+RdARB^Rl+}24W!6LWXLjjil9A+T0{`xDj}+bAAvT)=@hDgp3m6~?M8GWwrKw@ z_$0zumdXDTT5_%;t{|lLs6liG3_nHZAiOY)icCQzv=lr5UXGB0sE4Rka%4Anw(FcO z@GCl}%uRGy`%i(7XkThSgf@bi+7jeR&(FZMK4}nTX-vQf)4=q@mb({{s!n}^+-hR;VPh;p9J3IUBLZ(5?I6Iz-9a!u$+sUq&5y* z%t>H54*~b`r@#XK4(Q^nctl<2Rq==?Y7%wvmU!56C`z=C`{QBtK96Aje!c-5X`m_-mVCa?r$CWa{UyX&p;vh#i4{oXm} z-gocq&i9M2`^CXZF**<{uWF`>BeLkks1$vp!_(6;c)XBYXPovDjahU@vvLNugniEJ z*)r{>Wx#a?_P!Wj6VA*b*>s%9ZCXn`GIY^8IFr1tP3gZ8X9`IswV6cMF>lYQnWn*T#zS(M_Ls>LHz)&2ucy&%ls?yy z{$W8fs7fyS3ZWLEFJRu$tYxuTEJn1+xq{?np({!g?=`iq_vc}Ya0u^S(=Ys7 ztB{9}_bcoexJH$5jS8|KtEus}3x{9xR@LWn0&WQVQKDDFjtX%Av+G@syK#6;oN0DnvFkjY6)J|UkE)f$*yYUh z^jh4S2-fPxWXz4q=oHaZF{$W?D$5eyHH0NcHJ3jYvf#~LA^WPR*+}gw~AvSP%^$xL~d#hW; z624O1pRMo^S$YyY_0TrrDa3Mwr-Eoc{AOq?K9fT2(D|HKp}mORh+W1nu!zn>TaV@P zC!lrCb;M5yUHdU|1Ok4RzJU?Pz^cj>q;oH5HMj+#3p#9~7j%wZ4W2%evmgAX$yw?p zI%)i!;E#;2Yd?p!qPf~7$kRQqf*Z))P;=TN>Ro%`kG2@(>vc&n#gY2X?5Bcg2w?|_ z1`CKzLwljM|B3ON9wNGC{9nMgj2;31fzY*DU&3@+N3e`?gzlqt1w#9i;H2@}!L1hd zMJMUOT0}nSS(EfU_&MW`q4{2;kAeFUx>oPYdq!*jeT44w74pwQ=MU(*$+-!>VRH6a zS$xfZ12n{DzbTSLF=4Ng}4(4{V`fM zeMgyU z@it%|9{}#+Gr&Qf0RGB$OG4b|+Lna9qYC@R1F16ZZYdRacuz|r+zsy(ZYh3Z6hYvA HP$}YHD^;G$ diff --git a/tests/lua/build/ltm.o b/tests/lua/build/ltm.o index 108d7746e852d16c9ae425e204af9abfcfb57830..7be0167896530179783e54790debbb8e2cf1dda1 100644 GIT binary patch delta 484 zcmYjLJxfC|6uo&dO_NZnNZUtss0yv(B;q83=;FuVZ;(!J(m@biDqdVVwPxucD1@RG z7kQH)P7YQ?9NpB}#l`t~^F%P@p4^;!IOjeTPl~MyJGma)V~r3-Iw;Pv5RanlOZWmO z`vP9TjfPPGSULlUOEG=2a0q{F!LtR=W>Qw7(w6{HlB^~PDks8d5YUv%$eq$OBu;)# zC9swr9CnHid#<51N^fS+#GKS7tV=YG*A=zV4w$Y0VO zelrC!N@X-4XYMNhLi3LEyyvv;c{@Ro%M3*mb3Qglj-u{2h&mLDf_y}}msoK*x;K7MDQ+bSyzL%z%J=3JGPOou|?Y^4D1czmi-`X MS!HT$+s>HM50I6Bvj6}9 delta 570 zcmX|7F>4e-82x7F=61hXkGpUr+2n}m2^XVjQw94ZAl4QZdIVWKl0t)+!UMlf5R_>m zBqT5dHQ2~vAw=t3mqrjl5i3Cy|H1lZ4;}V>JM;E^Z{D}NQzuhTc)=O3uyS?cVF zIY_AJ3Xfv?L!L*5PRVz(JR+GpAS&hx91?m&|JY7oJAtiNEK6)(5#?pMT9y)fljSXv zRP^ku=%7s{EwpGKTZ_;9bD^ZQu!d_3xMar1dM5BzIQU$WX)x1cX40owe^OGf`!Tlp zJs4Nf+QGOj8sZQU(?MNYYgwa;qHT{kb5-l1(3For1XKLJq_1?wwN1OFZGZ$Qx8Rzx?7 zrTTuP-n);K5S=1XKompNpfMpR5@U#HmO$iV{!V*~#lXu>&+pyy zyXV~VJNNCY?jv1$BChH~(I&TRlvcPSo=ure^tAg>Y-H@5w8qXK@QH~M@%p(5A!G%O zNIRT#3umL$Xd`udp6N(R-IF{mrd>knld>WvghJ z!&^oBOIC5fqE(bAuF`-Vlaj?>-nr!!h-X&N!zFF5tu)}9Wh{yMRw_d=!V>5+jRz#crZ zW>Qw=XPrtp<~a64rJ!(hhvms?Ws)u{(2zEEUWO(b)U7n2VBolGM|N7shYF}uFr;=_ zVSCzD@c`E~dZt-n+*j(*JC`hEy%sup#>Q10vcS}bOlX72WLs>*Y}%w1PI~#=W|Ai& zLk~Kk%h?NJP9lC(Z`2k+fJHQ|FVel&X02Xt%jUtX?mJ@$&XeIY4*s_EgfqoWwby?dmO2u<1FDA zjtL!29-d7QSLvuXPc$kaEkaj$A*G(>LeE<=%;T4NbU4tb&4oI1$q0^m?Mbw>ABVNd#$M~F{ho^p|WP6BI1fL-UyOH;FNc>g)^m6S*bDw<_)Re0`(m*W zyO}d9$9b2r%Kr;6^Dn|*@QQSH!!c~Iv|QjC0uf+N^bUM4%w3A)$kng#eBeP~kC7{| zopD(X?*rxnymtb|c{u+m=BNfPE6%i*7UFM38UgVi6}Sn1U9EqPbvKNY7Aen3V~E$l z=acrU*jo6<6&`}$2xI89pX7)@YCWXz$Y9~g^vUC<}2{iysj=_D^$pL z*~wTXdIFdWKM6k!GujQc?@N z=MT3Mn3FPR6^xT!19uH`)FEDC9Ol6Yu@{*6Z^OR{WBzscFJLkLv>pTL3|<)Xr}YzX z{?ob|$jqAkwcEXSHvLw!#q|^oMCRe22aQK!t_SFYNWJ@T8GRp#yZ2Pn%}5+;b|+-1!j|(V|$r`#?Dj$KqV+ Xg;+d%5b{j9guov+&;O4Ef8zfFLtPmm delta 2654 zcmah}YiJZ#6u$eIb$2Jb<8(6aCNarQV%~-rtVEM&DlwWUVy#uHB5Fltu}0$CXjpZK zv8mO{K?+4|$hCsOQserg1u0UBDAm@swttEsQp8e_N`*=*O~11<8x1HO_RRU_-0z%w z9{29$IXBuqNO;Z-LV`L;8wqw%#y=p|v&pcIVQBuZyNj8UVgPGO#CRjGXV!$F}^h7CY{GS*b;IUy$ zjPlZQQjN_jeUHV--~f8$5lqHdqwGOjfXM1@#5jmMn6QjQ`n@ zQE8ETWERQ@Eu>JW&T)+%6uq}HQytADFL(Zg^rkB#kAuD$Y=NzIXGLktx zi=|47>2~NpyL1C|cA`xpnRjkQa& z9k3k_rtKbH9JcOmTkA(m^fiieYsdH?a3UHRG7m*6z4xR(Q0-oe2*sqDZRt5dSHt=g z&Y=xEwvEZ56_!>v2WR`oh-wU>mOsO@1GBl6v#C+dFKxkIEz*o9{hX=6<1wV(XzPDu z&Ym`eZthkmEA!wwk4`IPbW_a>&6K8ZCRav}lzK|!gq0>(ny4;kx-tV1XV5!2Q&J`x zW=NGArj4Fv_4(7x$5|ac&bD5KEE|SvgD)IA zc-fp%j)x+6QSooIM7w-E{Hcr zh^>g#((*!V4vk z1cdDmAmtFYS3@cxY@dsOt4>6J!I^TOb^lqRMaOzJ=Ig-Bc@z2#2y=FTb4bPf zdEqS>k3+JpzQGv6&p*%MMmRB_otq&Xs2}TdfU}A2W$gN%0%raI^l1q5A4G(B${fBC z*k3fkz@!%FnGhxwMRAaTv#ln^sE(gsftk;o`!4?&^h4&j-I|0oU)05iW1x)#Fm zk3+A7lm%_jY9mGe&jTIKO(RC2{51bzaA3H*l$zT*D@>d!N2 diff --git a/tests/lua/build/lvm.o b/tests/lua/build/lvm.o index 153d5f546e4df4f73a830ade66781d2f5fc35318..cb63580f80cf5a831c21f41434c67937da4fcd8c 100644 GIT binary patch delta 15806 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 IA*CYy1Nhr{PXGV_ delta 16650 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