• Stars
    star
    997
  • Rank 45,970 (Top 1.0 %)
  • Language
    C
  • License
    Other
  • Created almost 9 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Small C Compiler generating ELF executable Arm architecture, supporting JIT execution

AMaCC = Arguably Minimalist Arm C Compiler

Introduction

AMaCC is built from scratch, targeted at 32-bit Arm architecture. It is a stripped down version of C meant as a pedagogical tool for learning about compilers, linkers, and loaders.

There are 2 execution modes AMaCC implements:

  • Just-in-Time compiler (JITC) for Arm backend
  • Generate valid GNU/Linux executables with Executable and Linkable Format (ELF)

It is worth mentioning that AMaCC is designed to compile a subset of C required to self-host with the above execution modes. For example, global variables and, in particular, global arrays are there.

A simple stack based AST is generated through cooperating stmt() and expr() parsing functions, both of which are fed by a token generating function. The expr() function does some literal constant optimizations. The AST is transformed into a stack-based VM Intermediate Representation via a gen() function. The IR can be examined through a command-line option. Finally, a codegen() function is used to generate ARM32 instructions from the IR which can be executed via either jit() or elf32() executable generation.

AMACC mixes classical recursive descent and operator precedence parsing. An operator precedence parser is actually quite a bit faster than recursive descent parser (RDP) for expressions when operator precedence is defined using grammar productions that would otherwise get turned into methods.

Compatibility

AMaCC is capable of compiling C source files written in the following syntax:

  • support for all C89 statements except typedef.
  • support for all C89 expression operators.
  • data types: char, int, enum, struct, union, and multi-level pointers
    • type modifiers, qualifiers, and storage class specifiers are currently unsupported, though many keywords of this nature are not routinely used, and can be easily worked around with simple alternative constructs.
    • struct/union assignments are not supported at the language level in AMaCC, e.g. s1 = s2. This also applies to function return values and parameters. Passing and returning pointers is recommended. Use memcpy if you want to copy a full struct, e.g. memcpy(&s1, &s2, sizeof(struct xxx));
  • global/local variable initializations for supported data types
    • e.g., int i = [expr]
    • New variables are allowed to be declared within functions anywhere.
    • item-by-item array initialization is supported
    • but aggregate array declaration and initialization is yet to be supported e.g., int foo[2][2] = { { 1, 0 }, { 0, 1 } };

The architecture support targets armv7hf with Linux ABI, verified on Raspberry Pi 2/3/4 with GNU/Linux.

Prerequisites

  • Code generator in AMaCC relies on several GNU/Linux behaviors, and it is necessary to have Arm/Linux installed in your build environment.

  • Install GNU Toolchain for the A-profile Architecture

    • Select arm-linux-none-gnueabihf (AArch32 target with hard float)
  • Install QEMU for Arm user emulation

sudo apt-get install qemu-user

Running AMaCC

Run make check and you should see this:

[ C to IR translation          ] Passed
[ JIT compilation + execution  ] Passed
[ ELF generation               ] Passed
[ nested/self compilation      ] Passed
[ Compatibility with GCC/Arm   ] ........................................
----------------------------------------------------------------------
Ran 52 tests in 8.842s

OK

Check the messages generated by make help to learn more.

Benchmark

AMaCC is able to generate machine code really fast and provides 70% of the performance of gcc -O0.

Test environment:

  • Raspberry Pi 4B (SoC: bcm2711, ARMv8-A architecture)
  • Raspbian GNU/Linux, kernel 5.10.17-v7l+, gcc 8.3.0 (armv7l userland)

Input source file: amacc.c

compiler driver binary size (KiB) compile time (s)
gcc with -O0 -ldl (compile+link) 56 0.5683
gcc with -O0 -c (compile only) 56 0.4884
AMaCC 100 0.0217

Internals

Check Intermediate Representation (IR) for AMaCC Compilation.

Acknowledgements

AMaCC is based on the infrastructure of c4.

Related Materials

More Repositories

1

mini-arm-os

Build a minimal multi-tasking OS kernel for ARM from scratch
C
929
star
2

facebooc

Yet another Facebook clone written in C
C
553
star
3

MazuCC

A minimalist C compiler with x86_64 code generation
C
502
star
4

talks

schedule and materials about my presentations
338
star
5

nstack

Userspace TCP/IP stack for Linux
C
314
star
6

unix-v1

Restoration of 1st Edition UNIX kernel sources from Bell Laboratories
C
193
star
7

kernel-in-kernel

Develop your own OS kernel by reusing Linux infrastructure
C
171
star
8

min-dl

minimal dynamic linker implementation for ELF, supporting x86_64 and Arm/Aarch64
C
162
star
9

tetris

A text-mode tetris game
C
144
star
10

xv6-x86_64

re-implementation of UNIX v6 in ANSI C for x86_64 SMP
C
143
star
11

stm32f429-linux-builder

create a uClinux distribution for STM32f429 Discovery board
Makefile
133
star
12

full-stack-hello

minimal instruction set and assembler/compiler for "Hello World" execution
C
114
star
13

mazu-editor

a minimalist text editor with syntax highlight, copy/paste, and search
C
108
star
14

codezero

Codezero Microkernel
C
102
star
15

cregex

A small implementation of regular expression matching engine in C
C
80
star
16

tlsf-bsd

Two Level Segregated Fit (TLSF) memory allocator implementation, BSD License
C
74
star
17

simple-dvm

A simplified educational Dalvik virtual machine implementation
C
58
star
18

armv8-hello

Hello World for bare metal ARMv8 using QEMU
Makefile
51
star
19

lsd_slam

LSD-SLAM
C++
48
star
20

tinygl

TinyGL: a Small, Free and Fast Subset of OpenGL
C
44
star
21

ogc

A minimal mark-and-sweep garbage collector
C
43
star
22

x-compressor

A minimalist lossless data compressor
C
42
star
23

jit-construct

JIT compiler from scratch, derived from Nick Desaulniers' great work
Lua
37
star
24

svgirl

SVG Instant Rendering Library with focus on embedded systems
C
36
star
25

ttt

An implementation of tic-tac-toe in C, featuring an AI powered by the negamax algorithm
C
30
star
26

rv32jit

JIT-accelerated RISC-V instruction set simulator
C++
30
star
27

stm32f429-r3d

small software 3D rendering program on STM32F429-Discovery
C
26
star
28

kvm-user-x86

A simple userspace program to interact with Linux KVM
C
23
star
29

uThreads

A concurrent library based on cooperative scheduling of user-level threads(fibers) implemented in C++
C++
22
star
30

tvision

GCC/Linux port of Turbo Vision
C++
21
star
31

hungry-birds

classical example of concurrent producer/consumer problem
C
20
star
32

nalloc

structure aware memory allocator
C
19
star
33

stm32f429-lcd-demo

Simple STM32F429 Discovery LCD demo program using emWin library
C
18
star
34

jamvm

JamVM 2 + OpenJDK
C
18
star
35

littlefs-fuse

A FUSE wrapper that puts the littlefs in user-space
C
17
star
36

linsched

Restoration of The Linux Scheduler Simulator (LinSched)
C
16
star
37

stm32f429-demos

Collection of demo program for STM32F429 Discovery
Makefile
15
star
38

auto-tetris

Play Tetris game automatically!
C
15
star
39

skin-deep

Generate faces with smoother skin
C
14
star
40

matrix_oo

Object-oriented matrix implementation in C99
C
14
star
41

tic-tac-toe

An implementation of classical tic-tac-toe game for terminal I/O
C
12
star
42

dummy-driver

dummy Linux kernel module for education purpose
C
11
star
43

Taunix

Realtime operating system kernel for TI TMS320F24x DSP
C
11
star
44

MathEX

An embedded mathematical expression evaluator in C99
C
10
star
45

fizzbuzz

Implement Fizzbuzz without loop-internal conditionals, or arithmetic operators.
C
10
star
46

cjit

A tiny JIT compiler based on MIR
C++
9
star
47

anrmalloc

A new embedded-friendly memory allocator
C
9
star
48

arith_register

Use ELF linker set to construct lists of arithmetic implementations automatically
C
8
star
49

membroker

Memory Broker is a library that helps balance memory load between processes in user space using IPC
C
6
star
50

scalable-font-editor

A scalable font editor, which produces the fonts for embedded environments
C
5
star
51

bubble-sort-arm

Bubble sort in ARM assembly (incomplete)
Assembly
4
star
52

doxygen-oop-in-c

C
4
star
53

iota-whitepaper

IOTA whitepaper
TeX
4
star
54

micronaut-from-scratch

Ahead-of-Time compilation with Micronaut and GraalVM
Java
1
star
55

git-hook-tests

Tests for Git Hooks
Shell
1
star
56

ci-test-public

(TMP) A repository for testing CI pipeline
1
star
57

muxleq

16-bit virtual machine with a two-instruction set CPU capable of running Forth
Forth
1
star