Condition codes
Mark Smotherman
Last updated: April 2004
Summary: Condition codes provide architectural elegance but are
troublesome for high-performance implementations.
UNDER CONSTRUCTION
Condition codes are extra bits kept by a processor that summarize the
results of an operation and that affect the execution of later instructions.
These bits are often collected together in a single condition or indicator
register (CR/IR) or grouped with other status bits into a status register
(PSW/PSR).
John Hennessy, et al., in the paper "Hardware/Software Tradeoffs for
Increased Performance," ASPLOS-1, Palo Alto, March 1982, pp. 2-11,
identified four uses of condition codes:
- conditional control flow (branching)
- evaluation of boolean expressions
- overflow detection
- multiprecision arithmetic
They make two good arguments against including condition codes in an
architecture:
- condition codes are a hindrance to more aggressive code scheduling
by the compiler (e.g., you cannot schedule an otherwise-independent
instruction between a compare instruction and a branch instruction
if the otherwise independent instruction also sets the condition
code); and,
- condition codes complicate a high-performance implementation in
matching the relevant conditional-code-setting instruction with the
condition-code-using instruction (as you would want to do in early
branch determination).
Dick Sites in "Alpha AXP Architecture," Digital Tech. Jrnl., special
Alpha issue, 1992, pp. 19-34, also rejects condition codes. His reason
is similar to (b) above: multiple instruction issue is limited by any
special (single-instance) or hidden (implicit) resources.
As an example of the complication that condition codes cause in
high-performance implementations, consider the S/360 Model 91 (ca. 1967),
which was the fastest S/360 family member and which had a deep pipeline.
The Model 91 would set a tag in the youngest cc-setting instruction during
decoding and broadcast a signal to reset the tags in all the older
instructions still in flight. Only the tagged instruction could write
to the condition codes.
The following sections examine architecture issues of control flow with
and without condition codes, overflow response, and multiprecision
arithmetic without an explicit carry.
Conditional control flow
The following design tree is based on Figure 6-12 in Blaauw and Brooks
(1997), which depicts making decisions in instruction sequencing:
- implied - testing and branching/trapping combined (i.e., one inst.)
- explicit - condition setting and branching/trapping decomposed
(i.e., two insts.)
- condition placed in condition code / indicators / flags
- single instance
- separate integer and floating-point condition codes
- multiple condition codes
- condition placed in extra bits in result register
- condition placed in general registers or on stack
- condition placed in memory
- condition placed in table
Blaauw and Brooks argue, based on orthogonality, for a visible and durable
condition to decouple relational operators from branching operators:
Separating the specification of a condition from the specification
of branch target improves both the understanding and the quality of
the design. Such separation is achieved by making the condition
explicit, and hence durable and visible. Any desired expression
can produce this condition; any desired branching can be specified
for this condition. (p. 354)
Note that
in section 8.1.2 of D. Sima, T. Fountain, and P. Kacuk, Advanced Computer
Architecture: A Design Space Approach, Addison-Wesley, 1997, the following
terms are used:
- direct check - implied and explicit when using a general register
- result state - for explicit when using a condition code
See also
- DeRosa and Levy, "An Evaluation of Branch Architectures," ISCA,
Pittsburgh, 1987.
- R. Russell, "The PDP-11: A case study of how not to design condition
codes," ISCA, 1978.
Some examples of implied decision style
- accumulator machines typically used conditional branches that checked
the contents of the accumulator, e.g., IAS (1946 paper, built 1952)
- Univac I (1951) - compare ACC vs. MQ and branch
- CDC 6600 (1964) - various compare and branches (ZR, NZ, PL, NG on X regs.;
EQ, ZR, NE, NZ, GE, PL, LT, NG on B regs.)
- MIPS integer branching
- integer compare against zero and branch (bgez,bgtz,blez,bltz)
- integer compare two registers and branch (beq,bne)
- integer compare two registers and trap (teq,tge,tlt,tne)
(unsigned ge and lt versions also available)
- integer compare register and immediate and trap (teqi,tgei,tlti,tnei)
(unsigned ge and lt versions also available)
Some examples of single instance of condition code
- IBM 705 (1956) - compare sets indicator registers; other instructions
do not appear to set indicators as side effects
- IBM Stretch (1961) - comparisons and other instructions set bits in
indicator register
- S/360 (1964) - comparisons (integer and FP) and other instructions
set a 2-bit (encoded) condition code
- note that MIPS FP branching uses a condition code set by an FP compare
instruction
Some examples of separate integer and FP condition codes
- SPARC
- integer condition code NVZC in PSR
- integer condition code setting is optional and is specified
a by bit in instruction format; in assembly language,
a suffix of "cc" is added to the operation mnemonic
- cmp is really subcc with resulting value discarded (sent to %g0)
- 16 integer branches (including always and never)
- 16 integer traps (including always and never)
- FP condition code ELGU (eq, lt, gt, unordered) in FSR
- FP compare instruction sets condition code
- 16 FP branches (including always and never)
Some examples of multiple condition codes
- IBM ACS, RS/6000, PPC
- SPARC v9 has four FP condition codes
- predicate registers and predication (see EPIC history for details)
more recent IBM TDBs
- multiple-field condition register where each field is set by a different
type of instruction [Vol. 25, No. 1, June 1982, pp. 136-137]
- two additional fields [Vol. 29, No. 7, December 1986, pp. 3176-3177]
- multiple-field condition register [Vol. 31, No. 2, July 1988, pp. 294-296]
Some examples of use of extra bits in result register
- poison bits and trapping (e.g., Itanium)
Some examples of use of general registers
- AMD 29K
- MIPS integer compare and set (slt,slti)
(unsigned versions also available)
Some examples of use of stack registers
- Zuse Z4 (1945, rebuilt 1950) - signum operator leaves 1/0/-1 on stack
and conditional sequencing operators inspect the stack top for 1
- B5500 (1964) - comparison pushes word on stack, condition is rightmost bit
Some examples of use of memory
Some examples of use of table
- ... are there any? ...
- ... does an ALAT qualify? ...
or the volatile register holding address during LL/SC sequence ...
Overflow detection
... tbd ...
Without an explicit overflow bit, ...
- MIPS - multiple versions of add, etc.
(add traps on overflow, addu doesn't)
Multiprecision arithmetic
... tbd ...
An explicit carry bit for multiprecision arithmetic dates
back to at least the Harvard Mark 1 (1944).
Without an explicit carry bit, Hennessy, et al., recommended that you
build multiprecision words out of 31-bit units.
John Mashey's comp.arch posts on multiprecision arithmetic in MIPS
... need to add current practice for multiprecision on MIPS/Alpha ...
(GMP is written in C)
[History page]
[Mark's homepage]
[CPSC homepage]
[Clemson Univ. homepage]
mark@cs.clemson.edu