6. Shift Instructions
Part of
the Hawk Manual

6.1. Shift Format
6.2. Left Shift
6.3. Right Shift
6.4. Bit Testing
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).
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.
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]<<s  
1 0 1 0  dst (nz)  s1 (0)  s2 (16)  ADDSL  dst,s1,s  r[dst] = r[dst]<<s + 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]'<<s) > 2^{321}  
ADDSL  N = r[dst]:31  
Z = (r[dst] = 0)  
V = ( r[dst]:31 ⊕ ( r[dst]':31 ≡ r[s1]':31 ))  
C = (r[dst]'<<s + r[s1]') > 2^{321}  
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
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]'):s1:0 ≠ 0)  
C = (r[dst]' + r[s1]'):s1  
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 integerADJUST 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
Any bit in a register can be tested using one of three instructions:
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,s1  0 ≤ b ≤ 15: s = b + 1  
1 0 1 1  0 0 0 0  s1 (nz)  s2 (16)  BITTST  s1,31s  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.