maq - a preprocessor for qhasm


The qhasm programming language makes programming on the assembly level much easier and basically you are able to do anything that you can also do in assembly (except calling functions).
However, while porting Emilia Käsper's bitsliced AES code to qhasm I realized that the lack of macros lead to a more or less unreadable qhasm version of the originally very clear and structured assembly code. So I decided to implemented a small preprocessor for qhasm based on "gcc -E" .
Currently supported preprocessor directives are "@include" and "@define". (I used @ instead of # because # is used for comments in qhasm).

Getting and using maq

To obtain maq just do the following
wget http://cryptojedi.org/programming/data/maq-20150712.tar.bz2
tar xjvf maq-20150712.tar.bz2
Then you can process an input file by
$PATH_TO_MAQ_DIR/maq $FILE.pq > $FILE.q

That's it, you can just process one file at a time and maq has no commandline options. Input files for maq are qhasm files with additional preprocessor directives explained in the following. For an example of a program using maq see the qhasm version of the bitsliced AES code for 64-bit Intel processors originally written by Emilia Käsper.

The @include directive

The @include directive includes files. There is no include path which is searched by default, so the argument has to be a relative (or absolute) path to the included file, for example

@include "macros.pq"

includes the file macros.pq from the same directory as the file containing this line.

The @define directive

This directive works just as the #define preprocessor command for gcc. Although usually qhasm does not have semicolons at the end of lines, for multiline @define statements you will have to put ;\ at the end of each line.
To evaluate constant expressions possibly involving macro arguments, put the expression in $ $. The expression has to be separated by blanks from the $ signs. Hence, a typical multiline macro would look like this:

@define foo(x) \
  a = *(uint32 *)(table + $ 4*x $);\
  *(uint32 *)(out + $ 4*x $) = a

The @@ directive

The @@ directive is used for concatenation of macros. It works like the ## directive in C preprocessor macros.

Automatic alignment

To make the output still somewhat readable and managable, maq will put comments in the output at the beginning and end of each expanded macro. Furthermore the source code will be aligned automatically, manual text alignment in the qhasm code will of course not get lost.