SPIM machine description level 0 ------------------------------- These machine descriptions have been prepared by Sameera Deshpande (sameera@cse.iitb.ac.in) for the Workshop on GCC Internals (www.cse.iitb.ac.in/~uday/gcc-workshop) conducted by CFDVS and Dept. of CSE, IIT Bombay, during 18,19, and 20 June 2007. Level 0 of the compiler has three sublevels - Level 0.0 is sufficient to generate a compiler (i.e. the build process succeeds) but compilation of any program may not succeed. - Level 0.1 supports compilation only parameterless empty functions in C. - Level 0.2 includes complete activation record layout which is required in level 1 onwards. Although level 0 supports minimal functions, the retargetability mechanism in GCC still requires plenty of details to be supplied to the compiler generation framework. This information is divided in the following categories: A. Memory Layout B. Supported Instructions C. Registers D. Addressing Modes E. Activation Record Conventions ============================================================================ A. Memory layout issues: ============================================================================ We need to describe the following: - Bit, byte and word endianness Spim simulator assumes the endianness of the underlying architecture on which the simulator is being executed. For our experiments, the underlying architecture is i*86 and all entities are ordered in little endian manner. - Alignment boundaries Alignment is not enforced strictly by the spim simulator. We have chosen to align stack data at 64 bits whereas words are aligned to 32 bits. ============================================================================ B. Supported Instruction: ============================================================================ - Level 0.0 does not support any instruction. However, . In order to facilitate building the compiler, the data structures in the compiler source should not be empty. Hence we include a dummy instruction. . Since compiler adds a dummy common exit to each function, it has to be made to believe that direct and indirect jump instruction have been supported. - In order to compile parameterless empty function to a valid assembly program accepted by spim simulator, Level 0.1 compiler requires . assembly formats, . jump instructions, . return insn (implemented through a jump indirect instruction in spim). This is generated through standard pattern "epilogue". Prologue is empty. - Level 0.2 does not support any additional instruction. It includes complete specification of activation records and calling conventions. Although, it is irrelevant to compiling empty functions, it sets the stage for Level 1 compiler which supports assignment statements (and hence needs space to be allocated for variables). ============================================================================= C. Addressing mode issues: ============================================================================= An operand in spim assembly language can be described in the following ways: - imm(reg) - (reg) - imm + label - label + (reg) - label + imm(reg) - imm - label where reg is a base register. ============================================================================= D. Register specific information: ============================================================================= Register Class Hierarchy. Classes which do not appear on the same paths in the tree below are mutually exclusive. All-regs / \ / \ Available to Not available to the compiler the compiler / \ / \ General Floating Point / \ / \ / fixed GPR / \ (Address + Data) / \ / \ Address Data / \ Caller-saved Callee-saved Each register below is marked with the lowest class which describes it. It is assumed to belong to the higher classes also. +------+------+-----+----------------+--------------+ | Name|Number|Size | Usage | Class | | | | | | | +------+------+-----+----------------+--------------+ | $zero| 00 |32 | constant 0 | Constant Data| +------+------+-----+----------------+--------------+ | $at | 01 |32 | reserved for | NA | | | | | assembler | | +------+------+-----+----------------+--------------+ | $v0 | 02 |32,64| expr eval, | caller-saved | | | | | function result| | +------+------+-----+----------------+--------------+ | $v1 | 03 |32 | expr eval, | caller-saved | | | | | function result| | +------+------+-----+----------------+--------------+ | $a0 | 04 |32,64| argument no. 1 | caller-saved | +------+------+-----+----------------+--------------+ | $a1 | 05 |32 | argument no. 2 | caller-saved | +------+------+-----+----------------+--------------+ | $a2 | 06 |32,64| argument no. 3 | caller-saved | +------+------+-----+----------------+--------------+ | $a3 | 07 |32 | argument no. 4 | caller-saved | +------+------+-----+----------------+--------------+ | $t0 | 08 |32,64| temporary | caller-saved | +------+------+-----+----------------+--------------+ | $t1 | 09 |32 | temporary | caller-saved | +------+------+-----+----------------+--------------+ | $t2 | 10 |32,64| temporary | caller-saved | +------+------+-----+----------------+--------------+ | $t3 | 11 |32 | temporary | caller-saved | +------+------+-----+----------------+--------------+ | $t4 | 12 |32,64| temporary | caller-saved | +------+------+-----+----------------+--------------+ | $t5 | 13 |32 | temporary | caller-saved | +------+------+-----+----------------+--------------+ | $t6 | 14 |32,64| temporary | caller-saved | +------+------+-----+----------------+--------------+ | $t7 | 15 |32 | temporary | caller-saved | +------+------+-----+----------------+--------------+ | $s0 | 16 |32,64| temporary | callee-saved | +------+------+-----+----------------+--------------+ | $s1 | 17 |32 | temporary | callee-saved | +------+------+-----+----------------+--------------+ | $s2 | 18 |32,64| temporary | callee-saved | +------+------+-----+----------------+--------------+ | $s3 | 19 |32 | temporary | callee-saved | +------+------+-----+----------------+--------------+ | $s4 | 20 |32,64| temporary | callee-saved | +------+------+-----+----------------+--------------+ | $s5 | 21 |32 | temporary | callee-saved | +------+------+-----+----------------+--------------+ | $s6 | 22 |32,64| temporary | callee-saved | +------+------+-----+----------------+--------------+ | $s7 | 23 |32 | temporary | callee-saved | +------+------+-----+----------------+--------------+ | $t8 | 24 |32,64| temporary | caller-saved | +------+------+-----+----------------+--------------+ | $t9 | 25 |32 | temporary | caller-saved | +------+------+-----+----------------+--------------+ | $k0 | 26 |32,64| reserved for | NA | | | | | OS kernel | | +------+------+-----+----------------+--------------+ | $k1 | 27 |32 | reserved for | NA | | | | | OS kernel | | +------+------+-----+----------------+--------------+ | $gp | 28 |32,64| global pointer | Base | +------+------+-----+----------------+--------------+ | $sp | 29 |32 | stack pointer | Base | +------+------+-----+----------------+--------------+ | $fp | 30 |32,64| frame pointer | Base | +------+------+-----+----------------+--------------+ | $ra | 31 |32 | return address | Base | +------+------+-----+----------------+--------------+ ============================================================================ E. Activation record specific information: ============================================================================ The fields in Activation record: ------------------------------- * Caller saved registers * Parameters to be passed to the function * Callee saved registers * Return value * Return address * Previous activation's pointer (SP,FP,AP) * Local frame * Position where SP points * Position where FP points * Position where AP points * Relative offsets of FP and AP with respect to SP * Direction of growth of stack frame * Direction of growth of local variable frame * Direction of growth of Parameter frame * Size of each field (with special indication for variable length field) Level 0 activation record specification of spim: ----------------------------------------------- direction of | | CALLER'S ACTIVATION RECORD | growth of | +---------------------------------+ <-- Previous SP stack | | Parameters passed on stack | | | (Accessible from frame pointer.| \|/ | Direction of growth is opposite| V | to direction of stack growth) | +---------------------------------+ <-- Current AP | Return address | , +---------------------------------+ /|\ | Dynamic chain address | | | (Pointer to caller's AR) | | | Caller's SPR, FPR | | +---------------------------------+ Register storage area. | Other caller saved registers | | |.................................| | | Callee saved registers being | \|/ | used in the callee function | V +---------------------------------+ <-- Current FP | Local variables | |(Direction of growth of frame is | | same as direction of growth of | | stack) | +---------------------------------+ <-- Current SP | | * In Spim, local variable frame, callee saved registers and parameter frame are variable length fields. Each other field is of fixed size of 1 word. * Parameter frame is at offset 0 from AP * Local variable frame is at offset 0 from FP * FP-SP= * AP-FP=+ * AP-SP_prev= Since the number of saved registers can only be known after register allocation, the arguments frame is at a variable offset from the local variables frame. GCC tries to use a single register for both argument and local variables frame. This requires defining a Hard Frame Pointer and the Frame Pointer is eliminated by computing offsets after register allocation. In Level 0.0 Level 0.1 we have assumed all registers to be caller saved registers, so size of callee saved registers will be 0 and hard frame pointer is not required.