c2plan9

command module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 14, 2026 License: BSD-3-Clause Imports: 19 Imported by: 0

README

c2plan9

The C & LLVM IR to Go Plan 9 Assembly Transpiler Pipeline

«Zero CGO latency meets bare-metal vectorization — compile C intrinsics directly into Go Plan 9 assembly»

Go Version Go Reference License Target Ecosystem

c2plan9 is a high-performance compiler pipeline and machine code disassembly tool that converts C, C++, and LLVM IR source files into Go-compatible Plan 9 assembly (.s) and generates corresponding Go companion stubs (.go).

English • Русский

Why c2plan9?

High-throughput systems programming in Go often requires SIMD vectorization (AVX2, AVX-512, NEON, GFNI). However:

  1. CGO Call Latency: Invoking C libraries via CGO introduces 40–150 ns call overhead, destroying performance benefits for micro-kernels.
  2. Error-Prone Manual Plan 9 Assembly: Writing Plan 9 assembly by hand for complex vector intrinsics is tedious, brittle, and difficult to verify.
  3. c2plan9 Solution: Write clean, optimized C intrinsics, and let c2plan9 compile them via Clang/LLVM into portable ELF object files, disassemble them into Go Plan 9 assembly, and emit Go function stubs.

⚡ Key Capabilities

  • Dual-Architecture Support:
    • AMD64: AVX2, AVX-512, FMA, PCLMULQDQ, AES-NI, BMI1/2.
    • ARM64: NEON vectorization, Crypto extensions (AES, SHA1, SHA2, PMULL).
  • Portable ELF Object Generation: Forces -target x86_64-pc-linux-gnu or aarch64-linux-gnu across all host operating systems (Windows, Linux, macOS), completely bypassing platform-specific object format discrepancies (PE relocations, Mach-O symbol mangling).
  • Typed Return Frame Tracking: Full support for scalar returns (int, int32, float32, float64) and 128/256-bit SIMD vector returns (m128, m256), emitting exact register moves into Go's return frame.
  • Stack Alignment Preservation: Preserves dynamic stack alignment directives (e.g. ANDQ $-32, SP) and calculates frame sizes with alignment padding so AVX aligned spills (VMOVDQA) never fault.
  • Companion Stub Generation: Emits strongly-typed Go companion .go files with //go:noescape annotations.
  • WSL Integration: Native Windows support with optional --wsl flag for compiling via Linux Clang inside WSL.

⚠️ Architectural Constraints & Design Rules

c2plan9 is specifically engineered for computational SIMD microkernels, not as a general-purpose C compiler replacement. When authoring C source kernels, adhere to the following architectural invariants:

  1. Leaf Functions Only:
    • C kernels must be pure leaf functions. They cannot call external functions (call foo), use standard library routines (printf, memcpy, malloc), or trigger system calls.
    • All external memory must be passed directly via pointer arguments from Go.
  2. Parameter Limits:
    • AMD64: Maximum 6 integer/pointer arguments (passed via System V registers: RDI, RSI, RDX, RCX, R8, R9).
    • ARM64: Maximum 8 integer/pointer arguments (passed via AAPCS64 registers: R0–R7).
    • Note: A Go slice occupies 3 parameter slots (ptr, len, cap). For kernels requiring numerous buffers, pass structured pointer wrappers.
  3. Pointers for Vector Buffers:
    • SIMD vectors should be passed by pointer (const uint8_t* in, const __m256i* data), not by value in parameter lists. Return vectors by value (-ret=m256 or -ret=m128) are fully supported.
  4. No Jump Tables:
    • Dense switch statements must avoid jump tables. c2plan9 automatically passes -fno-jump-tables to Clang, forcing binary search branching (CMP/JE) which cleanly relocates into Plan 9.
  5. Freestanding Environment:
    • Compiles with -ffreestanding, -fno-stack-protector, and -fomit-frame-pointer. No C runtime (CRT) initialization exists.

📦 Installation

go install github.com/lemon4ksan/c2plan9@latest

🛠️ Usage

CLI Flags
Usage of c2plan9:
  -c string
        Path to input C / C++ / LLVM IR source file (required)
  -o string
        Path to output Plan 9 assembly (.s) file (optional)
  -stub string
        Path to output Go companion stub (.go) file (optional)
  -pkg string
        Target Go package name (defaults to output directory name)
  -arch string
        Target architecture: amd64 (default) or arm64
  -clang string
        Path to Clang executable (default "clang")
  -flags string
        Extra flags to pass to Clang
  -ret string
        Return type: float32, float64, m128, m256, int, int32, or void
  -wsl
        Compile via Clang inside WSL
Go Generate Example

In your Go package:

//go:generate c2plan9 -c ../csrc/fastscan.c -o fastscan_amd64.s -stub fastscan_amd64.go -pkg simd

Run generation:

go generate ./...

🧪 Testing

make test        # Fast unit tests
make race        # Race detector validation
make lint        # Run golangci-lint
make format      # Format code and enforce license headers

📄 License

This project is licensed under the BSD 3-Clause License. See the LICENSE file for details.

Documentation

Overview

Command c2plan9 converts C, C++, and LLVM IR source files into Plan 9 assembly for Go.

The tool automates the process of invoking Clang to compile hardware-accelerated intrinsic functions into object files and disassembling them into Go-compatible Plan 9 assembly format. It supports both AMD64 (with AVX2/FMA/PCLMUL) and ARM64 (with SIMD/Crypto) targets. The tool can also emit corresponding Go stub files to bridge the generated assembly with Go packages.

Key features include:

  • Portable ELF object generation: forces -target x86_64-pc-linux-gnu or aarch64-linux-gnu across all host operating systems, bypassing platform-specific object format discrepancies (PE addends, Mach-O symbol mangling and section layout).
  • Typed return tracking: supports float32, float64, and SIMD vector returns (m128, m256), emitting the correct return instructions (MOVSS, MOVSD, MOVOU, VMOVDQU from XMM/YMM registers on AMD64, and FMOVS, FMOVD, FMOVQ on ARM64) into the Go return frame.
  • Prologue stack alignment preservation: retains dynamic stack alignment instructions (e.g. ANDQ $-32, SP) and accounts for alignment padding in frame sizing, ensuring AVX aligned memory spills (VMOVDQA) do not fault.

Compared to the standard library

Stdlib counterpart: none - fills gap: automated C-to-Plan9 assembly translation

Rejected compromise: hand-writing complex SIMD instructions directly in Plan 9 assembly syntax

Accepted cost: introducing an external compilation toolchain (Clang/LLVM) dependency for code generation

Allocations: unconstrained

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL