Discussion 12

 

Instruction Set Design

 

When we design a new instruction set, we are creating the encodings for all of the instructions that a machine will be able to execute.  The process is as much art as it is engineering. Architects judge instruction set designs qualitatively by looking at how symmetric and regular they are. A symmetric instruction set avoids special conditions and cases that cause operations to operate differently on different operands. For example, in early microprocessors it was common to see registers that could be loaded from memory but not stored, and which had to be moved, using special instructions, to other registers that could be stored. In a symmetric instruction set, a register that can be stored can also be loaded, and if a value can be moved from one register to another, movement in the opposite direction is supported. A regular instruction set, operations can be applied uniformly to different operands. For example, addition is available for all lengths of integers; loads and stores of all types can refer to all data types; and so on.

 

An instruction set’s encoding is also a matter of art and engineering. Placing related instructions into a class or type together simplifies the decoding process. For example, dividing instructions into integer execute, floating point execute, load/store, and branch groups enables straightforward decoding and dispatch. It also makes life easier on the compiler writer or assembly language programmer. Some architectures begin with clean, straightforward instruction sets but evolve to include numerous special cases in their instruction sets. Other architectures, start out with irregular and asymmetric instruction sets due to sever constraints that were placed on the designers. It is rare to see an established architecture with a clean instruction set architecture (ISA).

 

Quantitatively,  we judge an instruction set by its effect on performance. Measuring ISA impact on performance is nontrivial. We would like to be able to measure the execution time for a piece of code, with and without an ISA feature. But that requires changing the ISA (usually in a software simulation) and the compiler (to take advantage of the feature). Making a simulation that accurately models all of the performance-affecting aspects of a modern processor is very difficult (even the manufacturers have trouble doing this), and changing a production-quality optimizing  compiler is also challenging.  In the past is has been common to see hand-coded routines that use a new feature, and beyond calling those library routines, it is found that a compiler cannot generate code to make use of it. Today, manufacturers are more cautious about adding new instructions or features.

 

There are fundamental parameters that must be chosen as the basis for an ISA. These include the width of the operands, the number of operands that are referenced in an instruction, the address range of the system, the number and types of operations that are supported, and the number of registers.

 

For example, with an execute instruction group that supports two sources and a destination among a file of 32 registers, 15 bits of the instruction code must be dedicated to the register references. In a 32-bit instruction, this leaves 17 bits to specify the operation and the instruction type. If there are four types (or classes) of instructions (e.g., integer execute, floating point execute, load/store, branch) then 15 bits remain for the operation. If only 16 operations are supported, then there are still 11 bits available for other uses.

 

 

Having extra bits make s it tempting to find a use for them. Let’s see what happens if we decide that some of the operations are going to work on an immediate operand in those extra bits. First of all, we can grab the 5 bits from Src0 and append them to the immediate operand field because we need only one source register when our second operand is immediate. This gives us 16 bits for immediate values, which is very nice as it can represent a short, two bytes, a Unicode character, and so on. However, we need some way to specify that this instruction has an immediate value and not a second source register. We need the Type, Dest and Src1 fields, so only the OP field remains for representing this status. With just 16 operations,  it would be difficult to dedicate a bit to indicate immediate or register operand – we would be left with just 8 distinct operations. Alternatively, we could just have a few special operations that work on immediate values, say op codes 0 – 3, and the rest refer to registers, However, this makes the instruction set irregular. Another option is to give up the idea of having 16-bit operands, and take a bit from the unused section that specifies immediate or register as Src0. All of these can work, and each one presents a set of tradeoffs. It’s up to the architects to choose the direction to follow.

 

As you can see, instruction set design is largely an exercise in balancing tradeoffs and attempting to estimate the impact. Once an architecture has been built, it is easier to evaluate the effect of a minor change. But initially it take a holistic awareness of the system and its intended applications to make decisions that seek the necessary balance.

 


© Copyright 1995, 1996, 2001 Charles C. Weems Jr. All rights reserved.


Back to Chip Weems' home page.


Back to courses index page.


Back to Computer Science Department home page.