Xcc700: Self-Hosted C Compiler For The ESP32/Xtensa

With two cores at 240 MHz and about 8.5 MB of non-banked RAM if you’re using the right ESP32-S3 version, this MCU seems at least in terms of specifications to be quite the mini PC. Obviously this means that it should be capable of self-hosting its compiler, which is exactly what [Valentyn Danylchuk] did with the xcc700 C compiler project.

Targeting the Xtensa Lx7 ISA of the ESP32-S3, this is a minimal C compiler that outputs relocatable ELF binaries. These binaries can subsequently be run with for example the ESP-IDF-based elf_loader component. Obviously, this is best done on an ESP32 platform that has PSRAM, unless your binary fits within the few hundred kB that’s left after all the housekeeping and communication stacks are loaded.

The xcc700 compiler is currently very minimalistic, omitting more complex loop types as well as long and floating point types, for starters. There’s no optimization of the final code either, but considering that it’s 700 lines of code just for a PoC, there seems to be still plenty of room for improvement.

15 thoughts on “Xcc700: Self-Hosted C Compiler For The ESP32/Xtensa

  1. I could not fathom this phrase “omitting more complex loop types”, because C loops are extremely simple. But, lo! the README says it supports ‘while’ but not ‘do’ or ‘for’.

    I’ve many times thought of using languages mostly to write a self-hosting compiler and for no other purpose (i.e., not to compile an existing body of code). FORTH obviously. Never thought of using a “C–” approach for that. By the time I really looked at, specifically, the 1990ish C– for DOS, its limitations (iirc, no nesting) were too much to inspire me. But if it’s nested, ‘while’ really is expressive enough, i’d be willing to write a compiler in a language that lacked ‘for’.

    I’d miss ‘struct’, though.

    1. Loops-wise all compilers resolve to about the same assembler code; all three, while, for and do, no difference, it is down to JUMP Assembler command to complete the loop.

      (disclaimer – its been decades since wrote Assembler code, but there are no real “loops” in Assembler to speak of, some kind of code increments/decrements/shifts register value, executes another piece of code, returns, inc/decr/shift – until some kind of condition is met, then jumps to a different piece of code).

      Meaning, it is no loss, really.

  2. I have a bunch ESP32s that I keep meaning to use, but so far everything I want to do with a microcontroller is doable with an ESP8266. But so far I have not been interested in capturing images — just weather data and turning things on and off.

  3. Self hosting a C-compiler is nice, but it has to live in an environment too. I see “ESP32-DOS” on the TFT, and there is an older article on hackaday for that: https://hackaday.com/2021/07/28/emulating-the-ibm-pc-on-an-esp32/ You’d also need a text editor to input the source code, and a generic (preferably multi tasking ) OS to start your programs would then be a logical choice. What’s up with that “elf loader”? If this works over a terminal (emulator (telnet / netcat)) that would be nice too, and drivers for the network are normally an OS function too, so multiple programs can use the network stack.

    I’d also really like to have a unix / linux like CLI, I’ve forgotten most of the old DOS commands, and they were extremely limited too (batch files did not even have a proper loop, pipes were never implemented properly). Sygwin to get command line unix utilities may be adequate. ncurses for simple menu’s.

    With such a system as a solid base, I guess / hope it would attract more people from the retro computing niches too, for example with Z80 and C64 emulators. ESP32 can also already run DOOM. https://www.youtube.com/watch?v=s9bV4q9rWs0

    With such a base it would in time also get extended into generic handheld devices, from (retro) game consoles to dedicated text entry (“distract-less editors”), diaries, calendar applications, programmable remote control and such. I’ve never had a flipper, but maybe that could benefit from this too, by combining the standard applications with custom scripts that can be modified on the fly on the device itself (Add a bluetooth keyboard?)

    Most of such things can also be done on a phone, but with an ESP32 you can do it on EUR 20 of hardware, and a battery life of weeks or months. (Or years even, if the “wake up duty cycle” is very low).

  4. Turbo Pascal ran fine on primitive 386 PCs of the era with full IDE, debugger and graphics library. Just goes to show how inefficient ANSI C is (not to mention C++ with its horrible STL, generics and exceptions. Also, in C malloc maps directly to a simple kernel call while in C++ new and delete is implementation-specific. Microsoft does is their way, GCC another and Segger Embedded Studio theirs. It’s a goddamn mess.

    1. I got into embedded programming thanks in part to Turbo C and an after-market product that let you use the Turbo C debugger against a x86 target running their debugging monitor (kind of like gdb server). I was able to code my project in Turbo C and target it to a NEC V30. Good times.

Leave a Reply to Karl MuellerCancel reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.