Objectives
To build a native code generator for a procedural language.
To demonstrate competence in X86-64 assembly language.
To solve common problems in register allocation and expression translation.
To gain experience in incremental software development.
Overview
Finally, you will complete
your compiler by adding a code generator. We will discuss
code generation extensively in class, so this assignment
won't specify it in too much detail. The goal is simple:
Your compiler must read in a B-minor program as specified
by the B-minor overview, and emit an 64-bit X86 assembly language
program that can be assembled, linked, and run correctly.
Requirements
Your program must be written in plain C (not C++) using GCC (not G++)
and use bison to generate the parser and flex to generate the scanner. You must have a Makefile such that
when you type make, all the pieces are compiled and result in
a binary program called bminor. make clean should also
delete all temporary files, so that the program can be made again from scratch.
Your code must work on the CSE student machines. You must use the Bminor Starter Code as the basis for your work.
Your compiler should be invoked as follows:
% bminor -codegen sourcefile.bminor sourcefile.s
If the program passes all earlier phases of compiling --
scanning, parsing, resolving, and typechecking --
then you should print a valid assembly language program
to the file specified in the third argument and exit
with status zero. If some error is encountered along
the way, then you must print a reasonable error and
exit with status one.
Your program will need a runtime library to operate correctly.
Use the library.c provided with the B-minor starter files.
Note that a print statement in B-Minor
should result in one or more calls to the C functions
print_string, print_integer, etc, depending
on the type of the expression. You may add additional
additional runtime calls as you see fit.
To convert assembly code into a working executable, use
GCC in assembly mode and include the B-minor standard library:
% gcc -g sourcefile.s library.c -o myprogram
% ./myprogram
It's quite possible that this final stage of the project
will require you do go back and make a few changes to earlier
stages. Do what you need to do in order to get the code working!
The assembly code that you produce should work correctly,
but it need not be simple, pretty, or optimal.
You may make the following simplifying assumptions:
Due to the large number of X86-64 registers, you may use a simple
non-spilling register allocator, and fail with an "out of registers"
error on really complicated nested expressions.
To keep the calling conventions simple, calls to functions with more than six arguments may fail with a "too many arguments" error.
Only one-dimensional arrays of integers at global scope must be implemented.
Arrays of other types, or arrays as parameters or local variables may fail with an "array not implemented" error.
Hints
Start by writing a bunch of *very* simple programs that do
very simple things, and then write just enough of the code
generator to cover those cases. For example, write a test
that declares one variable (and nothing else), or returns
a single constant value from main. Work up bit by
bit to handle integer arithmetic, then control statements,
function calls, and so forth.
When you are ready for a challenge, try these
complete example programs.
Grading
Please review the General Instructions for Turning In.
Your submission will be tested on the ND student Linux machines,
so make sure that your code works there. If you develop on your
laptop or another computer, leave plenty of time before final submission
to debug any differences between your computer and ours.
As before, the options from the previous three projects
must continue to work correctly. You must also turn in
a set of twenty test programs named good[1-20].bminor.
Each one must be a valid B-minor program on which you
produce working output. Make sure that your test cases
start with very simple examples and work up to complex
examples with complex expressions, control flow statements,
and functions. (You tested all the bad cases in previous stages,
so you don't need to include bad cases now.)
Your grade on this project will be based upon:
Continued correctness on previous stages. (10 percent)
General structure and completeness of the code generation stage. (40 percent)
Correctness of your test cases. (20 percent)
Correctness on our test cases. (20 percent)
Good programming style. (10 percent)
This assignment is due on Thursday, December 12th before 5PM. Late assignments are not accepted.
Frequently Asked Questions
None yet!