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


< Prev Contents Next >

16-/32-bit RISC

Even today, the venerable 68K is used as a measure of code density. Many consider the 68K to set the standard for acceptable embedded system code density. The 68K design team made a number of very effective architectural decisions, decisions that have proved themselves over time.

The key design parameters for the 68K was that it had a 32-bit data path (originally 32-bit registers with a 16-bit ALU and 16-bit memory interface) and 16-bit instructions. Most instructions fit into 16-bits with extensions for addressing and immediate data. This combination of 16-bit instructions and 32-bit data gave the 68K 32-bit processing power with roughly 16-bit ISA code density.

On the other hand 32-bit RISCs were designed to create a very tight register-to-ALU cycle, a fast execution. To do this RISC designers minimized the instruction set -- the less instructions, the less logic depth, and thus faster execution. These techniques resulted in much simpler ISAs, some with fewer than 50 basic instructions; and in load-store architectures where most processing takes place between registers, and the only memory operations are load/store of registers.

Crafting a 16-bit ISA from a 32-bit RISC ISA is not trivial. The smaller instruction word has smaller fields. Thus, it can only execute a smaller set of instructions using a smaller register set since the OP code field and register fields need to reduce to create 16 bit instructions.

The first dynamic 16-/32-bit RISC was the brain child of the ARM design team. They came up with Thumb, which took a very clever approach to running a 16-bit ISA. The trick was to pick a 16-bit subset of the 32-bit ARM ISA, with less registers and instructions to reduce the field sizes. All instructions, 16- and 32-bit, enter the CPU the same, but when a special mode bit is set, the decoder decodes the 16-bit ISA, not the 32-bit ISA. The decoded instructions are then passed through an expansion block, that expands the decode to the 32-bit form, and the decoded 16-bit instructions are then passed on to the next stage in the pipeline. The 16-bit instructions are retrieved, decoded and then expanded to 32-bit instructions for execution. The MIPS-16 takes a similar approach. Figure 2 shows the decode expansion block that expands the 16-bit instructions to 32-bitters.

The dynamic 16-/32-bit RISCs are different than some RISCs like the Hitachi SH series. Those have fixed 16-bit ISAs and a 32-bit datapath. The ARM Thumb and the MIPS-16 are 32-bit machines that can dynamically switch to run with a reduced 16-bit ISA. A mode or status bit sets 16 or 32-bit ISA mode. That bit cannot be set at any time during execution. It can only be set during a call or return, insuring that 16- or 32-bit ISA operation is defined at the function or subroutine level, or higher.

The key to dynamic 16-/32-bitters is their compilers. They run compiled code and the compiler compiles 16- or 32-bit ISA code. A switch or flag is set, and that indicates whether to compile a function or file as 16- or 32-bit code. With the GNU MIPS-16 assembler/compiler, the switch is -mips16'. The decision of what is 16- or 32-bit ISA code is made at compile time, not runtime. However, the generated code will set the proper ISA mode bit when switching from 32- to 16-bit code or vice versa.


< Prev Contents Next >