Code Generator
This unit processes intermediate code and generates executable code and reference records for Linker.
Most compilers use some kind of intermediate code which is a program representation somewhere betwen the high-level source code and executable code for target processor.
Turbo Pascal uses few procedures to generate any x86 instruction needed. In general two intermediate code records are used: one for the actual inctruction opcodes and immediate data and one for references.
Programs created with Turbo Pascal use stack frame. This is part of the processor’s stack space which can be accessed using a dedicated base pointer (BP) register.
Each module (program or unit) needs some initialization and finalization: entry and exit code.
Interrupt procedures also need some initialization and finalization. Turbo Pascal generates interrupt entry code that saves registers, creates stack frame and sets DS register to data segment.
Procedures and functions (including methods) also need initialization and finalization code.
Turbo Pascal generates jumps in an interesting way. Since most jumps will jump to the same place, Turbo Pascal keeps them in a linked list.
Whenever Turbo Pascal needs to reference anything that doesn’t have fixed location, i.e. its address is not known yet like variables, typed constants or procedures, the compiler generates intermediate code reference record which contains all information to later resolve the reference.
Turbo Pascal tries to optimize loading of addresses to ES:DI register pair. For this purpose it uses few intermediate code instructions that track addresses that need to be loaded. The first intermediate code instruction will load local variable address to ES:DI registers.
Turbo Pascal tries to convert all near jumps to short. This is only possible if jump displacement can be stored in a byte. This procedure is called just before the target code is generated. Since all changes reduce code size and therefore provide new opportunities for optimizations, the function is called in a loop until …
Before the target code is generated Turbo Pascal needs to know code size and offsets of instructions. This procedure processes intermediate code instructions and calculates the size of generated code, offsets of near jump instructions, offsets of labels and size of reference records.
This procedure generates target (x86) code from intermediate code instructions. This is the last phase in program block compilation. If debug info is enabled, source line code offsets will be saved into dedicated table, redundant loadings of addresses to ES:DI register pair will be removed and near jumps will be converted to short jumps where …