Microcode, nanocode, and now millicode. What are these things?
Microcode is an on-chip program that decodes various processor instructions and operates the appropriate portions of the processor's logic to implement the requested action. Ergo, microcode is a sort of program embedded inside the processor. In very complex processors, separate programs -- nanocode -- operate sections of the processor, such as the floating-point unit or the integer unit.
Millicode, as its name implies, operates at a level outside the processor. It implements highly efficient routines for frequently called functions. Normally, when a program calls a fun
ction on a PowerPC system, it uses a set of rules that organize the target function's temporary storage into a region of memory known as a
stack frame
. (
See the figure.
) This stack frame serves as a container that preserves any non-scratchpad registers, the function's local storage, a parameter (or argument area), and a linkage area. One such rule places a number of the function's arguments into processor registers. Additional arguments (if any) spill over into the stack frame's argument area. Another rule adjusts the link register (LR) to point to the target function's address, while the LR's original contents get stored into the link area of the stack frame. Once the program sets up the stack frame, it executes a branch to the function, based on the address in the LR. When the function exits, it restores the LR (which effectively creates the return address) and executes another LR-based branch.
To reduce overhead, millicode doesn't follow these conventions. Instead, yo
u place arguments in specific registers and use a branch absolute then link instruction (
bla
) to jump to the function. This convention reduces the function-call overhead to several register loads plus a single
bla
instruction. A register-based branch (using the LR) returns execution to your program when the function exits. Such unconditional branches typically take zero cycles to execute because the processor's branch unit can resolve them well in advance. Previous 603, 603e, and 604 processors used millicode to resolve little-endian addressing. As efficient as millicode is, it can add substantial overhead if the routine gets called frequently. The 166-MHz 603e and the 166-MHz 604e now handle these addressing issues in hardware, thus boosting the efficiency of the load/store instructions, which in turn increases the speed of the processor.
BYTE Digest editors every month analyze and evaluate the best articles from Information Week, EE Times, Dr. Dobb's Journal, Network Computing, Sys Admin,
and dozens of other CMP publications—bringing
you critical news and information about wireless communication,
computer security, software development, embedded systems,
and more!