![]() |
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.
Branch always. This is the venerable goto of computer programming.
BA_A | branch always, absolute | x9_100_0_0010 | BPA_A | branch-and-push always, absolute | x9_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:
| ||||
BA_E | branch always, relative, offset embedded | s9_000_0_0010 | BA_R | branch always, relative, offset in register | 081_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_E | branch-and-push always, relative, offset embedded | s9_000_1_0010 | BPA_R | branch-and-push always, relative, offset in register | 081_000_1_0010 |
Pulled: none
Pushed:
If s9 is a null integer, BPA_R is performed instead. | Pulled:
• #0 signed integer: offset Pushed:
|
Branch string. These instructions branch according to the value of a bit, indicated by the bit number, within a string.
BS_0AE | branch string on zero, absolute, bit number embedded | u8_0001_0_0010 | BS_0AR | branch string on zero, absolute, bit number in register | 18_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_1AE | branch string on one, absolute, bit number embedded | u8_0101_0_0010 | BS_1AR | branch string on one, absolute, bit number in register | 18_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_0RB | branch string on zero, relative, bit number embedded | u8_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_0RO | branch string on zero, relative, offset embedded | s9_011_0_0010 | BS_0RR | branch string on zero, relative, all operands in registers | 081_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_1RB | branch string on one, relative, bit number embedded | u8_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_1RO | branch string on one, relative, offset embedded | s9_111_0_0010 | BS_1RR | branch string on one, relative, all operands in registers | 081_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_0AE | branch-and-push string on zero, absolute, bit number embedded | u8_0001_1_0010 | BPS_0AR | branch-and-push string on zero, absolute, bit number in register | 18_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: 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: | ||||
BPS_1AE | branch-and-push string on one, absolute, bit number embedded | u8_0101_1_0010 | BPS_1AR | branch-and-push string on one, absolute, bit number in register | 18_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: 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: | ||||
BPS_0RB | branch-and-push string on zero, relative, bit number embedded | u8_1001_1_0010 | |||
Pulled:
• #0 string: container of the bit to be tested • #1 signed integer: offset Pushed, if branch is taken: If u8 is 255, BPS_0RR is performed instead. | |||||
BPS_0RO | branch-and-push string on zero, relative, offset embedded | s9_011_1_0010 | BPS_0RR | branch-and-push string on zero, relative, all operands in registers | 081_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: 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: | ||||
BPS_1RB | branch-and-push string on one, relative, bit number embedded | u8_1101_1_0010 | |||
Pulled:
• #0 string: container of the bit to be tested • #1 signed integer: offset Pushed, if branch is taken: If u8 is 255, BPS_1RR is performed instead. | |||||
BPS_1RO | branch-and-push string on one, relative, offset embedded | s9_111_1_0010 | BPS_1RR | branch-and-push string on one, relative, all operands in registers | 081_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: 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: |
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 u3 | Branch when … | Comments |
---|---|---|
0 | #0 has a value, and #0 > 0 | never both true |
1 | #0 has a value, and #0 ≤ 0 | |
2 | #0 has a value, and #0 ≠ 0 | never both true |
3 | #0 has a value, and #0 = 0 | |
4 | #0 has a value, and #0 < 0 | never both true |
5 | #0 has a value, and #0 ≥ 0 | |
6 | #0 is null | never 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_0A | branch integer on zero, absolute | u3_x4_000_10_0_0010 | BPI0A | branch-and-push integer on zero, absolute | u3_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: | ||||
BI_1A | branch integer on one, absolute | u3_x4_100_10_0_0010 | BPI1A | branch-and-push integer on one, absolute | u3_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: | ||||
BI_0R | branch integer on zero, relative | u3_x4_010_10_0_0010 | BPI0R | branch-and-push integer on zero, relative | u3_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: | ||||
BI_1R | branch integer on one, relative | u3_x4_110_10_0_0010 | BPI1R | branch-and-push integer on one, relative | u3_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: | ||||
BF_0A | branch float on zero, absolute | u3_x4_001_10_0_0010 | BPF_0A | branch-and-push float on zero, absolute | u3_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: | ||||
BF_1A | branch float on one, absolute | u3_x4_101_10_0_0010 | BPF_1A | branch-and-push float on one, absolute | u3_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: | ||||
BF_0R | branch float on zero, relative | u3_x4_011_10_0_0010 | BPF_0R | branch-and-push float on zero, relative | u3_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: | ||||
BF_1R | branch float on one, relative | u3_x4_111_10_0_0010 | BPF_1R | branch-and-push float on one, relative | u3_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: |
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 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_DAE | branch uninterruptable deny, absolute, instruction count embedded | u8_0001_0_1010 | BU_DAR | branch uninterruptable deny, absolute, instruction count in register | 08_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_GAE | branch uninterruptable grant, absolute, instruction count embedded | u8_0101_0_1010 | BU_GAR | branch uninterruptable grant, absolute, instruction count in register | 08_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_DRI | branch uninterruptable deny, relative, instruction count embedded | u8_1001_0_1010 | |||
Pulled:
• #0 signed integer: offset If u8 is 0, BU_DRR is performed instead. | |||||
BU_DRO | branch uninterruptable deny, relative, offset embedded | s9_011_0_1010 | BU_DRR | branch uninterruptable deny, relative, all operands in registers | 081_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_GRI | branch uninterruptable grant, relative, instruction count embedded | u8_1101_0_1010 | |||
Pulled:
• #0 signed integer: offset If u8 is 0, BU_GRR is performed instead. | |||||
BU_GRO | branch uninterruptable grant, relative, offset embedded | s9_111_0_1010 | BU_GRR | branch uninterruptable grant, relative, all operands in registers | 081_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_DAE | branch-and-push uninterruptable deny, absolute, instruction count embedded | u8_0001_1_1010 | BPU_DAR | branch-and-push uninterruptable deny, absolute, instruction count in register | 08_0001_1_1010 |
Pulled:
• #0 signed integer: address to which to go Pushed, if branch is taken: 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: | ||||
BPU_GAE | branch-and-push uninterruptable grant, absolute, instruction count embedded | u8_0101_1_1010 | BPU_GAR | branch-and-push uninterruptable grant, absolute, instruction count in register | 08_0101_1_1010 |
Pulled:
• #0 signed integer: address to which to go Pushed, if branch is taken: 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: | ||||
BPU_DRI | branch-and-push uninterruptable deny, relative, instruction count embedded | u8_1001_1_1010 | |||
Pulled:
• #0 signed integer: offset Pushed, if branch is taken: If u8 is 0, BPU_DRR is performed instead. | |||||
BPU_DRO | branch-and-push uninterruptable deny, relative, offset embedded | s9_011_1_1010 | BPU_DRR | branch-and-push uninterruptable deny, relative, all operands in registers | 081_011_1_1010 |
Pulled:
• #0 signed integer 0…255: instruction count Pushed, if branch is taken: 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: | ||||
BPU_GRI | branch-and-push uninterruptable grant, relative, instruction count embedded | u8_1101_1_1010 | |||
Pulled:
• #0 signed integer: offset Pushed, if branch is taken: If u8 is 0, BPU_GRR is performed instead. | |||||
BPU_GRO | branch-and-push uninterruptable grant, relative, offset embedded | s9_111_1_1010 | BPU_GRR | branch-and-push uninterruptable grant, relative, all operands in registers | 081_111_1_1010 |
Pulled:
• #0 signed integer 0…255: instruction count Pushed, if branch is taken: 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: |
The next instructions are suitable if the programmer is confident that the request for uninterruptability will be granted.
XU_DE | exception if uninterruptable denied, instruction count embedded | 08_ | XU_DR | exception if uninterruptable denied, instruction count in register | 08_ |
---|---|---|---|---|---|
Pulled: none
Pushed: none If u8 is 0, XU_DR is performed instead. | Pulled:
• #0 signed integer 0…255: instruction count Pushed: none |