E N D
CPSC 325 - Compiler Tutorial 8 Code Generator (unoptimized)
What Code Generator should do? • Translate all the instructions in the intermediate representation to assembly language • Allocate space for the variables, arrays etc. • Create the necessary symbolic information • Gather all of the necessary information
Assembly language • Advantages • Simplifies code generation due to use of symbolic instructions and symbolic names • Logical abstraction layer • Multiple Architectures can describe by a single assembly language • Can modify the implementation • Macro assembly instructions • Disadvantages • Additional process of assembling and linking • Assembler adds overhead
Assembly langauge • Relocatable machine language (object modules) • All locations (addresses) represented by symbols • Mapped to memory addresses at link and load time • Flexibility of separate compilation • Absolute machine language • Addresses are hard-coded • Simple and straightforward implementation • Inflexible – hard to reload generated code • Used in interrupt handlers and device drivers
Memory Registers ALU Control Modern CPU • ALU • Control • Memory • Registers
Arithmetic and Logic Unit (ALU) • Performs most of the data operations • Has the form: • OP Rdest, Rsrc1, Rsrc2 • Operations are: • Arithmetic operations (add, sub, mulo) • Logical operations (and, sll) • Comparison operations (seq, sge, slt)
Arithmetic and Logic Unit (ALU) • Many arithmetic operations can cause an exception • Overflow and underflow • Can operate on different data types • 8, 16, 32 bits • Signed and unsigned arithmetic • Floating-point operations (separate ALU)
Control • Handles the instruction sequencing • Executing instructions • All instructions are in memory • Fetch the instruction pointed by the PC and execute it • For general instructions, increment the PC to point to the next location in memory
Control • Unconditional Branches • Fetch the next instruction from a different location • Unconditional jump to an address • j label • Unconditional jump to an address in a register • jr rsrc • To handle procedure calls, do an unconditional jump, but save the next address in the current stream in a register • jal label jalr rsrc
Control • Conditional Branches • Perform a test,if successful fetch instructions from a new address, otherwise fetch the next instruction • Instructions are of the form: • brelop Rsrc1, Rsrc2, label • relop is of the form: • eq, ne, gt, ge, lt, le
Control • Control transfer in special (rare) cases • traps and exceptions • Mechanism • save the next (or current) instruction location • find the address to jump to (from an exception vector) • jump to that location
Others, additional information… • Please refer to your CPSC231 text book… In the book; there is all of the details.
Memory layout Stack Heap Data segment Text Segment Reserved
0 zero hard-wired to zero 1 at Reserved for asm 2 – 3 v0 – v1 expr. eval and return of result 4 – 7 a0 – a3 arguments 1 to 4 8 – 15 t0 – t7 caller saved temporary 16 – 23 s0 – s7 calliee saved temporary 24 – 25 t8, t9 caller saved temporary 28 gp pointer to global area 29 sp stack pointer 30 fp frame pointer 31 ra return address Register
Stack (cont.) • Please refer to the hand out for more details..
Guidelines for the code generator • Lower the abstraction level slowly • Do many passes, that do few things (or one things) • Easier to break the project down, generate and debug • Keep the abstraction level consistent • IR should have ‘correct’ semantics at all time • at least you should know the semantics • Use assertions liberally • Use an assertion to check your assumption
Guidelines for the code generator • Do the simplest but dump thing • it is ok to generate 0 + 1*x + 0*y • Make sure you know what can be done at… • Compile time in the compiler • Runtime in a runtime library • Runtime using generated code • Runtime library is your friend! • Don’t generate complex code sequences when it can be done in a runtime library assembly hack
Guidelines for the code generator • Remember that optimizations will come later • Let the optimizer do the optimizations • Think about what optimizer will need and structure you code accordingly • Example: Register allocation, algebraic simplification, constant propagation • Setup a good testing program