8. Add and Subtract Instructions
Part of
the Hawk Manual

8.1. Add and Subtract Format
8.2. Add and Subtract
8.3. Alternatives
07  06  05  04  03  02  01  00  15  14  13  12  11  10  09  08  
0 0 1   dst  s1  s2 
The ADD and SUB (subtract) instructions each specify a destination register r[dst] and two source registers r[s1] and r[s2]. These 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.
Note that ADD sets the bcdcarry field of the processor status word (see Section 1.3.4.1). As a result, ADD followed by ADJUST may be used to add 8digit binarycoded decimal constants (see Section 11.2). Thi works for adding negative BCD values represented in 10's complement form, and it works for excessthree representation.
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.
ADD Rd,R0,Rs2 and ADD Rd,Rs1,R0 should not be used; if r[0] is ued as a source operand, it will cause an illegal instruction trap (see Chapter 13). Assemblers should flag use of r[0] in this context as an error. ADD R0,Rs1,Rs2 is legal; this sets the condition codes but does not alter any registers. This is potentially useful because it allows testing for a=–b.
SUB Rd,Rs1,R0 should not be used; if r[0] is ued as the second source operand, it will cause an illegal instruction trap (see Chapter 13). Assemblers should flag use of r[0] in this context as an error. (see )
SUB Rd,R0,Rs2 is legal. In this case, r[0] as the first source operand is interpreted as the constant zero. The net effect of this is that the second operand is subtracted from zero, effectively computing its two's complement. This is useful enough that assemblers should support NEG Rd,Rs2 as a synonym for SUB Rd,R0,Rs2.
SUB R0,Rs1,Rs2 is legal. In this case, the use of r[0] instructs the processor to discard the result after setting the condition codes (see Section 1.3.4.1). The net effect of this is to report, in the condition codes, the result of comparing the two operands. This is useful enough that assemblers should support CMP Rs1,Rs2 as a synonym for SUB R0,Rs1,Rs2.
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.
To add without setting the condition codes, use PLUS (see Section 11.3).
To add a constant in the range –32768 to +32767 without setting condition codes, use LEA (see Section 3.2).
To add a small power of two without setting the condition codes, use ADJUST (see Section 11.2).
To add a constant in the range –32768 to +32767 setting the condition codes, use ADDI (see Section 3.2).
To add a constant in the range –8 to +8 setting the condition codes, use ADDSI (see Section 9.3).