Brainfuck to RISC-V JIT compiler written in Zig
Hi everybody, this was my project to learn Zig and RISC-V+x86_64 assembly. Not sure if anybody is actually interested in yet another Brainfuck compiler, so I'll just write up some random things I learned while building it! - A primitive assembly stitching compiler is 10x faster than the interpreter. Did not expect that. - The generated x86 code is really bad (e.g. it always uses 6 or 7 byte sized instructions with 32-bit immediates when there are much smaller ones) but it doesn't really matter. Good code generated by GCC and clang for transpiled Brainfuck->C is not much faster as it's…
What it does
In the maker’s words, at launch
Hi everybody, this was my project to learn Zig and RISC-V+x86_64 assembly. Not sure if anybody is actually interested in yet another Brainfuck compiler, so I'll just write up some random things I learned while building it! - A primitive assembly stitching compiler is 10x faster than the interpreter. Did not expect that. - The generated x86 code is really bad (e.g. it always uses 6 or 7 byte sized instructions with 32-bit immediates when there are much smaller ones) but it doesn't really matter. Good code generated by GCC and clang for transpiled Brainfuck->C is not much faster as it's bottlenecked by memory accesses anyways. - Zig is pretty far along actually. You can make serious projects with it! - But the community seems to like self-punishment. Unused parameters and variables are hard errors and there is no way to disable that even for debug builds. Makes quickly commenting out part of the code a real PITA. - I've had a miscompilation due to std.mem.span being broken and two source code breaks going from Zig 0.13 to 0.15 (std.mem.page_size got removed and ArrayList.popOrNull as well). - But arbitrary size integers are fantastic! And well-defined two's complement behaviour! Here is for example the code that encodes the c.beqz instruction: /// Branch if Equal to Zero (compressed): c.beqz rs1', offset -> beq rs1, x0, offset pub fn c_beqz(text: *std.ArrayList(u8), rs1: RV_X, offset: i9) !void { std.debug.assert(is3BitReg(rs1)); std.debug.assert(@mod(offset, 2) == 0); const imm: u9 = @bitCast(offset); const RV_CB = packed struct(u16) { op: u2, offset5: u1, offset1_2: u2, offset6_7: u2, rsd_rs1_: u3, offset3_4: u2, offset8: u1, funct3: u3, }; const ins = RV_CB { .op = 0x1, .offset5 = @truncate(imm >> 5), .offset1_2 = @truncate(imm >> 1), .offset6_7 = @truncate(imm >> 6), .rsd_rs1_ = @truncate(@intFromEnum(rs1) - 8), .offset3_4 = @truncate(imm >> 3), .offset8 = @truncate(imm >> 8), .funct3 = 0x6, }; try appendInstruction(text, u16, @bitCast(ins)); } This is really nice as all the exotic integer sizes are actually checked, too. - Zig support for Windows is good. Porting the project to Windows was very easy. - When the RISC-V registers are carefully chosen, almost all instructions could be compressed in this projects. - Compressed instructions and good branching code (using the branch instructions directly when the jump range is small enough instead of branching over a larger jump instruction) did not noticeably change performance on real hardware (OrangePi RV2). - But somehow QEMU got a massive boost from that. Not sure why exactly. So, that's about it! I hope at least something was interesting...
Does the same job
all alternatives →- RVRISCY-V02: A 16-bit 2-cycle RISC-V-ish CPU in the 6502 footprintMar 2026 · github.com · ▲7
Finally finished my little CPU project, RISCY-V02. I built it (with Claude) to challenge the notion that the 6502 was a "local optimum" in its transistor budget. Given the constraints of 1970s home computers (~1 MHz DRAM, so raw clock speed doesn't help), could RISC have been a better design choice? This design argues yes: pipelining, barrel shifters, and more registers beat microcode PLAs, questionable addressing modes, and hardware BCD. Highlights: 8x 16-bit general-purpose registers (vs 3x 8-bit on 6502) 2-stage pipeline (Fetch/Execute) with speculative fetch 61 fixed 16-bit…
- JAJig – a tool to define, compute and monitor metrics2021 · jigdev.com · ▲74
Hi HN, 8 months ago, I posted “Ask HN: I built it nobody came, what now?” and got a ton of (not very optimistic) feedback [1]. I took away 3 things: 1. The message wasn’t properly targeted 2. The onboarding experience was terrible. 3. Someone posted some advice to find leads which actually worked, yeah! So here we are. 8 months later. I unfortunately didn’t have a lot of time to put in the tool itself. But I improved the website, improved the onboarding, and got a paying customer who seems to really like the software. So here it is in its current form. Let me know what you think would make…
- IWI wrote a .NET to JS compiler. Here's an XNA demo compiled to JS.2011 · hildr.luminance.org · ▲103
- IMI made a set of tools to write kernel prototypes.2024 · github.com · ▲8
This is a personal project I've been working on and off for the past few years. It's a set of tools that have allowed me to prototype quickly small (and increasingly bigger) kernels, and create userspace programs to interact with them. Supports riscv64, amd64 and i386. The intel port has been tested and used on real hardware, from big dual-socket Xeon machines to an old X220. It is all C, I have plan to make rust bindings for the kernel library. But again, they're plans at this stage. Porting to new architectures is relatively simple, a basic port to riscv took me a couple of weeks of…
- IBI built an open-source kernel for Texas Instruments calculators2014 · ▲20
You know that old TI calculator you used in high school, then put in a box and forgot about? Have you ever wished you had an operating system for your calculator with preemptive multitasking, dynamic memory management, a tree filesystem conforming to the FHS, and all the comforts of Unix? Well, good news: that's totally a thing that exists. I've been working on my kernel for about three and a half years now and I'm looking for new contributors to help out. It's written entirely in z80 assembly, and it's both challenging and fun to work on. There's an IRC channel for contributors or people…
- LSLess Slow C++2025 · github.com · ▲6
Earlier this year, I took a month to reexamine my coding habits and rethink some past design choices. I hope to rewrite and improve my FOSS libraries this year, and I needed answers to a few questions first. Perhaps some of these questions will resonate with others in the community, too. - Are coroutines viable for high-performance work? - Should I use SIMD intrinsics for clarity or drop to assembly for easier library distribution? - Has hardware caught up with vectorized scatter/gather in AVX-512 & SVE? - How do secure enclaves & pointer tagging differ on Intel, Arm, & AMD? - What's…
More dev tools this month
the category →



Open-source GTM skills for technical founders
Dev tools · 29d ago · gtmcofounder.com

OpenTrailPaper is open-source bike computer firmware for the LilyGO T5S3 4.7" E-Paper PRO. It supports offline maps, GPX routes, FIT recording and Bluetooth sensors.
Dev tools · 1d ago · opentrailpaper.com

Launched alongside, May 2025
the whole month →
- C9
Life & fun · 2025 · felixrieseberg.github.io



