CSE 413 Autumn 2006

Assignment 8 -- D Code Generation

Due: Electronic turnin of entire compiler, including test output and written report, due Sunday, Dec. 10, by 11:00 pm.

You may work with a partner on this assignment. If you have a partner from the previous compiler assignments, you should continue working with that person. 

Overview

For this assignment, add code generation to your compiler. When the finished compiler is executed, it should open a D source program file, compile it, and produce a .s assembler text file containing an x86 assembly language version of the D program. Source lines from the D file, including comments and whitespace, should appear as comments in the assembler code, with each source line near the code generated from it.

Most of the work in this assignment consists of adding new code to the existing parser. While you might find it useful to create some extra functions or data structures, the bulk of the changes will be additions to existing parser functions.  A separate handout contains details about code generation for D programs.

Executing Compiled Code

The easiest way to run the compiled x86 code is to call it from a trivial C program as if it were an ordinary function.  That ensures that the stack is properly set up when the compiled code begins executing, and provides a convenient place to put functions that provide an interface between the compiled code and the external world (get and put).

C Bootstrap

The bootstrap program is named druntime.c (right click on the file name to download a copy). You should use this program to run your compiled code.  The file contains the get and put functions as well as the main program. Here is the key part that executes your compiled code.

int d$main();   /* prototype for external function */

int main() {
  printf("\nValue returned from D main: %d.\n", d$main());
  return 0;
}

A key point is that the "real" main program is here. The main function in your compiled code should have a label with the name d$main, and that name should appear in a .globl declaration in the compiled code to make it visible to the bootstrap program.

Executing Assembler Code with gcc

The output of your compiler is an ordinary text file. It can have any name you would like, but it is customary on Unix systems to give assembler source files a name ending with ".s".

Assuming that your compiled code is stored in a file named, e.g., code.s, you can use gcc to assemble this file, compile the bootstrap file, and load the result with a single command:

gcc code.s runtime.c

That produces an ordinary a.out file on linux systems contining the complete program, which can be run normally.

Where to Start

As with previous assignments, it's helpful to figure out what piece of the compiler can be done first, without having to finish everything at once. Here are some suggestions.

To get going, try implementing just enough to generate labels for functions and the ret instruction that ends a return statement. That should be enough to generate a text (.s) file containing an empty main program that can be called and return to the bootstrap without crashing.

Once you've done that, try implementing factor() for integer constants. Then return statements with constant values should work. From there you could implement arithmetic operations, which gives you return statements with expressions involving constants. You can test the code by writing small programs each of which has a main methods with a different return expression.

The next big step could be to figure out the details of stack frame layouts and the offsets assigned to parameters and local variables. Check your work by compiling some sample programs, print the local symbol tables, and verify that the offsets are correct. From there you should be able to add assignment statements and expressions (factors) that include integer variables.

There are several possible ways to go from here. Probably the most useful is to get function prologues and epilogues (the rest of return) to work. At this point you should have straight-line code with function calls, including calls to get and put, working properly.

Finally, look at code generation for conditions (rel-exp and bool-exp) and if and while statements. The issues here are getting the labels planted in the right place, and picking the right conditional jumps to the correct labels.

Test Programs

Several D test programs are available from the course web.  Feel free to create additional tests to demonstrate or debug your compiler.  If you create any new test programs, please feel free to share them with others or contribute them to the collection on the course web (send mail to cse413-staff@cs).

Project Turnin

Turn in the following electronically using this online turnin form. The electronic turnin should include all of the source code for your compiler, as well as test cases, output, and your written report. Include: