[Next] [Next Section] [Up/Previous]

Memory-Reference Instructions

Most of the computer's instructions tell it to perform a particular basic arithmetic calculation. The form of these instructions is shown below:

In addition to the register to register instructions, and the memory-reference instructions, the diagram also illustrates certain other instructions, the decoding of which is intertwined with that of these instructions.

Because this diagram shows the instructions which make up the largest proportion of the opcode space of the system, this is an appropriate point at which to note that instructions have been designed so as to simplify determining the length of an instruction.

While the scheme is not as simple as that of the IBM 360, in which, originally, an instruction began with 00 if it was 16 bits long, 01 or 10 if it was 32 bits long, and 11 if it was 48 bits long, it still allows the length of an instruction to be determined without fully completing the decoding of an instruction.

As can be seem from the diagram above, usually

0xxxxxxxxxxxxxxx: 16-bit instruction
1xxxxxxxxxxxxxxx: 32-bit instruction

but with the exception that if an instruction begins with 10, and the last three bits, indicating the base register, are zero, then additional 16-bit instructions are indicated.

Also, instructions of the form

00101mmvssxxxxxx

are two-address instructions where the length of the instruction is specified in two parts separately, as a consequence of the addressing modes of the source and destination operands, which may be independently indicated as requiring address fields. Three of the simplest addressing modes for instructions of this type are shown in the diagram; this type of instruction will be discussed in a later section.

A further exception is not visible on this diagram. Longer instructions are indicated by their first 16 bits corresponding to a register-to-register instruction where the destination register and source register fields are identical.

In a register-to-register instruction, the source and destination registers must be different. When these two fields contain the same number, the instruction is instead decoded to provide an instruction with an advanced addressing mode, for such things as string, packed decimal, or vector operations, or to provide an instruction other than a memory-reference instruction, such as an operate instruction.

Thus, in order for an instruction to be greater than 32 bits in length, the form of the first 16 bits must be the following:

000pxxxxxxabcabc

If the bit marked p is 1, the instruction is followed by a series of additional 16-bit units of which all but the last start with 1, and the last of which starts with 0. (There may be only one such 16-bit unit, starting with zero.) If it is zero, this section of the instruction is not present.

The bits marked abc both contain the number of 16-bit units without any restriction as to their first bit which appear at the end of the instruction. If the p bit is a one, the section of the instruction it indicates precedes these halfwords.

Generally, the section of the instruction indicated by the p bit consists of halfwords which contain various fields relating to the operation to be performed, while the section indicated by the two copies of abc will chiefly consist of halfwords containing addresses.

When the p bit is a one, it is possible for the abc fields to both contain zero, for this format, since that may still result in an instruction longer than 32 bits.


When the p bit is a zero, and the two abc fields both contain 001, as this format would normally indicate an instruction 32 bits in length by the scheme above, and would therefore be redundant, it indicates instead that the instruction will be a three-address instruction with fields which indicate separately if address values are appended to the instruction for the source, operand, and destination operands of the instruction. The PDP-11 is a well-known example of an architecture with this type of instruction; here, the address modes are more complicated, as this instruction format is used for vector arithmetic.

These instructions indicate the addressing modes used in the same way as the two-address instructions beginning with 00111xxxxxxxxxxx except with some of the relevant bits being in different positions.

A two-address instruction has only source and destination operands; in the case of a subtract instruction, the contents of the source operand are subtracted from the contents of the destination operand, and the result is placed in the destination operand. In a three-address subtract instruction, the contents of the source operand are subtracted from the contents of the operand operand, and the result is placed in the destination operand.

When the p bit is a zero, and the two abc fields both contain 000, this arrangement is also redundant, as it would indicate an instruction 16 bits in length. Therefore, this format instead indicates the 16-bit halfword is a 16-bit prefix which precedes an instruction the length of which is determined normally. This allows the potential of future expansion of the opcode space.

Additionally, 32-bit prefixes are also possible; what would be a 32-bit instruction of the form:

1100001xxxxxx000 xxxxxxxxxxxxxxxx

is instead a 32-bit prefix for an instruction, again, one the length of which is decoded normally.


One ingenious idea that allows some opcode space to be obtained from nearly any instruction format without any compromise was used in the SEL 32 series of computers, by Systems Engineering Laboratories. This firm made minicomputers, and it was located in Fort Lauderdale, Florida and NASA was one of its main customers.

Instructions were made more compact by only allowing aligned operands to be addressed. The unused least significant bits of the address in most cases were used to help indicate operand type in the instruction. (This idea is used not only in the regular memory-reference instructions, but in the 16-bit short format memory-reference instructions, and a similar principle is used to halve the amount of opcode space taken up by the shift instructions.)

The dR and sR fields, giving the destination register and the source register for an operation, can contain any value from 0 to 7.

The sB field, indicating the base/address register whose contents indicate the general area in memory from which a memory operand comes, can only contain a value from 1 to 7. When the sB field is zero in what would have been a memory-reference instruction with single-byte operands, this indicates the instruction only occupies a single 16-bit unit in memory, and is a branch instruction. When the sB field is zero in what would have been a memory-reference instruction with other fixed-point operands, this also indicates the instruction only occupies a single 16-bit unit in memory, but in this case it is a floating-point single-operand instruction. When the sB field is zero for what would have been a floating-point memory-reference instruction, the instruction still occupies two 16-bit units in memory, and is an instruction which performs either a load and store, for any of the basic fixed-point or floating-point types, from the appropriate register zero, to any memory address without alignment restrictions.

Also, and more simply, in a memory-reference instruction, the sX field, which indicates the arithmetic/index register whose contents are used to select the element of an array used as a memory operand, can only cause arithmetic/index registers 1 through 7 to act as the index register for the instruction. If this field contains zero, this indicates that indexing does not take place.

Note that normal memory-reference instructions will be incompatible with Subdivided Double operation in those cases where it causes double-precision operands to be reduced in size, since address values will not be available for all positions in memory containing an aligned double-precision value.

Register to register instructions, and unaligned load/store instructions, as well as scratchpad to register instructions, can still be used.

The opcodes for memory-reference, register-to-register, and short format memory-reference instructions are:

Memory Reference       Register   Scratchpad
--------------------   ------     ------
100xxx xxxxxx          0000xx     0600xx     SWB    Swap Byte
101xxx xxxxxx          0001xx     0601xx     CB     Compare Byte
102xxx xxxxxx          0002xx     0602xx     LB     Load Byte
103xxx xxxxxx                     0603xx     STB    Store Byte
104xxx xxxxxx          0004xx     0604xx     AB     Add Byte
105xxx xxxxxx          0005xx     0605xx     SB     Subtract Byte

110xxx xxxxxx          0010xx     0610xx     IB     Insert Byte
111xxx xxxxxx          0011xx     0611xx     UCB    Unsigned Compare Byte
112xxx xxxxxx          0012xx     0612xx     ULB    Unsigned Load Byte
113xxx xxxxxx          0013xx     0613xx     XB     XOR Byte
114xxx xxxxxx          0014xx     0614xx     NB     AND Byte
115xxx xxxxxx          0015xx     0615xx     OB     OR Byte

117xxx xxxxxx          0017xx     0617xx     STGB   Store if Greater Byte

120xxx xxxxx0 (xxx0)   0020xx     0620xx     SWH    Swap Halfword
121xxx xxxxx0 (xxx0)   0021xx     0621xx     CH     Compare Halfword
122xxx xxxxx0 (xxx0)   0022xx     0622xx     LH     Load Halfword
123xxx xxxxx0 (xxx0)              0623xx     STH    Store Halfword
124xxx xxxxx0 (xxx0)   0024xx     0624xx     AH     Add Halfword
125xxx xxxxx0 (xxx0)   0025xx     0625xx     SH     Subtract Halfword
126xxx xxxxx0 (xxx0)   0026xx     0626xx     MH     Multiply Halfword
127xxx xxxxx0 (xxx0)   0027xx     0627xx     DH     Divide Halfword

130xxx xxxxx0 (xxx0)   0030xx     0630xx     IH     Insert Halfword
131xxx xxxxx0 (xxx0)   0031xx     0631xx     UCH    Unsigned Compare Halfword
132xxx xxxxx0 (xxx0)   0032xx     0632xx     ULH    Unsigned Load Halfword
133xxx xxxxx0 (xxx0)   0033xx     0633xx     XH     XOR Halfword
134xxx xxxxx0 (xxx0)   0034xx     0634xx     NH     AND Halfword
135xxx xxxxx0 (xxx0)   0035xx     0635xx     OH     OR Halfword
136xxx xxxxx0 (xxx0)   0036xx     0636xx     MEH    Multiply Extensibly Halfword
137xxx xxxxx0 (xxx0)   0037xx     0637xx     DEH    Divide Extensibly Halfword

120xxx xxxxx1 (xx01)   0040xx     0640xx     SW     Swap
121xxx xxxxx1 (xx01)   0041xx     0641xx     C      Compare
122xxx xxxxx1 (xx01)   0042xx     0642xx     L      Load
123xxx xxxxx1 (xx01)              0643xx     ST     Store
124xxx xxxxx1 (xx01)   0044xx     0644xx     A      Add
125xxx xxxxx1 (xx01)   0045xx     0645xx     S      Subtract
126xxx xxxxx1 (xx01)   0046xx     0646xx     M      Multiply
127xxx xxxxx1 (xx01)   0047xx     0647xx     D      Divide

131xxx xxxxx1 (xx01)   0051xx     0651xx     UC     Unsigned Compare

133xxx xxxxx1 (xx01)   0053xx     0653xx     X      XOR
134xxx xxxxx1 (xx01)   0054xx     0654xx     N      AND
135xxx xxxxx1 (xx01)   0055xx     0655xx     O      OR
136xxx xxxxx1 (xx01)   0056xx     0656xx     ME     Multiply Extensibly
137xxx xxxxx1 (xx01)   0057xx     0657xx     DE     Divide Extensibly

120xxx xxxxx3 (x011)   0060xx     0660xx     SWL    Swap Long
121xxx xxxxx3 (x011)   0061xx     0661xx     CL     Compare Long
122xxx xxxxx3 (x011)   0062xx     0662xx     LL     Load Long
123xxx xxxxx3 (x011)              0663xx     STL    Store Long
124xxx xxxxx3 (x011)   0064xx     0664xx     AL     Add Long
125xxx xxxxx3 (x011)   0065xx     0665xx     SL     Subtract Long
126xxx xxxxx3 (x011)   0066xx     0666xx     ML     Multiply Long
127xxx xxxxx3 (x011)   0067xx     0667xx     DL     Divide Long

131xxx xxxxx3 (x011)   0071xx     0670xx     UCL    Unsigned Compare Long

133xxx xxxxx3 (x011)   0073xx     0672xx     XL     XOR Long
134xxx xxxxx3 (x011)   0074xx     0673xx     NL     AND Long
135xxx xxxxx3 (x011)   0075xx     0674xx     OL     OR Long
136xxx xxxxx3 (x011)   0076xx     0675xx     MEL    Multiply Extensibly Long
137xxx xxxxx3 (x011)   0077xx     0677xx     DEL    Divide Extensibly Long

140xxx xxxxx0 (xxx0)   0100xx     0700xx     SWM    Swap Medium
141xxx xxxxx0 (xxx0)   0101xx     0701xx     CM     Compare Medium
142xxx xxxxx0 (xxx0)   0102xx     0702xx     LM     Load Medium
143xxx xxxxx0 (xxx0)              0703xx     STM    Store Medium
144xxx xxxxx0 (xxx0)   0104xx     0704xx     AM     Add Medium
145xxx xxxxx0 (xxx0)   0105xx     0705xx     SM     Subtract Medium
146xxx xxxxx0 (xxx0)   0106xx     0706xx     MM     Multiply Medium
147xxx xxxxx0 (xxx0)   0107xx     0707xx     DM     Divide Medium

150xxx xxxxx0 (xxx0)   0110xx                MEUM   Multiply Extensibly Unnormalized Medium
151xxx xxxxx0 (xxx0)   0111xx                DEUM   Divide Extensibly Unnormalized Medium
152xxx xxxxx0 (xxx0)   0112xx                LUM    Load Unnormalized Medium
153xxx xxxxx0 (xxx0)   0113xx                STUM   Store Unnormalized Medium
154xxx xxxxx0 (xxx0)   0114xx                AUM    Add Unnormalized Medium
155xxx xxxxx0 (xxx0)   0115xx                SUM    Subtract Unnormalized Medium
156xxx xxxxx0 (xxx0)   0116xx                MUM    Multiply Unnormalized Medium
157xxx xxxxx0 (xxx0)   0117xx                DUM    Divide Unnormalized Medium

140xxx xxxxx1 (xx01)   0120xx     0710xx     SWF    Swap Floating
141xxx xxxxx1 (xx01)   0121xx     0711xx     CF     Compare Floating
142xxx xxxxx1 (xx01)   0122xx     0712xx     LF     Load Floating
143xxx xxxxx1 (xx01)              0713xx     STF    Store Floating
144xxx xxxxx1 (xx01)   0124xx     0714xx     AF     Add Floating
145xxx xxxxx1 (xx01)   0125xx     0715xx     SF     Subtract Floating
146xxx xxxxx1 (xx01)   0126xx     0716xx     MF     Multiply Floating
147xxx xxxxx1 (xx01)   0127xx     0717xx     DF     Divide Floating

150xxx xxxxx1 (xx01)   0130xx                MEU    Multiply Extensibly Unnormalized
151xxx xxxxx1 (xx01)   0131xx                DEU    Divide Extensibly Unnormalized
152xxx xxxxx1 (xx01)   0132xx                LU     Load Unnormalized
153xxx xxxxx1 (xx01)   0133xx                STU    Store Unnormalized
154xxx xxxxx1 (xx01)   0134xx                AU     Add Unnormalized
155xxx xxxxx1 (xx01)   0135xx                SU     Subtract Unnormalized
156xxx xxxxx1 (xx01)   0136xx                MU     Multiply Unnormalized
157xxx xxxxx1 (xx01)   0137xx                DU     Divide Unnormalized

140xxx xxxxx3 (x011)   0140xx     0720xx     SWD    Swap Double
141xxx xxxxx3 (x011)   0141xx     0721xx     CD     Compare Double
142xxx xxxxx3 (x011)   0142xx     0722xx     LD     Load Double
143xxx xxxxx3 (x011)              0723xx     STD    Store Double
144xxx xxxxx3 (x011)   0144xx     0724xx     AD     Add Double
145xxx xxxxx3 (x011)   0145xx     0725xx     SD     Subtract Double
146xxx xxxxx3 (x011)   0146xx     0726xx     MD     Multiply Double
147xxx xxxxx3 (x011)   0147xx     0727xx     DD     Divide Double

150xxx xxxxx3 (x011)   0150xx                MEUD   Multiply Extensibly Unnormalized Double
151xxx xxxxx3 (x011)   0151xx                DEUD   Divide Extensibly Unnormalized Double
152xxx xxxxx3 (x011)   0152xx                LUD    Load Unnormalized Double
153xxx xxxxx3 (x011)   0153xx                STUD   Store Unnormalized Double
154xxx xxxxx3 (x011)   0154xx                AUD    Add Unnormalized Double
155xxx xxxxx3 (x011)   0155xx                SUD    Subtract Unnormalized Double
156xxx xxxxx3 (x011)   0156xx                MUD    Multiply Unnormalized Double
157xxx xxxxx3 (x011)   0157xx                DUD    Divide Unnormalized Double

140xxx xxxxx7 (0111)   0160xx     0730xx     SWQ    Swap Quad
141xxx xxxxx7 (0111)   0161xx     0731xx     CQ     Compare Quad
142xxx xxxxx7 (0111)   0162xx     0732xx     LQ     Load Quad
143xxx xxxxx7 (0111)              0733xx     STQ    Store Quad
144xxx xxxxx7 (0111)   0164xx     0734xx     AQ     Add Quad
145xxx xxxxx7 (0111)   0165xx     0735xx     SQ     Subtract Quad
146xxx xxxxx7 (0111)   0166xx     0736xx     MQ     Multiply Quad
147xxx xxxxx7 (0111)   0167xx     0737xx     DQ     Divide Quad

150xxx xxxxx7 (0111)   0170xx                MEUQ   Multiply Extensibly Unnormalized Quad
151xxx xxxxx7 (0111)   0171xx                DEUQ   Divide Extensibly Unnormalized Quad
152xxx xxxxx7 (0111)   0172xx                LUQ    Load Unnormalized Quad
153xxx xxxxx7 (0111)   0173xx                STUQ   Store Unnormalized Quad
154xxx xxxxx7 (0111)   0174xx                AUQ    Add Unnormalized Quad
155xxx xxxxx7 (0111)   0175xx                SUQ    Subtract Unnormalized Quad
156xxx xxxxx7 (0111)   0176xx                MUQ    Multiply Unnormalized Quad
157xxx xxxxx7 (0111)   0177xx                DUQ    Divide Unnormalized Quad

The opcodes for the unaligned load/store instructions are:

142xx0   UALH   Unaligned Load Halfword
143xx0   UASTH  Unaligned Store Halfword
144xx0   UAL    Unaligned Load
145xx0   UAST   Unaligned Store
146xx0   UALL   Unaligned Load Long
147xx0   UASTL  Unaligned Store Long
150xx0   UALM   Unaligned Load Medium
151xx0   UASTM  Unaligned Store Medium
152xx0   UALF   Unaligned Load Floating
153xx0   UASTF  Unaligned Store Floating
154xx0   UALD   Unaligned Load Double
155xx0   UASTD  Unaligned Store Double
156xx0   UALQ   Unaligned Load Quad
157xx0   UASTQ  Unaligned Store Quad

The opcodes for the scratchpad load/store instructions are:

042xx0   SLH   Scratchpad Load Halfword
043xx0   SSTH  Scratchpad Store Halfword
044xx0   SL    Scratchpad Load
045xx0   SST   Scratchpad Store
046xx0   SLL   Scratchpad Load Long
047xx0   SSTL  Scratchpad Store Long
050xx0   SLM   Scratchpad Load Medium
051xx0   SSTM  Scratchpad Store Medium
052xx0   SLF   Scratchpad Load Floating
053xx0   SSTF  Scratchpad Store Floating
054xx0   SLD   Scratchpad Load Double
055xx0   SSTD  Scratchpad Store Double
056xx0   SLQ   Scratchpad Load Quad
057xx0   SSTQ  Scratchpad Store Quad

It is intended that the 64 scratchpad registers can be used to keep values with which a program is currently working, so that references to memory can be kept to a minimum. Thus, although memory-reference instructions also include arithmetic operations, unlike the case on a RISC architecture, the motivation behind a load/store architecture is still accepted as valid.

In the instruction mnemonics, "Long" refers to 64-bit integers, "Medium" to 48-bit floating-point numbers, "Floating" to 32-bit single-precision floating-point numbers, and "Quad" to 128-bit extended-precision floating-point numbers.

Integer operations working with long, or 64-bit integers, have as their destination a pair of registers, beginning with an even-numbered register. The location of an operand in memory can begin with any byte, as addresses are byte addresses, but there may be a performance penalty if an operand is fetched from an unaligned location. In the case of floating-point numbers of the medium type, 48 bits in length, an aligned operand is one that begins on the boundary of a unit of 16 bits; for other types, an aligned operand is one whose address is an integer multiple of its length in bytes, so that all memory could be evenly divided into units of that length with no bytes left over at the beginning or the end. Note that it may be attempted by an implementation to fetch more than 16 bits of a medium floating-point number in a single operation, in which case a performance penalty may be experienced on aligned operands on this type which cross a block boundary; the rules for this would be both more complicated and implementation-dependent.

For integers shorter than 32 bits, the insert and unsigned load instructions are used as possible alternatives to the load instruction. The difference between the three instructions is as follows:

The load instruction performs sign extension. A quantity loaded into a 32-bit register is loaded into its rightmost, or least significant, bits, and the first bit of that quantity is also used as the value to which to set all the bits to the left of those filled by the quantity. This ensures that a negative number represented in a variable occupying less than 32 bits of memory is converted to the same negative number in 32-bit form.

The unsigned load instruction fills the bits to the left of the number with zeroes. This allows using variables to represent positive numbers only, and recovering the use of the first bit to allow larger positive numbers to be represented.

The insert instruction does not alter the bits to the left of the number. This allows a 32-bit number to be built up out of smaller pieces.

Other instructions that may need some explanation are as follows:

The compare instruction sets certain status bits in the same way that an ideal subtraction would set them. That is, the status bits indicate "negative" if the destination is less than the source, "zero" if they are equal, and "positive" if the destination is larger than the source, even if performing an actual subtraction for the same argument type would result in an overflow.

The unsigned compare instruction treats its operands as unsigned numbers, since this makes a difference in what the result of a comparison would be, even though two's complement representation means that a subtraction produces the same resulting pattern of bits in both cases.

The multiply extensibly instruction has a destination which is as long as the source on entry, but twice as long as its source on exit. This means that it produces a double-length product of two values, allowing it to be used in performing multi-precision arithmetic.

The divide extensibly instruction has a destination which is twice as long as the source on entry, and which consists of two consecutive registers, or groups of registers, the first twice as long as the source, and the second as long as the source, on exit. It divides the destination by the source, and places the quotient in the first part of the destination, while leaving the remainder in the second, shorter, part of the destination.

Note that because not only the dividend, but also the quotient, is twice as long as the divisor and the remainder with this instruction, the condition known as a "divide check", where a large dividend and a small divisor results in a quotient that will not fit into the result field on exit cannot occur.

The other instructions are self-explanatory.

The swap instruction exchanges the contents of the source and destination.

Add, subtract, multiply, and divide perform the indicated operation, producing results of the same type as their operands.

AND, OR, and XOR perform the basic logical operations:

 a  b    a AND b    a OR b    a XOR b
--------------------------------------
 0  0       0         0          0
 0  1       0         1          1
 1  0       0         1          1
 1  1       1         1          0

in a bitwise fashion on their operands, storing the result in the destination.

A store instruction takes the value at the location specified by the destination field, and stores it at the location specified by the source field. By reversing the normal uses of destination and source, it allows values in registers to be written back out to memory.

Not all the possible combinations of the bits shown above are valid instructions. The Insert and Unsigned Load instructions only apply to byte and halfword operands. Also, Multiplication and division are not provided for byte operands. Instead, the instruction that would have been Divide Extensibly Byte is Store if Greater Byte: this instruction compares the destination byte (which is in a register) to the source byte (which may be in memory), and if the source byte is less than the destination byte, the byte at the destination is copied to the source location, overwriting its contents. This specialized instruction is used to allow semaphores to be used to control the sharing of resources between processes.

Unnormalized Floating Point Instructions

When the computer is operating on floating-point numbers in IEEE 754 format, these instructions are, of course, not available, since the leading 1 bit of the mantissa is suppressed, which requires that the number must be normalized, except in the special case of gradual underflow.

However, this architecture offers the option of changing the mode of floating-point operation to use other floating-point formats, in which numbers may generally be represented in an unnormalized form.

Unnormalized add or subtract instructions operate by first aligning the operand with the lower exponent with the other operand, and then performing the addition or subtraction on the mantissa portion of the arguments. If a carry out of the mantissa results, a single right shift, with adjustment of the exponent, is performed; otherwise, no repositioning of the mantissa is performed.

Unnormalized multiply or divide instructions produce a result which has either as many leading zeroes as or one less leading zero than that of the operand with the greater number of leading zeroes, so as to correctly indicate the significance of the result. The number of leading zeroes will be the same if the mantissa of the result is equal to or greater than the mantissa of the operand with the greater number of leading zeroes (in the case where both operands have the same number of leading zeroes, if the mantissa of the operand is equal to or greater than the mantissas of both operands), and it will be one less otherwise. Thus, these instructions, unlike the unnormalized add and subtract instructions, do not work by merely omitting a postnormalization step; instead, they are specifically designed to support significance arithmetic.

Significance arithmetic is one method of allowing a computer to keep track of ongoing errors in a calculation. Other methods of doing this are also available, significance arithmetic is considered by some to be flawed, and at least one of the other methods of doing this, interval arithmetic, tends to be acknowledged as having a somewhat greater degree of mathematical validity than significance arithmetic, although it, too, is considered to be of limited benefit rather than approaching the effectiveness of a panacea in this area.

Despite the fact that these concerns have some validity, the simple form of significance arithmetic that can be obtained through unnormalized arithmetic is considerably more amenable to a hardware implementation than most other possible methods. The IBM 7030, or STRETCH, had an option of adding a constant value, termed a noise value, to the last bits of floating-point numbers; thus, this option was equivalent to the method, available today on IEEE-754-compliant systems today of running the same program with different rounding modes selected, although it resembles a different proposed method, of appending random noise bits to the ends of floating-point numbers.

The major limitation of significance arithmetic is that it will indicate when precision is lost in an individual step of a calculation, but it will not indicate how error accumulates due to the involvement of a large number of quantities of limited accuracy in a calculation. This limitation is not entirely a bad thing, as it does not prevent significance arithmetic from pointing out correctable deficiencies in programs, while still permitting that form of arithmetic to be used even with computations such as simulations, from which useful data can be obtained, even though the final "result", in the sense of the state of the system, is nonsense. That is, a simulation of the Earth's atmosphere can still be used to learn general facts about how different types of weather systems behave, even if it is allowed to run past the amount of simulated time for which it could, if loaded with the actual present state of the Earth's atmosphere, yield accurate weather forecasts. (A full discussion of chaos theory is beyond the scope of this section.)

Note that there is one circumstance under which an unnormalized arithmetic instruction will not retain significance, but will instead post-normalize despite the fact that this will indicate the presence of nonexistent significance in this number: that is when the result is near the upper end of the valid exponent range, and an unnormalized result would lead to exponent overflow.

The unnormalized multiply extensibly and divide extensibly instructions behave like the analogous operations on integers, where the mantissa portions of the arguments are the integers, and the exponents are adjusted so as to indicate the numerical magnitude of the result. Where numbers occupying a pair of registers are generated, both have an exponent part, and the difference between the two exponents reflects the precision of the floating-point type in use. Fixed-point overflow of the exponent is allowed and ignored, and, where a special value of the exponent is used to indicate symbols representing "not-a-number" (NaN) values, that value is skipped.

Unlike the integer multiply extensibly and divide extensibly instructions, their operands always consist of multiple registers at the given precision; a double-length operand is never a single register at a higher precision. Thus, these instructions always behave like Multiply Extensibly and Divide Extensibly, never like Multiply Extensibly Halfword and Divide Extensibly Halfword, even when the basic type does not have the full 128-bit length of a floating-point register.

In an unnormalized multiply extensibly instruction, if the destination is in register N, the product is in registers N and N+1; register N+1 contains an exponent equal to the sum of the exponents of the arguments, and register N has an adjusted exponent which may be incorrect if a fixed-point overflow took place.

In an unnormalized divide extensibly instruction, when the destination field of the instruction specifies register N, the dividend is in register N and N+1, and the exponent in register N is the one considered as being valid; after the operation, registers N and N+1 contain the quotient, which is not rounded, unlike the result of a regular unnormalized divide instruction, and register N+2 contains the remainder.

It is these instructions, rather than the simple multiply unnormalized and divide unnormalized instructions, that work by omitting postnormalization, because their purpose is to facilitate software multi-precision floating-point operations.

The Multiply Extensibly Unnormalized and Divide Extensibly Unnormalized instructions are unavailable, even though the other unnormalized operations are available, with the Modified Comprehensive, Modified Standard, and Modified Native formats. However, if neither Extremely Gradual Underflow nor Extremely Gradual Overflow is enabled, they are available, along with the other unnormalized operations, for the Native format, and if these features, and Hyper-Gradual Overflow and Hyper-Gradual Underflow as well are all turned off, they are also available, along with the other unnormalized operations, for the Comprehensive format.

Note that there are no unnormalized single-operand instructions. Dividing a number by itself will provide a one with the same number of significant digits as the original number, and this can be multiplied by the result of a conventional single-operand instruction to produce a result with the desired significance. This technique is, however, not applicable to all the single-operand instrcutions; the logarithm function is an obvious case where a special rule applies to the number of significant bits in the logarithm of a number with a given number of significant bits.

The more straightforwards operate instructions will be discussed in the next section, such as the jump instruction and memory-reference instructions for packed decimal and character-string types.


[Next] [Next Section] [Up/Previous]