12. Hawk Branch Instructions
the Hawk Manual
12.1. Branch Format
12.2. Conditional Branch
|0 0 0 0||c||disp|
The Branch format instructions are 16 bits each, incorporating a 4-bit branch condition and an 8 bit 2's complement branch displacement. For all of these instructions, the effective address is formed by adding twice the displacement to the address of the immediately following instruction.
This allows conditional branches to be taken to any instruction halfword within a 256 halfword range, with a displacement of zero referring to the instruction immediately following the branch instruction. Positive displacements refer to later instructions, and negative displacements refer to earlier instructions.
Assemblers for the Hawk should automatically compute the appropriate displacement when given the symbolic label of the destination. Thus, if L is the label on some location in the code the notation
should cause, in effect, the assignment of the value of L to the program counter.
Note that branch instructions with a displacement of –1 create infinite loops; as such, Hawk assemblers should discourage use of this displacement. Future versions of the Hawk architecture may give special meaning to branches with disp=11111111, for example, interpreting them as sleep instructions that put the CPU into a low-power sleeping or standby state until the next interrupt wakes the processor up.
There is actually only one branch instruction, with the c field selecting one of 15 tests to be made on the condition codes. By convention, however, the assembler uses a different mnemonic for each of the 15 possible branches. Also note that c=1000 is unassigned and reserved for future use.
|0 0 0 0 1 1 1 1||disp||BGTU||ea||if (C ∧ ~Z) pc = ea|
|0 0 0 0 1 1 1 0||disp||BGT||ea||if ((N⊕V)∧~Z) pc=ea|
|0 0 0 0 1 1 0 1||disp||BGE||ea||if (N ⊕ V) pc = ea|
|0 0 0 0 1 1 0 0||disp||BCR||ea||if (~C) pc = ea|
|0 0 0 0 1 0 1 1||disp||BVR||ea||if (~V) pc = ea|
|0 0 0 0 1 0 1 0||disp||BZR||ea||if (~Z) pc = ea|
|0 0 0 0 1 0 0 1||disp||BNR||ea||if (~N) pc = ea|
|0 0 0 0 0 1 1 1||disp||BLEU||ea||if (~C ∨ Z) pc = ea|
|0 0 0 0 0 1 1 0||disp||BLE||ea||if ((N ≡ V)∨Z) pc = ea|
|0 0 0 0 0 1 0 1||disp||BLT||ea||if (N ≡ V) pc = ea|
|0 0 0 0 0 1 0 0||disp||BCS||ea||if (C) pc = ea|
|0 0 0 0 0 0 1 1||disp||BVS||ea||if (V) pc = ea|
|0 0 0 0 0 0 1 0||disp||BZS||ea||if (Z) pc = ea|
|0 0 0 0 0 0 0 1||disp||BNS||ea||if (N) pc = ea|
The conditional branch group of instructions allows 14 combinations of condition code settings to be tested. There are two groups of seven branch instructions, where the second group is identical to the first, except that the condtion tested is inverted. Both the format of this instruction and the use made of the condition codes date back to 1970, when they were used for the DEC PDP-11. Both the Intel 80x86/Pentium and the Motorola 680x0 families also copied their branch instructions from the PDP-11.
Hawk assemblers should define the following additional synonyms for some of the above conditional branch instructions:
|0 0 0 0 0 0 1 0||disp||BEQ||ea||if (Z) pc = ea|
|0 0 0 0 0 1 0 0||disp||BGEU||ea||if (C) pc = ea|
|0 0 0 0 1 0 1 0||disp||BNE||ea||if (~Z) pc = ea|
|0 0 0 0 1 1 0 0||disp||BLTU||ea||if (~C) pc = ea|
The BNS (branch if N set), BZS (branch if Z set), BVS (branch if V set) and BCS (branch if C set) instructions simply test individual condition code bits, branching when the indicated bit is set to one. Similarly, BNR (branch if N reset), BZR (branch if Z reset), BVR (branch if V reset) and BCR (branch if C reset) branch when the indicated bits are zero.
After a CMP or CMPI instruction, where the operands are both signed integers, BGT (branch if greater than), BGE (branch if greater than or equal), BEQ (branch if equal), BNE (branch if not equal), BLE (branch if less than or equal), and BLT (branch if less than) will branch if the first operand has the indicated relationship to the second operand. Four of these instructions involve complex tests of the condition codes, but two are merely BZS and BZR under different names. These can also be used after LOADSCC or LOADCC, where the effect is to compare the loaded signed operand with zero.
After a CMP or CMPI instruction, where the operands are both unsigned integers, BGTU (branch if greater than unsigned), BGEU (branch if greater than or equal unsigned), BLEU (branch if less than or equal unsigned), and BLTU (branch if less than unsigned) will correctly respond to the unsigned relationship between the first and second operands. Comparison for equality is, of course, identical for signed and unsigned operands. Note that two of these instructions are merely BCS and BCR under different names.
When there is a need to load a boolean into a register from the condition codes, a sequence of instrucitons such as the following can be used:
LIS R3,TRUE BGT .+4 LIS R3,FALSE
This sequence will load either TRUE or FALSE depending on the condition tested by the branch instruction. In this example, it will load R3 with TRUE if the GT condition was true (if the first operand was greater than the second in the immediately preceeding compare instruction of two signed operands), and FALSE otherwise.
The following sequence of instructions will load the 4 bit condition-code field into a register without use of privileged instructions and without changing the condition codes:
LIS R3,0 BCS .+4 ADJUST R3,PLUS1 BVS .+4 ADJUST R3,PLUS2 BZS .+4 ADJUST R3,PLUS4 BNS .+4 ADJUST R3,PLUS8
|0 0 0 0 0 0 0 0||disp||BR||ea||pc = ea|
The BR (branch) instruction unconditional transferrs control to to the indicated destination. BR can be used whereever a program-counter-relative JUMP instruction is used, so long as the destination is one of the 256 reachable locations.
There are occasional contexts where an instruction that does absolutely nothing is required. All conditional branches do nothing if the displacement is zero, so any one of them could be used for this purpose, but BR with a displacement of zero is the preferred no-op for the Hawk machine and assemblers should support it with the mnemonic NOP.
|0 0 0 0 0 0 0 0||0 0 0 0 0 0 0 0||NOP||—|
Thus, the following three assembly language instructions should generate exactly the same results:
NOP BR .+2 BR NEXT NEXT:
Note that BR .+2 branches to the next succeeding instruction because, during the assembly of the BR instruction, the assembly location counter . (dot) holds the address of the current instruction until assembly of that instruction is completed. The example BR NEXT uses an explicit label to do exactly the same thing.
The facts that NOP is coded 000016 and MOVE R15,R15 is coded as FFFF16 may simplify development on PROM-based systems. One or the other of these no-ops should represent the raw, unprogrammed state of PROM, useful for patch areas reserved to hold later additions to the code, while the other should represent a value that can be overwritten over any existing code that needs to be deleted.