9. Hawk Short Constant Instructions
Part of
the Hawk Manual
|
9.1. Short Constant Format
9.2. Truncate and Sign Extend
9.3. Branch Truncated
9.4. Add Short Immediate
07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 | 15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | |
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 in a field, from 1 to 16 where zero encodes 16. For a b-bit field, bit numbers run from 0 to b–1, so the high bit number is b–1.
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.
07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 | 15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | ||||||
0 0 0 1 | dst (nz) | 1 1 1 1 | src (16) | TRUNC | dst,b | r[dst] = r[dst]:f:0 | |||||||||||||||
0 0 0 1 | dst (nz) | 1 1 1 0 | src (16) | SXT | dst,b | r[dst] = sx(r[dst]:f: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]':f)) | ||||
C = (r[dst]':31:b ≠ 0) | ||||
The primary use of TRUNC is in truncating unsigned integers shorter forms 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. Similarly, SXT is used to truncate signed integers to shorter forms and test for information loss. SXT and TRUNC are equivalent when r[dst]:f 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.
To truncate or sign extend a register preserving more than 16 bits, use a sequence of two shift operations, 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
07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 | 15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | ||||||
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 | ||
The BTRUNC (branch truncated) instruction 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 instruction 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. The BTRUNC R3,bits instruction is equivalent to the following sequence of instructions, except that it does not alter any registers:
TRUNC R3,bits LEA R4,TABLE ADDSL R3,R4,1 JUMPS R3 TABLE:
BTRUNC is appropriate for constructing case-select control structures involving a small number of alternatives. For example, to shift R3 the number of places indicated by the least significant 2 bits of R4, this instruction seqauence can be used:
NOT R4 BTRUNC R4,2 SL R3,1 ; if R4 was 3 SL R3,1 ; if R4 was 2 or 3 SL R3,1 ; if R4 was 1 or 2 or 3 NOT R4 ; restore R4 (if needed)Other uses of BTRUNC include non-aligned memory references, where the least significant 2 bits of the address must be checked to see if EXTH can be used, or whether more complex code is required. BTRUNC can also be used in fast multiplication algorithms in order to decode the least significant digit of the multiplier.
07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 | 15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | ||||||
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) | ||||
The ADDSI (add short immediate) instruction is used to increment or decrement a the destination register r[dst] by the small constant given by 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. This is the fastest and most compact way to increment or decrement a register. The dst must be nonzero, and assemblers should forbid incrementing by zero, while they accept +8 and encode it as zero.
The condition codes 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).