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!
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
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.
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.
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.
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.
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.
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...
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:
c
successfully compiles t
into an assembly file
a
.a
against the standard
Xi library results in a runnable program o
.o
, when executed, terminates (within an arbitrarily bounded
amount of time) with a return code of 0 (i.e., it terminates normally, and not
as a result of an assertion failing or an array out-of-bounds violation).All test cases must:
io
, conv
, and
assert
interfaces.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.
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:
*.class
).Main-Class
to be your driver. This
will enable us to run your JAR file directly. See Sun's tutorial for
help with this.To create a self-contained JAR file, you will have to merge all of the dependencies (cup runtime, framework classes) into it. This can be conveniently accomplished e.g. using the Ant task described in PA4.
.jar
, .zip
, or .tar.gz
) containing your
all source files of your submission (*.java
, *.flex
, *.cup
, etc.). Do not forget to
include your source. Failure to do so will result in a 0 for this
assignment..
Please ensure that your submitted source code archive does not include any of our framework code!
.jar
, .zip
, or .tar.gz
) containing your testing code
and any data files required by it..zip
, or .tar.gz
)
containing up to 5 functional test cases your group would like to be considered
for the test case contest.