# 6. Shift Instructions

## Contents

6.1. Shift Format
6.2. Left Shift
6.3. Right Shift
6.4. Bit Testing

## 6.1. Shift Format

 07 06 05 04 03 02 01 00 15 14 13 12 11 10 09 08 1 0 - - dst s1 s2

Shift instructions are 16 bits each, specifying a source register (s1), a destination register (dst) and a shift count s derived from (s2).

if (s2 ≠ 0)
then s = s2
else s = 16

Note that shift counts from 1 to 15 use the conventional binary encoding, but a count of 16 is encoded as zero. Assemblers should automatically limit shift counts to the range 1 to 16 and take care of the encoding.

## 6.2. Left Shift

 07 06 05 04 03 02 01 00 15 14 13 12 11 10 09 08 1 0 1 1 dst (x) s1 (nz) s2 (16) MOVESL dst,s1,s r[dst] = r[s1]<

 MOVESL N = r[dst]:31 — result is negative Z = (r[dst] = 0) — result is zero V = (r[dst]:31 ≠ r[src]':31) C = (r[s1]'< 232-1 ADDSL N = r[dst]:31 Z = (r[dst] = 0) V = ( r[dst]:31 ⊕ ( r[dst]':31 ≡ r[s1]':31 )) C = (r[dst]'< 232-1

MOVESL (move and shift left) moves an operand from the source register r[s1] to register r[dst] while shifting left. The source must not be r[0]; if r[0] is used, it will cause an illegal instruction trap (see Chapter 13). Assemblers should flag MOVESL Rd,R0,c as an error.

ADDSL (add and shift left) first shifts the destination register r[dst] left and then adds in the source register r[s1]. The destination must not be r[0]; if r[0] is used, it will cause an illegal instruction trap (see Chapter 13). Assemblers should flag ADDSL R0,Rs,c as an error.

After MOVESL and ADDSL, the conditon codes will be set to reflect the result; if any one bits are shifted out of r[dst] or if the add results in a carry out, the C bit will be set; if the sign of r[dst] is different from the expected sign, the V bit will be set, and N and Z will be set if the result is negative or zero.

When r[0] is used as a source register for ADDSL, the constant zero is used. The net result is that the destination register r[dst] is simply shifted left. Because of this, assemblers should support SL Rd,c (shift left) as a synonym for ADDSL Rd,R0,c.

 07 06 05 04 03 02 01 00 15 14 13 12 11 10 09 08 1 0 1 0 dst (nz) 0 0 0 0 s2 (16) SL dst,s r[dst] = r[dst] << s

ADDSL is useful for array indexing. Given that R3 points to an array and R4 contains a displacement into the array, if array elements have sizes that are powers of two, ADDSL R4,R3,c can be used to compute the address of the correct array element in R4.

Single ADDSL and SL instructions can be used to multiply by many common constants (see Section 14.1):

```        SL     R1,1       ; multiply R1 by 2
ADDSL  R1,R1,1    ; multiply R1 by 3
SL     R1,2       ; multiply R1 by 4
ADDSL  R1,R1,2    ; multiply R1 by 5
SL     R1,3       ; multiply R1 by 8
ADDSL  R1,R1,3    ; multiply R1 by 9
```

## 6.3. Right Shift

 07 06 05 04 03 02 01 00 15 14 13 12 11 10 09 08 1 0 0 1 dst (x) s1 (0) s2 (16) ADDSR dst,s1,s r[dst] = (r[dst]+r[s1])>>s 1 0 0 0 dst (x) s1 (0) s2 (16) ADDSRU dst,s1,s r[dst] = (r[dst]+r[s1])>>>s

 ADDSR    ADDSRU N = r[dst]:31 — result is negative Z = (r[dst] = 0) — result is zero V = ((r[dst]' + r[s1]'):s-1:0 ≠ 0) C = (r[dst]' + r[s1]'):s-1

ADDSR (add and shift right) ADDSRU (add and shift right, unsigned) both add r[src] to r[dst] and then shift r[dst] to the right. ADDSR uses a signed shift, duplicating the sign bit, while ADDSRU uses an unsigned shift, shifting zeros into the left end of the result. The intermediate result between the add and shift is a 33 bit quantity, and as a result, overflow will not occur.

After ADDSR and ADDSRU, N and Z will be set as usual to report results that are negative or zero. Note that ADDSR never has a negative result. V will be set if any one bits are shifted out of the result, and C will be set to the last bit shifted out.

When r[0] is used as a source register for ADDSR or ADDSRU, the constant zero is used. The net result is that the destination register r[dst] is simply shifted right. Because of this, assemblers should support SR Rd,c (shift right) as a synonym for ADDSR Rd,R0,c and SRU Rd,c (shift right unsigned) as a synonym for ADDSRU Rd,R0,c.

 07 06 05 04 03 02 01 00 15 14 13 12 11 10 09 08 1 0 0 1 dst (x) 0 0 0 0 s2 (16) SR dst,s r[dst] = r[dst] >> s 1 0 0 0 dst (x) 0 0 0 0 s2 (16) SRU dst,s r[dst] = r[dst] >>> s

SRU allows fast division of unsigned numbers by powers of two (see Section 14.1).

```        SRU    R1,1       ; unsigned divide by 2, truncated
SRU    R1,2       ; unsigned divide by 4, truncated
SRU    R1,3       ; unsigned divide by 8, truncated
```

ADDC can be used to round the quotient to the nearest integer (see Section 10.3):

```        SRU    R1,1       ; unsigned divide by 2, truncated
ADDC   R1,R0      ; round to nearest integer
```

SR allows division of signed numbers by powers of two, but note that the result will be truncated down toward negative values, not truncated toward zero. Thus (–3)/2 will be –2 with a remainder of 1 instead of –1 with a remainder of –1.

```        SR     R1,1       ; signed divide by 2, truncated down
SR     R1,2       ; signed divide by 4, truncated down
```

ADDC works with SR to round the result to the nearest integer:

```        SR     R1,1       ; unsigned divide by 2, truncated
ADDC   R1,R0      ; round to nearest integer
```
ADJUST works with SR to truncate the result toward zero (see Section 11.2):
```        SR     R1,2       ; unsigned divide by 4, truncated
ADJUST R1,SSQ     ; truncate result toward zero
```

## 6.4. Bit Testing

Any bit in a register can be tested using one of three instructions:

• To test bit b in the range 0 to 15, use ADDSR R0,src,b+1 to move this bit to the C condition code (see Section 6.3).

• To test bit b in the range 16 to 30, use MOVESL R0,src,31-b to move this bit to the N condition code (see Section 6.2).

• To test bit 31, use MOVECC R0,src to move this bit to the N condition code. (see Section 2.2).

In each case, the test is done with register zero as the destination register. It is confusing that a different condition code is set when testing different bits of a word. To simplify this, assemblers should support BITTST src,b as a synonym for one of the above, depending on the bit number b being tested.

 07 06 05 04 03 02 01 00 15 14 13 12 11 10 09 08 1 0 0 1 0 0 0 0 s1 (0) s2 (16) BITTST s1,s-1 0 ≤ b ≤ 15: s = b + 1 1 0 1 1 0 0 0 0 s1 (nz) s2 (16) BITTST s1,31-s 16 ≤ b ≤ 30: s = 31 - b 1 1 1 1 0 0 0 0 1 1 1 0 x BITTST x,31 b = 31

The assembler should generate one or the other of the above BITTST instructions, depending on the bit number provided. BITTST r,0 tests the least significant bit and BITTST r,31 tests the most significant bit.

Because the condition code to be tested depends on the bit that was tested, BITTST should define or redefine the BBS (branch on bit set) instruction to be equivalent to either BCS or BNS, and the BBR (branch on bit reset) instruction to be equivalent to either the BCR or BNR instruction, depending on the bit tested (see Section 12.2). BITTST followed immediately by BBS or BBR will always check the correct condition code.