Project 4: Code Generation
Due: Tuesday, April 9, 2013 by midnight

Description

We now have everything we need from the front end and middle to generate machine code.

In this phase of the project, you will walk the IR from Project 3 and generate x86-32 machine code that runs under thot.cs.pitt.edu machine (Linux). Thot is accessible outside of the VPN and uses your pitt.edu login rather than your cs.pitt.edu information.

A Suggested Progression

This is one possible order in which to make the compiler do more work at each step but still have a small testable unit:

1.       Compile a “Hello, world” program

2.       Compile a program that outputs a small calculation (like 5+4)

3.       Arbitrary straight line code with local and global variables

4.       Arbitrary straight line code with functions and parameters

5.       Add in Control Flow and support for recursion (proper activation records)

6.       Do Register Allocation, no spills, no coalescing.

7.       Do Register Allocation, no spills, coalescing.

8.       Do Register Allocation, with spills, and the allocator enforces the calling convention

9.       Dynamically Allocate Objects and Arrays

For instance, to add functions without enforcing the calling convention, you can make your generated functions save all registers on the stack and then restore them before returning. In x86, you can use the instructions pusha and popa to do that.

That will allow you the registers EAX, EBX, ECX, EDX, ESI, and EDI at least to hold locals. Your first programs can simply allocate everything to the stack, and then load a needed value into a register (say, EAX) to be operated upon. Then store the value back to memory. (That is, “allocate” each temporary and variable in your symbol table with a stack offset and emit code of the form ESP+OFFSET. The offset is allowed to be an arbitrary 32-bit immediate/constant in x86.)

You do not need to implement object deallocation or garbage collection for this project.

Calling Convention

We will use the most basic x86 calling convention. We will assume all registers must be caller-saved and that a return value will be held in EAX. Arguments will be passed on the stack.

You can push the arguments left to right for the functions you create, but remember that C functions expect their arguments pushed right to left. One way to deal with this is to write small wrapper functions around the C standard library functions that fix the order of the parameters, and to call those (for something like Print(int x) that might be implemented as printf(“%d”, x)). The other way is to make the entire program use the C calling convention.

Example ASM File: hello.S

.intel_syntax noprefix

 

.globl main

 

.data

 

string: .string "Hello From ASM"

 

.text

 

main:

     mov  eax, OFFSET FLAT:string

     push eax

     call puts

     mov  eax, 0

     sub  esp, 4

     push 0

     call exit

     ret

 

Assemble hello.S with the following command line:

gcc -m32 hello.S -o hello

 

This will link in the C Standard Library. You may not use any other flags.

Standard Library Calls

You may call any of the C standard library functions or system calls to do I/O, malloc, string handling, and exit.

Submission

Copy your zipfile from thot to:

/afs/pitt.edu/home/j/r/jrmst106/submit/2210

 

You may need to do a klog USERNAME@pitt.edu if not on thot in order to do so.

Please also email the TA to set up a demo time.

 

Do include:

·         All of the source code

·         A README

·         A Makefile

·         At least 3 distinct programs of your creation that demonstrate what your project is able to do.