LT4335 branch instructions.
Version of 5 July 2011.
Home.

If a branch is taken, the branch-and-push instruction leaves in the stack a return address (absolute, not relative), which is the address of the first instruction in physical genspace that follows the branch instruction. The return address can also be calculated by adding 17 to the address of the branch instruction. Otherwise, the branch-and-push instruction works the same as its non-push counterpart.

At the end of a subroutine (which was presumably invoked with a branch-and-push instruction) the instruction to return is simply BA_A.

In the descriptions below:

u3 or u8 is the address of a bit within #0 to test. If it represents an unused bit, an exception will be thrown.

s9 is the offset, and it indicates the address, relative to that of the physically-next instruction, to which to branch. The offset is multiplied by 17 (because every instruction is 17 bits long) and added to the address of what would have been the next instruction had no branch been taken. If it is null, an exception will be thrown. If a branch relative instruction has an offset of zero, execution proceeds to the same instruction as if no branch instruction had been encountered.


Branch always. This is the venerable goto of computer programming.

BA_Abranch always, absolutex9_100_0_0010 BPA_Abranch-and-push always, absolutex9_100_1_0010
Pulled:
• #0 signed integer: address at which to continue execution

Pushed: none

Pulled:
• #0 signed integer: address at which to continue execution

Pushed:
• #0 signed integer: return address

BA_Ebranch always, relative, offset embeddeds9_000_0_0010 BA_Rbranch always, relative, offset in register081_000_0_0010
Pulled: none

Pushed: none

If s9 is a null integer, BA_R is performed instead.

Pulled:
• #0 signed integer: offset

Pushed: none

BPA_Ebranch-and-push always, relative, offset embeddeds9_000_1_0010 BPA_Rbranch-and-push always, relative, offset in register081_000_1_0010
Pulled: none

Pushed:
• #0 signed integer: return address

If s9 is a null integer, BPA_R is performed instead.

Pulled:
• #0 signed integer: offset

Pushed:
• #0 signed integer: return address


Branch string. These instructions branch according to the value of a bit, indicated by the bit number, within a string.

BS_0AEbranch string on zero, absolute, bit number embeddedu8_0001_0_0010 BS_0ARbranch string on zero, absolute, bit number in register18_0001_0_0010
Pulled:
• #0 string: container of the bit to be tested
• #1 signed integer: address to which to go

Pushed: none

If u8 is 255, BS_0AR is performed instead.

Pulled:
• #0 string: container of the bit to be tested
• #1 signed integer: address to which to go
• #2 signed integer 0…254: bit number

Pushed: none

BS_1AEbranch string on one, absolute, bit number embeddedu8_0101_0_0010 BS_1ARbranch string on one, absolute, bit number in register18_0101_0_0010
Pulled:
• #0 string: container of the bit to be tested
• #1 signed integer: address to which to go

Pushed: none

If u8 is 255, BS_1AR is performed instead.

Pulled:
• #0 string: container of the bit to be tested
• #1 signed integer: address to which to go
• #2 signed integer 0…254: bit number

Pushed: none

BS_0RBbranch string on zero, relative, bit number embeddedu8_1001_0_0010  
Pulled:
• #0 string: container of the bit to be tested
• #1 signed integer: offset

If u8 is 255, BS_0RR is performed instead.

BS_0RObranch string on zero, relative, offset embeddeds9_011_0_0010 BS_0RRbranch string on zero, relative, all operands in registers081_011_0_0010
Pulled:
• #0 string: container of the bit to be tested
• #1 signed integer 0…254: bit number

If s9 is a null integer, BS_0RR is performed instead.

Pulled:
• #0 string: container of the bit to be tested
• #1 signed integer: offset
• #2 signed integer 0…254: bit number

Pushed: none

BS_1RBbranch string on one, relative, bit number embeddedu8_1101_0_0010  
Pulled:
• #0 string: container of the bit to be tested
• #1 signed integer: offset

If u8 is 255, BS_1RR is performed instead.

BS_1RObranch string on one, relative, offset embeddeds9_111_0_0010 BS_1RRbranch string on one, relative, all operands in registers081_111_0_0010
Pulled:
• #0 string: container of the bit to be tested
• #1 signed integer 0…254: bit number

If s9 is a null integer, BS_1RR is performed instead.

Pulled:
• #0 string: container of the bit to be tested
• #1 signed integer: offset
• #2 signed integer 0…254: bit number

Pushed: none

BPS_0AEbranch-and-push string on zero, absolute, bit number embeddedu8_0001_1_0010 BPS_0ARbranch-and-push string on zero, absolute, bit number in register18_0001_1_0010
Pulled:
• #0 string: container of the bit to be tested
• #1 signed integer: address to which to go

Pushed, if branch is taken:
• #0 signed integer: return address

If u8 is 255, BPS_0AR is performed instead.

Pulled:
• #0 string: container of the bit to be tested
• #1 signed integer: address to which to go
• #2 signed integer 0…254: bit number

Pushed, if branch is taken:
• #0 signed integer: return address

BPS_1AEbranch-and-push string on one, absolute, bit number embeddedu8_0101_1_0010 BPS_1ARbranch-and-push string on one, absolute, bit number in register18_0101_1_0010
Pulled:
• #0 string: container of the bit to be tested
• #1 signed integer: address to which to go

Pushed, if branch is taken:
• #0 signed integer: return address

If u8 is 255, BPS_1AR is performed instead.

Pulled:
• #0 string: container of the bit to be tested
• #1 signed integer: address to which to go
• #2 signed integer 0…254: bit number

Pushed, if branch is taken:
• #0 signed integer: return address

BPS_0RBbranch-and-push string on zero, relative, bit number embeddedu8_1001_1_0010  
Pulled:
• #0 string: container of the bit to be tested
• #1 signed integer: offset

Pushed, if branch is taken:
• #0 signed integer: return address

If u8 is 255, BPS_0RR is performed instead.

BPS_0RObranch-and-push string on zero, relative, offset embeddeds9_011_1_0010 BPS_0RRbranch-and-push string on zero, relative, all operands in registers081_011_1_0010
Pulled:
• #0 string: container of the bit to be tested
• #1 signed integer 0…254: bit number

Pushed, if branch is taken:
• #0 signed integer: return address

If s9 is a null integer, BPS_0RR is performed instead.

Pulled:
• #0 string: container of the bit to be tested
• #1 signed integer: offset
• #2 signed integer 0…254: bit number

Pushed, if branch is taken:
• #0 signed integer: return address

BPS_1RBbranch-and-push string on one, relative, bit number embeddedu8_1101_1_0010  
Pulled:
• #0 string: container of the bit to be tested
• #1 signed integer: offset

Pushed, if branch is taken:
• #0 signed integer: return address

If u8 is 255, BPS_1RR is performed instead.

BPS_1RObranch-and-push string on one, relative, offset embeddeds9_111_1_0010 BPS_1RRbranch-and-push string on one, relative, all operands in registers081_111_1_0010
Pulled:
• #0 string: container of the bit to be tested
• #1 signed integer 0…254: bit number

Pushed, if branch is taken:
• #0 signed integer: return address

If s9 is a null integer, BPS_1RR is performed instead.

Pulled:
• #0 string: container of the bit to be tested
• #1 signed integer: offset
• #2 signed integer 0…254: bit number

Pushed, if branch is taken:
• #0 signed integer: return address


Branch integer or float. (see also integer and float) These quick-test instructions branch according to whether an integer or float has a value, or how it compares to zero. Each instruction performs one of eight tests:

Value of u3Branch when … Comments
0#0 has a value, and #0 > 0never both true
1#0 has a value, and #0 ≤ 0
2#0 has a value, and #0 ≠ 0never both true
3#0 has a value, and #0 = 0
4#0 has a value, and #0 < 0never both true
5#0 has a value, and #0 ≥ 0
6#0 is nullnever the same
7#0 has a value

The tests do not attempt to handle the case where a float is to be tested with a tolerance.

BI_0Abranch integer on zero, absoluteu3_x4_000_10_0_0010 BPI0Abranch-and-push integer on zero, absoluteu3_x4_000_10_1_0010
Pulled:
• #0 signed integer: to be tested
• #1 signed integer: address to which to go

Pushed: none

Pulled:
• #0 signed integer: to be tested
• #1 signed integer: address to which to go

Pushed, if branch is taken:
• #0 signed integer: return address

BI_1Abranch integer on one, absoluteu3_x4_100_10_0_0010 BPI1Abranch-and-push integer on one, absoluteu3_x4_100_10_1_0010
Pulled:
• #0 signed integer: to be tested
• #1 signed integer: address to which to go

Pushed: none

Pulled:
• #0 signed integer: to be tested
• #1 signed integer: address to which to go

Pushed, if branch is taken:
• #0 signed integer: return address

BI_0Rbranch integer on zero, relativeu3_x4_010_10_0_0010 BPI0Rbranch-and-push integer on zero, relativeu3_x4_010_10_1_0010
Pulled:
• #0 signed integer: to be tested
• #1 signed integer: offset

Pushed: none

Pulled:
• #0 signed integer: to be tested
• #1 signed integer: offset

Pushed, if branch is taken:
• #0 signed integer: return address

BI_1Rbranch integer on one, relativeu3_x4_110_10_0_0010 BPI1Rbranch-and-push integer on one, relativeu3_x4_110_10_1_0010
Pulled:
• #0 signed integer: to be tested
• #1 signed integer: offset

Pushed: none

Pulled:
• #0 signed integer: to be tested
• #1 signed integer: offset

Pushed, if branch is taken:
• #0 signed integer: return address

BF_0Abranch float on zero, absoluteu3_x4_001_10_0_0010 BPF_0Abranch-and-push float on zero, absoluteu3_x4_001_10_1_0010
Pulled:
• #0 float: to be tested
• #1 signed integer: address to which to go

Pushed: none

Pulled:
• #0 float: to be tested
• #1 signed integer: address to which to go

Pushed, if branch is taken:
• #0 signed integer: return address

BF_1Abranch float on one, absoluteu3_x4_101_10_0_0010 BPF_1Abranch-and-push float on one, absoluteu3_x4_101_10_1_0010
Pulled:
• #0 float: to be tested
• #1 signed integer: address to which to go

Pushed: none

Pulled:
• #0 float: to be tested
• #1 signed integer: address to which to go

Pushed, if branch is taken:
• #0 signed integer: return address

BF_0Rbranch float on zero, relativeu3_x4_011_10_0_0010 BPF_0Rbranch-and-push float on zero, relativeu3_x4_011_10_1_0010
Pulled:
• #0 float: to be tested
• #1 signed integer: offset

Pushed: none

Pulled:
• #0 float: to be tested
• #1 signed integer: offset

Pushed, if branch is taken:
• #0 signed integer: return address

BF_1Rbranch float on one, relativeu3_x4_111_10_0_0010 BPF_1Rbranch-and-push float on one, relativeu3_x4_111_10_1_0010
Pulled:
• #0 float: to be tested
• #1 signed integer: offset

Pushed: none

Pulled:
• #0 float: to be tested
• #1 signed integer: offset

Pushed, if branch is taken:
• #0 signed integer: return address


Branch uninterruptable. These tests inquire of the the CPU whether it is willing to perform the the next several instructions atomically, that is to say suppressing any interrupts, context switches, et cetera.

The branch uninterruptable instruction itself does not count toward the instruction count.

The purpose of the branch uninterruptable tests is to allow short instruction sequences to be processed atomically, while still preventing any one thread from taking over the machine. Some CPUs might be wired with a fixed maximum count, while others might fluctuate according to the circumstances.

Programmers frequently need (for instance, for semaphores) an uninterruptable sequence similar to this: (1) read an integer from genspace into a register, (2) increment the integer, and (3) write the integer from the register into genspace. Thus for programs to make good progress, three-instruction requests should rarely be denied. To go further: if the designers of a particular implementation of the CPU see that it will always be sensible to grant uninterruptibility for short sequences, they can include a simpler instruction (see XU_DE and XU_DR below) that omits branching information.

A program, having been granted one uninterruptability request, might ask for a second before the first expires:

The use of branching means that a clever program, when faced with a denied request, can try an alternate means to accomplish the task at hand, or can initiate a non-busy wait.


Ideally, there will be no constraint on what kinds of instructions may be executed during the uninterruptable period. Whether this can be accomplished in practice is an open issue, raising the question of what to do if uninterruptibility is granted, and then an ineligible instruction is encountered.

Throwing an exception in the midst of an unterruptable section is no panacea, because it may leave inconsistent data in shared genspace, confusing other CPUs in a multiprocessor system.

A complication is that an uninterruptable segment might contain ordinary conditional branching statements, and it would be difficult for the CPU to pre-scan all possible paths within the program in order to verify that all instructions qualify. Even a total prohibition of branching statements, which might make a pre-scan feasible in a pipelining environment, still leaves a problem if some instruction throws an exception that the programmer did not anticipate, such as a get from a bad address.

BU_DAEbranch uninterruptable deny, absolute, instruction count embeddedu8_0001_0_1010 BU_DARbranch uninterruptable deny, absolute, instruction count in register08_0001_0_1010
Pulled:
• #0 signed integer: address to which to go

Pushed: none

If u8 is 0, BU_DAR is performed instead.

Pulled:
• #0 signed integer: address to which to go
• #1 signed integer 0…255: instruction count

Pushed: none

BU_GAEbranch uninterruptable grant, absolute, instruction count embeddedu8_0101_0_1010 BU_GARbranch uninterruptable grant, absolute, instruction count in register08_0101_0_1010
Pulled:
• #0 signed integer: address to which to go

Pushed: none

If u8 is 0, BU_GAR is performed instead.

Pulled:
• #0 signed integer: address to which to go
• #1 signed integer 0…255: instruction count

Pushed: none

BU_DRIbranch uninterruptable deny, relative, instruction count embeddedu8_1001_0_1010  
Pulled:
• #0 signed integer: offset

If u8 is 0, BU_DRR is performed instead.

BU_DRObranch uninterruptable deny, relative, offset embeddeds9_011_0_1010 BU_DRRbranch uninterruptable deny, relative, all operands in registers081_011_0_1010
Pulled:
• #0 signed integer 0…255: instruction count

If s9 is a null integer, BU_DRR is performed instead.

Pulled:
• #0 signed integer: offset
• #1 signed integer 0…255: instruction count

Pushed: none

BU_GRIbranch uninterruptable grant, relative, instruction count embeddedu8_1101_0_1010  
Pulled:
• #0 signed integer: offset

If u8 is 0, BU_GRR is performed instead.

BU_GRObranch uninterruptable grant, relative, offset embeddeds9_111_0_1010 BU_GRRbranch uninterruptable grant, relative, all operands in registers081_111_0_1010
Pulled:
• #0 signed integer 0…255: instruction count

If s9 is a null integer, BU_GRR is performed instead.

Pulled:
• #0 signed integer: offset
• #1 signed integer 0…255: instruction count

Pushed: none

BPU_DAEbranch-and-push uninterruptable deny, absolute, instruction count embeddedu8_0001_1_1010 BPU_DARbranch-and-push uninterruptable deny, absolute, instruction count in register08_0001_1_1010
Pulled:
• #0 signed integer: address to which to go

Pushed, if branch is taken:
• #0 signed integer: return address

If u8 is 0, BPU_DAR is performed instead.

Pulled:
• #0 signed integer: address to which to go
• #1 signed integer 0…255: instruction count

Pushed, if branch is taken:
• #0 signed integer: return address

BPU_GAEbranch-and-push uninterruptable grant, absolute, instruction count embeddedu8_0101_1_1010 BPU_GARbranch-and-push uninterruptable grant, absolute, instruction count in register08_0101_1_1010
Pulled:
• #0 signed integer: address to which to go

Pushed, if branch is taken:
• #0 signed integer: return address

If u8 is 0, BPU_GAR is performed instead.

Pulled:
• #0 signed integer: address to which to go
• #1 signed integer 0…255: instruction count

Pushed, if branch is taken:
• #0 signed integer: return address

BPU_DRIbranch-and-push uninterruptable deny, relative, instruction count embeddedu8_1001_1_1010  
Pulled:
• #0 signed integer: offset

Pushed, if branch is taken:
• #0 signed integer: return address

If u8 is 0, BPU_DRR is performed instead.

BPU_DRObranch-and-push uninterruptable deny, relative, offset embeddeds9_011_1_1010 BPU_DRRbranch-and-push uninterruptable deny, relative, all operands in registers081_011_1_1010
Pulled:
• #0 signed integer 0…255: instruction count

Pushed, if branch is taken:
• #0 signed integer: return address

If s9 is a null integer, BPU_DRR is performed instead.

Pulled:
• #0 signed integer: offset
• #1 signed integer 0…255: instruction count

Pushed, if branch is taken:
• #0 signed integer: return address

BPU_GRIbranch-and-push uninterruptable grant, relative, instruction count embeddedu8_1101_1_1010  
Pulled:
• #0 signed integer: offset

Pushed, if branch is taken:
• #0 signed integer: return address

If u8 is 0, BPU_GRR is performed instead.

BPU_GRObranch-and-push uninterruptable grant, relative, offset embeddeds9_111_1_1010 BPU_GRRbranch-and-push uninterruptable grant, relative, all operands in registers081_111_1_1010
Pulled:
• #0 signed integer 0…255: instruction count

Pushed, if branch is taken:
• #0 signed integer: return address

If s9 is a null integer, BPU_GRR is performed instead.

Pulled:
• #0 signed integer: offset
• #1 signed integer 0…255: instruction count

Pushed, if branch is taken:
• #0 signed integer: return address

The next instructions are suitable if the programmer is confident that the request for uninterruptability will be granted.

XU_DEexception if uninterruptable denied, instruction count embedded08_ XU_DRexception if uninterruptable denied, instruction count in register08_
Pulled: none

Pushed: none

If u8 is 0, XU_DR is performed instead.

Pulled:
• #0 signed integer 0…255: instruction count

Pushed: none