Skip to main content

upeepz80 - Universal Peephole Optimizer for Z80

A language-agnostic peephole optimization library for Z80 compilers that generate pure Z80 assembly.

Overview

upeepz80 provides high-quality optimization passes for compilers targeting the Zilog Z80 processor. Unlike upeep80, this library expects pure Z80 mnemonics in lowercase as input (ld, jp, jr, etc.) and produces optimized Z80 assembly output with lowercase mnemonics.

If your compiler generates 8080 mnemonics (MOV, MVI, LXI, etc.) that need translation to Z80, use upeep80 instead.

Features

Peephole Optimizations

  • Pattern-based optimization on Z80 assembly
  • Redundant load/store elimination
  • Jump optimization (jp to jr conversion, jump threading)
  • djnz conversion (dec b; jr nz → djnz)
  • Stack operation combining (push/pop to ld conversions)
  • Dead store elimination
  • Tail call optimization (call x; ret → jp x)
  • Register copy optimization (push hl; pop de → ld d,h; ld e,l)

Z80-Specific Features

  • Relative jump optimization (jp → jr where in range)
  • djnz loop optimization
  • Z80 block instruction awareness
  • Direct ld de,(addr) usage (Z80-only instruction)

Installation

pip install upeepz80

Or for development:

git clone https://github.com/avwohl/upeepz80.git
cd upeepz80
pip install -e ".[dev]"

Usage

Basic Usage

from upeepz80 import optimize

# Optimize Z80 assembly code
assembly = """
    ld a,0
    push hl
    pop de
    jp LABEL
LABEL:
    ret
"""

optimized = optimize(assembly)
print(optimized)
# Output:
#     xor a          ; ld a,0 → xor a (smaller)
#     ld d,h         ; push/pop → register moves (faster)
#     ld e,l
#     ret            ; jp to next instruction eliminated

Using the Optimizer Class

from upeepz80 import PeepholeOptimizer

# Create optimizer
optimizer = PeepholeOptimizer()

# Optimize assembly code
optimized_asm = optimizer.optimize(assembly_text)

# Check statistics
print(f"xor a conversions: {optimizer.stats.get('xor_a', 0)}")
print(f"Jump threading: {optimizer.stats.get('jump_thread', 0)}")
print(f"djnz conversions: {optimizer.stats.get('djnz', 0)}")

Optimization Phases

The optimizer runs multiple phases:

  1. Pattern Matching - Apply peephole patterns (up to 10 passes)
  2. Z80-Specific Optimizations - Inline patterns for Z80 instructions
  3. Jump Threading - Thread through intermediate jumps
  4. Relative Jump Conversion - Convert jp to jr where possible
  5. djnz Optimization - Convert dec b; jr nz to djnz
  6. Dead Store Elimination - Remove unused stores

Architecture

upeepz80 is designed to be language-agnostic:

  • Works directly on Z80 assembly text
  • No knowledge of source language required
  • Pattern-based transformation engine
  • Zero runtime dependencies

Comparison with upeep80

Feature upeep80 upeepz80
Input 8080 or Z80 mnemonics Z80 mnemonics only
Output Z80 or 8080 (configurable) Z80 only
Translation 8080 → Z80 translation None needed
Use case Compilers generating 8080 code Compilers generating Z80 code

Choose upeepz80 if your compiler already generates Z80 mnemonics. Choose upeep80 if your compiler generates 8080 mnemonics.

Used By

  • uplm80 - PL/M-80 compiler for Z80 (after migration)
  • uada80 - Ada compiler for Z80 (after migration)

Development

Running Tests

pytest

Type Checking

mypy upeepz80

Code Formatting

black upeepz80
ruff check upeepz80

Performance

Benchmarks on typical compiler workloads:

  • Peephole optimization: ~50,000 instructions/second
  • Memory usage: Minimal (pattern-based, no large data structures)

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

License

This project is licensed under the GNU General Public License v2.0 - see LICENSE for details.

History

upeepz80 is a sibling project to upeep80, designed for compilers that generate native Z80 assembly. It shares the same optimization algorithms but removes the 8080 translation layer for cleaner, more efficient code when 8080 support isn't needed.

Related Projects

  • 80un - Unpacker for CP/M compression and archive formats (LBR, ARC, squeeze, crunch, CrLZH)
  • cpmdroid - Z80/CP/M emulator for Android with RomWBW HBIOS compatibility and VT100 terminal
  • cpmemu - CP/M 2.2 emulator with Z80/8080 CPU emulation and BDOS/BIOS translation to Unix filesystem
  • ioscpm - Z80/CP/M emulator for iOS and macOS with RomWBW HBIOS compatibility
  • learn-ada-z80 - Ada programming examples for the uada80 compiler targeting Z80/CP/M
  • mbasic - Modern MBASIC 5.21 Interpreter & Compilers
  • mbasic2025 - MBASIC 5.21 source code reconstruction - byte-for-byte match with original binary
  • mbasicc - C++ implementation of MBASIC 5.21
  • mbasicc_web - WebAssembly MBASIC 5.21
  • mpm2 - MP/M II multi-user CP/M emulator with SSH terminal access and SFTP file transfer
  • romwbw_emu - Hardware-level Z80 emulator for RomWBW with 512KB ROM + 512KB RAM banking and HBIOS support
  • scelbal - SCELBAL BASIC interpreter - 8008 to 8080 translation
  • uada80 - Ada compiler targeting Z80 processor and CP/M 2.2 operating system
  • uc80 - ANSI C compiler targeting Z80 processor and CP/M 2.2 operating system
  • ucow - Unix/Linux Cowgol to Z80 compiler
  • um80_and_friends - Microsoft MACRO-80 compatible toolchain for Linux: assembler, linker, librarian, disassembler
  • uplm80 - PL/M-80 compiler targeting Intel 8080 and Zilog Z80 assembly language
  • z80cpmw - Z80 CP/M emulator for Windows (RomWBW)

See Also

Release files for upeepz80 0.2.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for upeepz80 0.2.3
File Size Uploaded
upeepz80-0.2.3.tar.gz 34.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for upeepz80 0.2.3
File Interpreter ABI Platform
upeepz80-0.2.3-py3-none-any.whl Python 3 none any Details

Total release size: 62.5 kB

Release files / upeepz80-0.2.3.tar.gz

Download URL upeepz80-0.2.3.tar.gz
Size 34.8 kB
Tags Source
SHA-256 checksum
How to use checksums
f6317d2e940f5ba7a28cbd41f4be12c3d97b89cfdb977a7fffb4efadcef3a1ca
BLAKE2b-256 checksum
How to use checksums
935a636edcb5620e5d89a7e8e6a30051b243b612aeae7722b715cd9acc9c8ade
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 23, 2026.

Transparency log

Release files / upeepz80-0.2.3-py3-none-any.whl

Download URL upeepz80-0.2.3-py3-none-any.whl
Size 27.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
59e4a5964b9ca837cc0b3cc15d98031b1c716c283eb9be73ca208ef0a87aa079
BLAKE2b-256 checksum
How to use checksums
6bc268244931158b8f98a0ac68c86093c986455b724198798b3fc406380458dc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 23, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.3 This release

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page