Voodoo Compiler
2014-11-09
Introduction
The Voodoo compiler is an implementation of the Voodoo programming language. The Voodoo programming language is a low-level programming language, abstracting over the platform's instruction set and calling conventions, but otherwise leaving the programmer free to do anything at all. The Voodoo compiler is written in Ruby and generates code for i386-compatible, AMD64, ARM, and MIPS CPUs.
The Voodoo Programming Language
The Voodoo programming language page provides a detailed description of the Voodoo programming language.
Download
The Voodoo compiler is open source and freely available under the terms of the GNU Lesser General Public License, version 2.1. There are two main ways to obtain Voodoo: releases and the development branch.
The development branch is where development occurs, and has the latest features, bug fixes, and new bugs. It is recommended for developers who wish to contribute to Voodoo or develop their own software based on it.
Releases are snapshots from the development branch that have been deemed ready for public consumption. They have received some amount of testing and the included documentation matches the included software. If you want to use Voodoo, but do not want to modify the compiler itself, you should probably get one of the releases.
Releases
The latest release of the Voodoo compiler is version 1.1.4, available here: voodoo-1.1.4.tar.bz2 (73 KB). This is a maintenance release, and contains the following bug fixes and improvements:
- References to symbols are now always position-independent, even if the symbol is not exported or imported. This means shared libraries can now have symbols that are not externally visible.
- On AMD64,
tail-call
now restores all callee-save registers in the active frame to their saved values before transferring control to the function being called. Before this fix, calling code generated by the Voodoo compiler from code generated by a different compiler would, under certain circumstances, cause callee-save registers to have wrong values upon return to the code from the other compiler. - On AMD64, rbx is now a callee-save register, as required by the ABI.
- More rigorous tests for expressions have been added. These exposed some bugs in the generated code on AMD64, which have been fixed.
- The ARM code generator now emits constant pools as necessary to keep them within limited distance from the code that uses them. Previously, constant pools were only emitted at the end of blocks, which could cause the offset between a constant and an instruction that uses that constant to be larger than what can be encoded in the instruction.
Development Branch
The latest version of the Voodoo compiler is available via Git from the Voodoo Git repository. It can be checked out with the following command:
git clone git://repo.or.cz/voodoo-lang.git voodoo
Note that this is the development branch of the Voodoo compiler, so it will generally have more features than the releases on this webpage, but be less thoroughly tested.
Installation
To run the Voodoo compiler, you need to have the following software installed:
- A Ruby implementation. MRI 1.8 and 1.9 should work. If you use something a different Ruby implementation, please let me know if it worked or not.
- To produce object files, you will need an assembler for your
target architecture.
- For i386 and AMD64, NASM and YASM are supported
- For other architectures, the GNU Assembler is supported
- To produce executables, you will need a linker. If you link with the C library, the easiest way is usually to use the C compiler (cc). GNU ld will work, too, if you pass it the right options. Other linkers have not been tested.
If you have RubyGems
installed, the easiest way to install the Voodoo compiler is by
running the command gem install voodoo
.
If you have the source code of the compiler (see
Download), you can install it using the
common configure, make, make install
mantra. This means that
the steps to installation are:
- Obtain the files.
You can either download a release, or fetch a current development
snapshot using git. If you
have downloaded a release tarball, you can extract the files in it
using a command like
bunzip < voodoo-1.1.4.tar.bz2 | tar xf -
- Run configure.
Enter the directory where you have stored the files. There is a script
there called configure. You can run it using a command like
./configure
. The script will check if you have all the required software installed and create a file Makefile.cfg for you. If configure reports that some programs are missing, you should install them first. - Run make.
The command
make
is used to perform any steps required to build the compiler. Runningmake
without arguments will perform a default build. Afterwards, you can runmake test
to run the provided tests, and you can runmake rdoc
to generate API documentation from the Ruby source code. - Run make install.
The final step is to run
make install
to install the software and the documentation. You may have to perform this action as root or usingsudo
, e.g.sudo make install
.
Usage
There are two main ways to use the Voodoo compiler:
by running the voodooc
program, or by using the
Ruby API.
The voodooc
program compiles a Voodoo source files.
Its usage is described in the voodooc.1
manpage, included
in the distribution. The following is an example of how voodooc
can be used to create an executable hello
from a source
file hello.voo
:
$ voodooc hello.voo
$ cc hello.o -o hello
$ ./hello
Hello, world!
An implementation of hello.voo
can be
found in the directory test
of the distribution.
The second way to use the Voodoo compiler is by using it from a
Ruby program. This can be used, for
example, to generate code for the target platform without having to
create a .voo
file. The following is an example which
creates an object file called fact.o
, containing a
definition of a function fact
which computes factorials:
require 'voodoo'
generator = Voodoo::CodeGenerator.get_generator
generator.add :functions, [:export, :fact], [:label, :fact]
generator.add_function [:n],
[:ifle, [:n, 1],
# then
[[:return, 1]],
# else
[[:let, :x, :sub, :n, 1],
[:set, :x, :call, :fact, :x],
[:return, :mul, :n, :x]]]
File.open('fact.o', 'w') { |outfile| generator.write outfile }
The Voodoo compiler API that is a available to Ruby programs is described in the API documentation.
Test Matrix
The following table given an overview of the platforms the Voodoo compiler has been tested on. For each platform, the table lists the machine architecture, the name of the operating system, the version of the operating system, the latest version of the Voodoo compiler that was tested, and if it worked (passed all testcases).
Architecture | Operating System | OS Version | Voodoo Version | Works? |
---|---|---|---|---|
amd64 | Debian GNU/Linux | 7.1 | 1.1.4 | |
i386 | Debian GNU/Linux | 7.1 | 1.1.4 | |
i386 | DragonFly BSD | 2.4.1 | 1.1.4 | |
mipsel | Debian GNU/Linux | 5.0 | 1.1.4 | |
arm | Raspbian | wheezy | 1.1.4 |