9. Short Constant Instructions

Part of the Hawk Manual
by Douglas W. Jones
THE UNIVERSITY OF IOWA Department of Computer Science

Contents

9.1. Short Constant Format
9.2. Truncate and Sign Extend
9.3. Branch Truncated
9.4. Add Short Immediate


9.1. Short Constant Format

07060504 03020100 15141312 11100908
0 0 0 1 dst 1 1 - - src

Short constant format instructions hold a constant source operand used to modify the destination register.

When used for truncation or sign extension, the constant gives the count of bits to be preserved, from 1 to 16 where zero encodes 16. The bits of a b-bit field are numbered from 0 to b–1, so the highest bit preserved is numbered b–1.

if src = 0
then b = 16
else b = src

When used by the add short immediate instruction, the value zero encodes +8, so that the constant c ranges from –8 to +8 instead of the normal 2's complement range from –8 to +7.

if src = 0
then c = +8
else c = sx(src)
 

9.2. Truncate and Sign Extend

07060504 03020100 15141312 11100908                        
0 0 0 1 dst (nz) 1 1 1 1 src (16) TRUNC dst,b r[dst] = r[dst]:b–1:0
0 0 0 1 dst (nz) 1 1 1 0 src (16) SXT dst,b r[dst] = sx(r[dst]:b–1:0)

TRUNC    
SXT
N = (r[dst] < 0)  — result is negative
Z = (r[dst] = 0)  — result is zero
V = (r[dst]':31:b ≠ sx(r[dst]':b–1))
C = (r[dst]':31:b ≠ 0)
 
TRUNC (truncate) and SXT (sign extend) instructions preserve r[dst]:b–1:0 (the least significant b bits), where b is given by the src field of the instruction as a value from 1 to 16. The remaining bits, r[dst]:31:b are set to zero by TRUNC while SXT sets them equal to r[dst]:b–1 (the most significant preserved bit). Assemblers should take a bit count b from 1 to 16 as src, encoding the value 16 as zero.

The primary use of TRUNC is to truncate unsigned integers to sizes shorter than 32 bits and testing for loss of information, but it may be used anywhere a logical and with one less than a power of 2 is needed, for powers of 2 from 1 to 16.

SXT can be used to truncate two's complement signed integers to shorter sizes and test for information loss. It can also be used to convert a short signed value to its 32-bit representation. For example, after using EXTB (see Section 7.3) to extract an 8-bit byte from a word loaded from memory, SXT can be used to treat bit 7 of that byte as the sign bit.

SXT and TRUNC are equivalent when r[dst]:b–1 is zero.

After TRUNC or SXT The N and Z condition codes are set to reflect whether the result is negative or zero. C is set if any bits above the least significant b bits were nonzero, an unsigned overflow, and V is set if any bits above the least significant b bits differed from the sign of the result, a signed overflow.

With both TRUNC or SXT, the dst field must be nonzero. Attempts to use r[0] as a destination will cause an instruction trap (see Chapter 13). Assemblers should flag use of r[0] as an error.

To truncate or sign extend a register preserving more than 16 bits, use a sequence of two shift operations (see Chapter 6), testing for overflow after the first. For example, to truncate R3 to 24 bits, use:

        SL      R3,8          ; shift 8 bits left
        BCS     LOSTBITS      ; optional test for data loss
        SRU     R3,8          ; right shift, clearing top 8 bits

9.3. Branch Truncated

07060504 03020100 15141312 11100908                        
0 0 0 1 dst (nz) 1 1 0 1 src (16) BTRUNC dst,b pc=pc+((r[dst]:f:0)«1)

BTRUNC    NZVC unchanged

BTRUNC (branch truncated) truncates its operand, using the same truncation logic as TRUNC and then adds twice the truncated result to the program counter. As a result, this skips over a number of successive halfwords depending on the truncated value. Care should be taken to make sure that the succeeding instructions that may be skipped are one halfword each.

BTRUNC is appropriate for constructing case-select control structures involving a small number of consecutive alternatives. In this case, the succeeding instructions will usually be branches (see Section 12.3) For example, a 4 way case-select might look like this:

	BTRUNC  R3,2    ; select (R3) {
        BR      CASE0
        BR      CASE1
        BR      CASE2
        BR      CASE3

Sometimes, if the body of each case is just one halfword and each case ends by falling into the next, very tight code is possible For example, to shift r[3] from 0 to 3 places (see Chapter 6), with the number of bits shifted determined by the low 2 bits of r[4], this instruction seqauence can be used:

	NOT	R4
        BTRUNC  R4,2
        SL      R3,1
        SL      R3,1
        SL      R3,1

The NOT instruction above (see Section 10.2) makes this sequence shift 0 places for an initial value in r[4] of 0; omitting the not would make it shift 3 places for 0, 2 places for 1, 1 place for 2 and 0 places for 3.

Another use of BTRUNC is in fast multiplication algorithms using base 4 or base 16 (see Section 14.4).

BTRUNC R3,bits can be replaced by a 4-instruction sequence that uses two registers to hold intermediate results:

        TRUNC   R3,bits
        LEA     R4,TABLE
        ADDSL   R3,R4,1
        JUMPS   R3
TABLE:

9.4. Add Short Immediate

07060504 03020100 15141312 11100908                        
0 0 0 1 dst (nz) 1 1 0 0 src (8) ADDSI dst,c r[dst] = r[dst] + c

ADDSI     N = (r[dst] < 0)  — result is negative
Z = (r[dst] = 0)  — result is zero
V = ((r[dst]:31 ⊕ r[dst]':31) ∧ (r[dst]':31 ≡ src:3)
C = (~r[dst]:31 ∧ r[dst]':31)

ADDSI (add short immediate) is used to increment or decrement a the destination register r[dst] by the small constant given in the src field. This may vary over the range -8 to +8, encoded as a 2's complement number, except that zero is used to encode +8. Generally, ADDSI rd,x is equivalent to ADDI rd,rd,x (see Section 3.2); ADDSI is just one halfword, while ADDI is just two halfwords and able to use different registers for source and destination.

The condition codes (see Section 1.3.4.1) are set to report on the result, with N and Z reporting whether the result is negative or zero, V reporting whether two's complement overflow occurred, and C reporting whether there was a carry out of the high bit (the sign changed from 1 to 0).

Note that ADDSI sets the bcd-carry field of the processor status word (see Section 1.3.4.1). As a result, ADDSI followed by ADJUST may be used to add binary-coded decimal constants up to +7 (see Section 11.2). This does not work for adding negative BCD values represented in 10's complement form, nor does it work for excess-three representation.