Multiplication and Division -- Binary

We have instructions for multiplying and dividing 32-bit signed integers.


Multiply Register or MR

The format for this is:

         MR    R1,R2

and it is a type RR instruction.

The first register, R1, must be an even-numbered register and represents a pair of even-and-odd adjacent registers such as 2 & 3 or 4 & 5. We temporarily think of this pair of registers as one 64-bit register (even on the left, odd on the right).

The values in registers R1+1 and R2 are multiplied. The result is a 64-bit signed integer which is then stored in registers R1 and R1+1.

Notice that the original value of register R1 is irrelevant and is replaced.

Example 1

Suppose we have the following values.

     Register 7 contains the decimal value 17 or X'00000011'.           
     Register 3 contains the decimal value 14 or X'0000000E'.

Next we execute this instruction:

         MR    6,3

Now we have the following values:

     Register 6 contains the decimal value   0 or X'00000000'.
     Register 7 contains the decimal value 238 or X'000000EE'.
     Register 3 is unchanged.

Example 2

Suppose we have the following values.

     Register 6 may have any value.
     Register 7 contains the decimal value -5 or X'FFFFFFFB'.
     Register 3 contains the decimal value  1 or X'00000001'.

Next we execute this instruction:

         MR    6,3

Now we have the following values:

     Register 6 contains the decimal value -1 or X'FFFFFFFF'.
     Register 7 is unchanged.
     Register 3 is unchanged.

Example 3

Suppose we have the following values.

     Register 6 may have any value.
     Register 7 contains the decimal value 12 or X'0000000C'.
     Register 3 contains the decimal value  1 or X'00000001'.

Next we execute this instruction:

         MR    6,3

Now we have the following values:

     Register 6 contains the decimal value 0 or X'00000000'.
     Register 7 is unchanged.
     Register 3 is unchanged.


Multiply or M

The format for this is:

         M     R,D(X,B)

and it is a type RX instruction.

The register, R, must be an even-numbered register and represents a pair of even-and-odd adjacent registers such as 2 & 3 or 4 & 5. We temporarily think of this pair of registers as one 64-bit register (even on the left, odd on the right).

The address D(X,B) should resolve to a fullword boundary.

The value in register R+1 and the fullword at the D(X,B) address are multiplied. The result is a 64-bit signed integer which is then stored in registers R and R+1.

If the address D(X,B) does not resolve to a fullword boundary, we have a specification exception (interruption code 0006).

Notice that the original value of register R is irrelevant and is replaced.


Divide Register or DR

The format for this is:

         DR    R1,R2

and it is a type RR instruction.

The first register, R1, must be an even-numbered register and represents a pair of even-and-odd adjacent registers such as 2 & 3 or 4 & 5.

The two registers R1 and R1+1 are treated temporarily as one 64-bit register (even on the left, odd on the right). The signed 64-bit value stored in it is divided by the value in register R2. The quotient is then stored in register R1+1 and the remainder is stored in register R1. That is:

Usually when we use DR, the numerator (or dividend) we care about is in register R1+1. We nonetheless have to worry about the contents of register R1. See Example 6 below.

Example 4

Suppose we have the following values.

Register 6 contains the decimal value  0 or X'00000000'.           
     Register 7 contains the decimal value 17 or X'00000011'.           
     Register 3 contains the decimal value  3 or X'00000003'.

Next we execute this instruction:

         DR    6,3

Now we have the following values:

     Register 6 contains the decimal value 2 or X'00000002'.
     Register 7 contains the decimal value 5 or X'00000005'.
     Register 3 is unchanged.

Example 5

Suppose we have the following values.

     Register 6 contains the decimal value  -1 or X'FFFFFFFF'.
     Register 7 contains the decimal value -23 or X'FFFFFFE9'.           
     Register 3 contains the decimal value   4 or X'00000004'.

Next we execute this instruction:

         DR    6,3

Now we have the following values:

     Register 6 contains the decimal value -3 or X'FFFFFFFD'.
     Register 7 contains the decimal value -5 or X'FFFFFFFB'.
     Register 3 is unchanged.

Example 6

Suppose we have the following values.

     Register 6 contains the decimal value   0 or X'00000000'.
     Register 7 contains the decimal value -16 or X'FFFFFFF0'.           
     Register 3 contains the decimal value   3 or X'00000003'.

Next we execute this instruction:

         DR    6,3

Now we have the following values:

     Register 6 is unchanged.
     Register 7 contains the decimal value 1431655760 or X'55555550'.
     Register 3 is unchanged.

This may seem surprising. The problem is that the 64-bit value in registers 6 and 7 is not -16 but instead is quite a large number, 4294967280. Remember: a signed fixed-size binary number is negative only if the leftmost bit is a 1.

Notice we do not have an ABEND here.

How can this problem be avoided? We could do the following:

         M     6,=F'1'
         DR    6,3
The effects of multiplying by 1 are

See examples 2 and 3 above.

Example 7

Suppose we have the following values.

     Register 6 may have any value.
     Register 7 may have any value.
     Register 3 contains the decimal value   0 or X'00000003'.

Next we execute this instruction:

         DR    6,3

This will cause an ABEND, as we cannot divide by 0. In particular, this is a "Fixed-Point Divide" problem, and we have Interruption Code 0009.

Example 8

Suppose we have the following values.

     Register 6 contains the decimal value  4 or X'00000004'.
     Register 7 contains the decimal value 12 or X'0000000C'.           
     Register 3 contains the decimal value  2 or X'00000002'.

Next we execute this instruction:

         DR    6,3

This will cause an ABEND, as the quotient should be X'200000006', which is too large to fit into one register. In particular, we have a "Fixed-Point Overflow" problem, and we have Interruption Code 0008.


Divide or D

The format for this is:

         D     R,D(X,B)

and it is a type RX instruction.

The register, R, must be an even-numbered register and represents a pair of even-and-odd adjacent registers such as 2 & 3 or 4 & 5.

The address D(X,B) should resolve to a fullword boundary.

If the address D(X,B) does not resolve to a fullword boundary, we have a specification exception (interruption code 0006).

The two registers R and R+1 are treated temporarily as one 64-bit register (even on the left, odd on the right). The signed 64-bit value stored in it is divided by the fullword value at the D(X,B) address. The quotient is then stored in register R+1 and the remainder is stored in register R. That is:

As with DR, we can have an ABEND due to Fixed-Point Overflow or Fixed- Point Divide problems.