Evaluating Hardware/ Software Tradeoffs - Hardware extensions and the compilers that make them real


< Prev Contents Next >

MIPS-16

Figure 3:  Mapping compressed MIPS-16 instructions

The MIPS-16 ISA is the 16-bit ISA derived from the 32-bit MIPS I ISA. It supports the full range of MIPS ISAs. To fit into 16 bits, the MIPS-16 uses 5-bits for its major op code field and function field (they were 6-bits), 3-bits for the register fields (they were 5 bits). Additionally, the MIPS-16 uses only two register fields, rather than the three of the MIPS I ISA. And it shrinks the immediate value field from 16- to 5-bits. Figure 3 compares the MIPS-32 and MIPS-16 instruction fields.

The 16-bit ISA's restricted register set directly effects compiler register allocation strategy. With the normal MIPS-32 ISA, when the compiler allocates registers for a complex expression, it normally feels free to allocate a new register any time one is needed. Usually there are enough registers, and if there are not enough, if too many registers are needed, some are merged or spilled to the stack. In the MIPS-16 ISA, which has fewer registers than the 32-bit ISA, the compiler is forced to use argument registers as temporary registers.

Other changes include adding a special stack pointer instead of using a general register. The MIPS-16 only has 8 general registers, too few to use on as designated stack pointer. Figure 4  shows the MIPS-16 and MIPS-32 register usage.

Figure 4:  MIPS register mapping

Switching between the MIPS-16 and 32-bit MIPS I ISAs is done through the jump and link instructions: JALX, JALR (Jump And Link eXchange). JALX jumps and saves the next address in a link register and is used for subroutine calls. The JALR returns to the address in the link register. Using JALX, a 32-bit ISA routine can call a 16-bit ISA routine and vice versa. JALR and JR (jump return) can also set or reset the ISA mode bit. The ISA mode bit can also be changed when an exception occurs. Generally exceptions are handled by the system in full 32-bit ISA mode.

There were some interesting consequences of implementing a 16-bit MIPS ISA. For example, the MIPS-16 ISA dos not permit access to the floating-point registers. This becomes a problem since the MIPS calling convention is meant to pass floating-point values in the floating-point registers. This could be a real problem when a 32-bit MIPS-32 function calls a 16-bit MIPS-16 function and passes a floating-point argument. The MIPS-16 code cannot access that value.

We fixed the problem by making sure that the compiler emits a 32-bit stub for any 16-bit function that took a floating-point argument. The stub copies the floating-point register into regular argument registers, and that then jump to the 16-bit function. The linker arranges for all calls from 32-bit functions to go to the 32-bit stub. If the 32-bit stub is never called, the linker deletes it.

When a 16-bit function calls a function with a floating-point argument, the compiler adds a 32-bit stub. The linker arranges the function call to go through the stub if calling a 32-bit function; it will go directly to a 16-bit function.


< Prev Contents Next >