8. Hawk Add and Subtract Instructions
Part of
the Hawk Manual
|
8.1. Add and Subtract Format
8.2. Add and Subtract
07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 | 15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | |
0 0 1 - | dst | s1 | s2 |
Three-register instructions are 16 bits each, specifying two source registers and a destination register. The ADD and SUB instructions are perhaps the most obvious instructions in the entire Hawk architecture.
07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 | 15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | ||||||
0 0 1 1 | dst (x) | s1 (nz) | s2 (nz) | ADD | dst,s1,s2 | r[dst] = r[s1] + r[s2] | |||||||||||||||
0 0 1 0 | dst (x) | s1 (0) | s2 (nz) | SUB | dst,s1,s2 | r[dst] = r[s1] – r[s2] |
ADD | N = r[dst]:31 | — result is negative | ||
Z = (r[dst] = 0) | — result is zero | |||
V = (( r[dst]:31 ⊕ r[s1]':31 ) ∧ ( r[s1]':31 ≡ r[s2]':31 )) | ||||
C = carry out of adder | ||||
SUB | N = r[dst]:31 | — result is negative | ||
Z = (r[dst] = 0) | — result is zero | |||
V = (( r[dst]:31 ⊕ r[s1]':31 ) ∧ ( r[s1]':31 ⊕ r[s2]':31 )) | ||||
C = not borrow from difference | ||||
The add and subtract instructions are used to perform integer arithmetic. 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 for addition, or no borrow for subtraction.
Subtraction is done by adding the two's complement of the subtrahend. Thus, where the function of the SUB instruction was documented as r[dst]=r[s1]–r[s2], this could have been written r[dst]=r[s1]+~r[s2]+1. When interpreted this way, C and V are computed identically for addition and subtraction. Some computer architectures, notably the Intel x86 architecture, make an attempt to make the carry bit mean borrow after subtraction. This simplifies explanations to naive programmers, but it adds slightly to the complexity of the hardware.
Note that when r[0] is used as a source operand, the value is zero, while if r[0] is used as a destination operand, the result is discarded. To compute the two's complement of a number in a register, subtract it from zero. To compare two numbers, subtract one from the other and discard the result. These operations are distinctive enough that assemblers should support them with the mnemonics NEG and CMP
07 | 06 | 05 | 04 | 03 | 02 | 01 | 00 | 15 | 14 | 13 | 12 | 11 | 10 | 09 | 08 | ||||||
0 0 1 0 | dst (x) | 0 0 0 0 | s2 (nz) | NEG | dst,s2 | r[dst] = 0 – r[s2] | |||||||||||||||
0 0 1 0 | 0 0 0 0 | s1 (0) | s2 (nz) | CMP | s1,s2 |
There may be some value in adding two numbers and discarding the result, since this can test for a=–b, but in general, ADD should never be used with s1 or s2 equal to zero, and SUB should not be used with S2 equal to zero, since these usages duplicate the function of MOVECC.