The Dauug House Wright State University logo
Dauug|36 minicomputer documentation

Mixed arithmetic-with-logic instructions

Opcode P/U Category Description
HAM2 user ALU: mixed Hamming weight part 2
NOLIST user ALU: mixed NOP, but hidden in listings
NOP user ALU: mixed no operation
STUN user ALU: mixed stacked unary
UN.A user ALU: mixed unary alpha
UN.B user ALU: mixed unary beta
UN.G user ALU: mixed unary gamma

Mixed arithmetic-with-logic instructions are those where their operands and results represent neither all numeric values nor all non-numeric values. NOP and NOLIST are documented with this set, because they handle no data and therefore show no bias toward being solely for arithmetic or solely for logic.

HAM2 Hamming weight part 2

Syntax
c = a ham2 b
Register Signedness
All ignored
1 opcode only
Flag Set if and only if
N never; flag is cleared
Z all result bits are zero
T flag does not change
R flag does not change

HAM2 evaluates the quartic polynomial:

c =               b_0   * 2**0 +
         ( a_6  + b_1 ) * 2**1 +
  ( a_12 + a_7  + b_2 ) * 2**2 +
         ( a_13 + a_8 ) * 2**3 +
                  a_14  * 2**4

where r_i denotes the 2**i bit of register r. Each r_i bit has either 0 or 1 as its value. The result of the polynomial evaluation is stored in c. The maximum value this polynomial can produce is 49.

This crazy expression, when preceded by the HAM1 macro, counts the number of 1 bits in a register. This count is called the Hamming weight or population count. Because the architecture uses 36-bit words, the Hamming weight will be in the range 0 through 36 inclusive. Use would look like:

unsigned x       ; input
unsigned ones    ; number of 1 bits in x
unsigned t       ; temporary

t = ham1 x
ones = t ham2 t

The POPC macro, which expands to HAM1 and HAM2, is more readable—although it disguises the fact two instructions execute instead of one:

unsigned x       ; input
unsigned ones    ; number of 1 bits in x

t = popc x

Unfortunately, none of the macros (including HAM1 and POPC) are implemented, but POPC would ultimately expand to STUN and HAM2, neither of which are macros. So the way population count is presently regression tested looks liike this:

unsigned x       ; input
unsigned ones    ; number of 1 bits in x
unsigned t       ; temporary

t = x stun.c 141414141414`o
ones = t ham2 t

NOLIST No list

Syntax
nolist
No registers used
1 opcode only
No flags changed

This instruction sits out the current CPU cycle without writing to any register or changing any flags. NOLIST produces the same control decoder signals as and behaves identically to NOP.

NOP differs from NOLIST for documentation and testing purposes. Unused segments of code memory are filled with NOLIST to tell disassemblers not to spew thousands of lines of irrelevant material. In contrast, NOP is used in proximity to other instructions, and disassemblers should display any NOPs encountered.

NOP No operation

Syntax
nop
No registers used
1 opcode only
No flags changed

This instruction sits out the current CPU cycle without writing to any register or changing any flags. See also NOLIST.

The NOP writeup on page 399 of the dissertation is very outdated and should be disregarded.

STUN Stacked unary

Syntax
c = a stun.a b
c = a stun.b b
...
c = a stun.k b
Register Signedness
Left varies and not well specified
Right varies and not well specified
Destination varies and not well specified
11 opcodes at present

The STUN opcodes have yet to be standardized and are unstable as of 14 June 2023. Do not use them in production software!

The STUN opcodes represent “super-instructions” that employ the ALU’s alpha, beta, and gamma layers in combination to compute one of 64 unary functions. The dissertation describes 25 functions, leaving another 39 slots available for future use.

STUN employs the left operand as the argument for the unary function, and the right operand as a 6-bit selector that specifies which of 64 functions is being applied. This selector must be replicated across all 6 subwords in order to reach all 18 RAMs of the ALU’s alpha, beta, and gamma layer, which is why the constant 141414141414`o appears in the above HAM2 code example.

STUN can do some crazy tricks, such as:

The unary functions supplied by STUN have specific, conflicting requirements with respect to some of the control decoder signals. This is why there are eleven opcodes, why this section is so incompletely written, why I’m not ready to even begin writing regression test cases, and why it’s not helpful to define any assembler macro semantics yet.

More information about STUN is available in the dissertation at pages 137–138 and 161–170, as well as in instruct.c and unary.c in the firmware source.

UN.a Simple unary, alpha layer

Syntax
c = a un.a b
Register Signedness
Left ignored
Right ignored
Dest. ignored
1 opcode only

UN.a splits left operand a into 6 contiguous subwords of 6 bits each, and pairs them off with the corresponding subwords of the right operand b. Each right operand selects one of 64 unary functions, each having 6 input and 6 output bits, to apply to its corresponding left operand. The results are stored in the corresponding subwords of c. The operation is done in the alpha layer of the ALU only.

The UN.a instruction is somewhat of a solution looking for a problem. You aren’t likely to use it in programs you write, nor would you typically find it in programs I write. A fuller description of UN.a, along with a list of available functions, appears in the dissertation at pages 160–161.

The UN.a, UN.b, and UN.g lookup tables are identical, so the UN.a instruction will produce the same result as UN.g despite employing different SRAMs to compute it.

UN.b Simple unary, beta layer

Syntax
c = a un.b b
Register Signedness
Left ignored
Right ignored
Dest. ignored
1 opcode only

UN.b is analogous to UN.a and UN.c and uses the same lookup tables, except the bits from the left operand are transposed, and the bits to the destination are transposed. Drawings showing this transposition are available on pages 75 and 88 of the dissertation.

The following two code segments produce identical results for c:

; segment 1
c = a un.b b       ; computed in beta while electrically transposed

; segment 2
a' = 0 txor a      ; transpose
c' = a' un.a b     ; computed in alpha using transposed value
c = 0 txor c'      ; un-transpose

The UN.b instruction is somewhat of a solution looking for a problem. You aren’t likely to use it in programs you write, nor would you typically find it in programs I write. A fuller description of UN.b, along with a list of available functions, appears in the dissertation at pages 160–161.

UN.g Simple unary, gamma layer

Syntax
c = a un.g b
Register Signedness
Left ignored
Right ignored
Dest. ignored
1 opcode only

UN.g splits left operand a into 6 contiguous subwords of 6 bits each, and pairs them off with the corresponding subwords of the right operand b. Each right operand selects one of 64 unary functions, each having 6 input and 6 output bits, to apply to its corresponding left operand. The results are stored in the corresponding subwords of c. The operation is done in the gamma layer of the ALU only.

The UN.g instruction is somewhat of a solution looking for a problem. You aren’t likely to use it in programs you write, nor would you typically find it in programs I write. A fuller description of UN.g, along with a list of available functions, appears in the dissertation at pages 160–161.

The UN.a, UN.b, and UN.g lookup tables are identical, so the UN.a instruction will produce the same result as UN.g despite employing different SRAMs to compute it.


Marc W. Abel
Computer Science and Engineering
College of Engineering and Computer Science
marc.abel@wright.edu
Without secure hardware, there is no secure software.
937-775-3016