CS 4120: Introduction to Compilers
Fall 2011

Programming Assignment 5: Assembly Code Generation

due: Monday, Nov 7
changes:

The goal of this assignment is to generate assembly code from your IR, therefore making your compiler fully functional. The output should be processable by the GNU assembler and linkable with the runtime library we provide in order to produce working executables. Your code will run!

Runtime library

We require the code you produce to be able to interface with the runtime we provide, and to interoperate with other functions we may create for testing. To do this it is sufficient to follow the Xi ABI, and you have likely done most of the required work in the previous assignment. In here, you should finish implementing the details that were not visible in your IR. In particular, you'll need to be aware of the rules on register saving. Please see the updated ABI overview document for more details.

You should download the sources for the library here, as a .tar.gz or a .zip (Version 1, Oct 19). The archive also includes sample assembly files, and instructions on testing them. Please see README.txt in the file for more details

Output code quality

We do not expect you to implement optimizations or high-quality register allocation for this assignment; the goal here is to produce working programs. However, we do expect you to implement non-trivial instruction selection with tiles that take advantage of the expressive x86-64 instruction set features like complicated addressing modes and in-memory operands. You are free to implement register allocation if you wish, but it is fully acceptable to stack-allocate all temporaries and use registers only to shuttle data between instructions and the stack.

Calling conventions and binary compatibility

Presently, two main conventions for passing and returning function arguments exist: the System V ABI, which is used by Mac OS, Linux, and other Unix-like operating systems, and the independently developed Microsoft calling conventions.

In this course, we require that you support the System V ABI. The course staff will run your submissions on Linux—hence, we recommend that you test your compiler on a Linux machine. If you don't have access to one, alternative options are to use the CSUGLab or a virtual machine (VMWare, VirtualBox, etc.).

Fortunately, given the right compiler architecture, it is relatively straightforward to support multiple calling conventions. This may be desirable if the members of your group use several different operating systems. Please take a look at the corresponding section in the ABI document for details.

Driver

Your new functionality must be invokable through your driver. Your driver must support at least the following command-line interface:

java -jar YOUR_JAR [-O] [-o OUTPUT_FILE] SOURCE_FILE

-O Disable optimizations.
-o OUTPUT_FILE Specify the file to write the output to. If this option is not specified, and the file name SOURCE_FILE ends with .xi, replace that with .s. If SOURCE_FILE has a different extension, append .s instead.
-target OS Specify the operating system for which to generate code. OS may be one of linux, windows, or macos. Your compiler is only required to support the linux option. You may support additional operating systems at your discretion, and you may define the default operating system for your compiler in a way that is convenient for you.

As in previous assignments, your driver should accept the file name of an Xi source file. If the file is invalid Xi (syntactic or semantic), you should report a helpful error message including the position of the invalid code and a description of the problem. If the program is valid, you should compile it, and output the assembly to a file, with the name determined as given above in the description of the -o option.

For example, java -jar acm22_waj23_gs376.jar hello.xi should output the assembly code the compiler produces for the program hello.xi into hello.s.

You may add additional flags and options as long as you support these requirements.

Advice for how to proceed

You should complete your implementation as you see fit, but we offer the following suggestions.

First, download and compile the runtime. Take a look at the .s files inside the examples/ directory, and try assembling and linking them by hand. If you can do it for the examples, you'll be able to run programs your compiler produces.

As part of your solution, you'll be specifying many different tiles and their mapping to the IR. You probably want to plan out how you'll be specifying and organizing these tiles.

Since you're now able to produce runnable programs, you can have runnable functionality test cases. Taking advantage of that can help automate testing. However, do not limit yourself to such tests, as it may be hard to get good coverage over instruction-selection cases from .xi sources alone.

Outside manuals

The following documents may be useful:
IntelĀ® 64 and IA-32 Architectures Software Developer's Manuals
GNU Assembler manual

Building on PA 4

As before, you are building upon your work from PA4. The protocol is the same as in prior assignments: you are required to devise and incorporate tests that expose any issues with your implementation, then fix these issues.

Test cases

We are providing a few test cases for you to try out your compiler on (testcases.zip). However, you should not consider these test cases to be exhaustive. You will need to develop your own test cases to properly test your compiler. And you can submit your test cases to...

Functional test contest

Now that your compilers will generate runnable code, you will be able to include end-to-end tests (often called functional tests) as part of your testing strategies. For fun (and for good karma), groups may participate in a contest of sorts. Each group may (optionally) submit a subset of their most difficult test cases, and the course staff will run these test cases against every group's compilers. The goal will be to craft test cases (that conform to the common language specification) that expose bugs in others' compilers.

Each functional test case will be a valid Xi source file. A compiler c passes a test t if and only if:

All test cases must:

Each group may submit up to 5 test cases. Submitting test cases that fail to conform to the above requirements may result in disqualification (and thus bad karma). Groups that submit test cases that expose bugs in compilers (i.e., test cases that compilers do not pass) will discover good karma. All test cases submitted for the contest will be released after the assignment's due date.

Submission instructions

As in previous assignments, please ensure that all your Java code lives in a package containing the NetId of at least one of your group members. Your code should compile without errors or warnings. Your code should not contain any superfluous print or debug statements.

Submit the following: