Architecture: Processor
The processor reads and evaluates instructions serially from program memory.
Instruction cycle
An instruction value will be read from the memory address currently referenced by the program counter, the program counter will be incremented by 1, and then the processor will evaluate the instruction. This cycle will repeat until an instruction value of zero is encountered, at which point the processor will halt.
Instruction encoding
Instructions for the Bedrock processor are encoded as 8-bit values. The lower five bits of the value determine which operation will be performed, and the higher three bits of the value are mode flags which determine how the operation will be performed.
Bit | Mask | Description |
---|---|---|
0x7 | 0x80 | Return-mode flag |
0x6 | 0x40 | Literal-mode flag |
0x5 | 0x20 | Double-mode flag |
... | 0x1f | Operation code |
Return-mode flag
If the return-mode flag is set, the instruction will use the return stack in place of the working stack, and the working stack in place of the return stack.
Literal-mode flag
If the literal-mode flag is set, the first time the instruction would pop a value from a stack, it will instead read a value from the next byte or double of program memory, incrementing the program counter by 1 for each byte read in the process.
Double-mode flag
If the double-mode flag is set, the instruction will operate on double-size values, otherwise the instruction will operate on byte-size values. Some operations use fixed-size values, which will not be affected by this flag. Fixed-size byte values are denoted by a trailing !
in a signature, and fixed-size double values are denoted by a trailing *
in a signature.
Operation code
The processor can perform 32 different operations, as per the following table:
Base | Name | Description | Signature |
---|---|---|---|
0x00 | HLT | Halt the processor. | ( -- ) |
0x01 | JMP | Jump to an address. | ( a* -- ) |
0x02 | JCN | Conditionally jump to an address. | ( t! a* -- ) |
0x03 | JCK | Conditionally jump to an address, keeping the value. | ( t a* -- t ) |
0x04 | LDA | Read a value from program memory. | ( a* -- v ) |
0x05 | STA | Write a value to program memory. | ( v a* -- ) |
0x06 | LDD | Read a value from the device bus. | ( p! -- v ) |
0x07 | STD | Write a value to the device bus. | ( v p! -- ) |
0x08 | PSH | Move the top value from one stack to the other. | ( -- x : x -- ) |
0x09 | POP | Remove the top value of a stack. | ( x -- ) |
0x0A | CPY | Copy the top value from one stack to the other. | ( -- x : x -- x ) |
0x0B | SPL | Split packed values into multiple bytes. | ( x -- y z ) |
0x0C | DUP | Duplicate the top value of a stack. | ( x -- x x ) |
0x0D | OVR | Duplicate the second value of a stack. | ( x y -- x y x ) |
0x0E | SWP | Swap the top two values on a stack. | ( x y -- y x ) |
0x0F | ROT | Rotate the top three values on a stack. | ( x y z -- y z x ) |
0x10 | ADD | Find the sum of two values. | ( x y -- r ) |
0x11 | SUB | Find the difference of two values. | ( x y -- r ) |
0x12 | INC | Increment a value by 1. | ( x -- r ) |
0x13 | DEC | Decrement a value by 1. | ( x -- r ) |
0x14 | LTH | Test if one value is less than another. | ( x y -- t! ) |
0x15 | GTH | Test if one value is greater than another. | ( x y -- t! ) |
0x16 | EQU | Test if two values are equal. | ( x y -- t! ) |
0x17 | NQK | Test if two values are inequal, keeping the values. | ( x y -- x y t! ) |
0x18 | IOR | Find the bitwise disjunction of two values. | ( x y -- r ) |
0x19 | XOR | Find the bitwise non-equivalence of two values. | ( x y -- r ) |
0x1A | AND | Find the bitwise conjugation of two values. | ( x y -- r ) |
0x1B | NOT | Find the bitwise compliment of a value. | ( x -- r ) |
0x1C | SHF | Shift the bits of a value. | ( x y! -- r ) |
0x1D | SHC | Rotate the bits of a value. | ( x y! -- r ) |
0x1E | TAL | Count the number of set bits in a value. | ( x -- r! ) |
0x1F | REV | Reverse the order of bits in a value. | ( x -- r ) |
Operations
HLT
Halt the processor. If any mode flag is set, do nothing.
The instruction variants DB1
, DB2
, DB3
, DB4
, DB5
, and DB6
can be used as hooks for implementation defined debug functionality.
Signature |
---|
( -- ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack | Notes |
---|---|---|---|---|---|---|---|
0x00 | HLT | ( -- ) | ( -- ) | Halt the processor. | |||
0x20 | NOP | * | ( -- ) | ( -- ) | No effect. | ||
0x40 | DB1 | : | ( -- ) | ( -- ) | No effect. | ||
0x60 | DB2 | * | : | ( -- ) | ( -- ) | No effect. | |
0x80 | DB3 | r | ( -- ) | ( -- ) | No effect. | ||
0xA0 | DB4 | * | r | ( -- ) | ( -- ) | No effect. | |
0xC0 | DB5 | : | r | ( -- ) | ( -- ) | No effect. | |
0xE0 | DB6 | * | : | r | ( -- ) | ( -- ) | No effect. |
JMP
Jump to an address.
The double a
is popped from the primary stack. If the double-mode flag is set, the double b
is then read from the program counter and pushed to the secondary stack. The double a
is then written to the program counter.
Signature |
---|
( a* -- : -- [b*] ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x01 | JMP | ( a* -- ) | ( -- ) | |||
0x21 | JMS | * | ( a* -- ) | ( -- b* ) | ||
0x41 | JMP: | : | ( -- ) | ( -- ) | ||
0x61 | JMS: | * | : | ( -- ) | ( -- b* ) | |
0x81 | JMPr | r | ( -- ) | ( a* -- ) | ||
0xA1 | JMSr | * | r | ( -- b* ) | ( a* -- ) | |
0xC1 | JMPr: | : | r | ( -- ) | ( -- ) | |
0xE1 | JMSr: | * | : | r | ( -- b* ) | ( -- ) |
JCN
Conditionally jump to an address.
The double a
is popped from the primary stack, then the byte t
is popped from the primary stack. If the double-mode flag is set and t
is not zero, the double b
is then read from the program counter and pushed to the secondary stack. If t
is not zero, the double a
is then written to the program counter.
Signature |
---|
( t! a* -- : -- [b*] ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x02 | JCN | ( t a* -- ) | ( -- ) | |||
0x22 | JCS | * | ( t a* -- ) | ( -- b* ) | ||
0x42 | JCN: | : | ( t -- ) | ( -- ) | ||
0x62 | JCS: | * | : | ( t -- ) | ( -- b* ) | |
0x82 | JCNr | r | ( -- ) | ( t a* -- ) | ||
0xA2 | JCSr | * | r | ( -- b* ) | ( t a* -- ) | |
0xC2 | JCNr: | : | r | ( -- ) | ( t -- ) | |
0xE2 | JCSr: | * | : | r | ( -- b* ) | ( t -- ) |
JCK
Conditionally jump to an address, keeping the test value.
The double a
is popped from the primary stack, then the value t
is popped from the primary stack, then the value t
is written to the primary stack. The double a
is then written to the program counter if t
is not zero.
Signature |
---|
( t a* -- t ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x03 | JCK | ( t a* -- t ) | ( -- ) | |||
0x23 | JCK* | * | ( t* a* -- t* ) | ( -- ) | ||
0x43 | JCK: | : | ( t -- t ) | ( -- ) | ||
0x63 | JCK*: | * | : | ( t* -- t* ) | ( -- ) | |
0x83 | JCKr | r | ( -- ) | ( t a* -- t ) | ||
0xA3 | JCKr* | * | r | ( -- ) | ( t* a* -- t* ) | |
0xC3 | JCKr: | : | r | ( -- ) | ( t -- t ) | |
0xE3 | JCKr*: | * | : | r | ( -- ) | ( t* -- t* ) |
LDA
Read a value from program memory.
The double a
is popped from the primary stack, and then the value v
is read from program memory starting at the memory address referenced by a
and is pushed to the primary stack.
Signature |
---|
( a* -- v ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x04 | LDA | ( a* -- v ) | ( -- ) | |||
0x24 | LDA* | * | ( a* -- v* ) | ( -- ) | ||
0x44 | LDA: | : | ( -- v ) | ( -- ) | ||
0x64 | LDA*: | * | : | ( -- v* ) | ( -- ) | |
0x84 | LDAr | r | ( -- ) | ( a* -- v ) | ||
0xA4 | LDAr* | * | r | ( -- ) | ( a* -- v* ) | |
0xC4 | LDAr: | : | r | ( -- ) | ( -- v ) | |
0xE4 | LDAr*: | * | : | r | ( -- ) | ( -- v* ) |
STA
Write a value to program memory.
The double a
is popped from the primary stack, then the value v
is popped from the primary stack, and then the value v
is written to program memory starting at the memory address referenced by a
.
Signature |
---|
( v a* -- ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x05 | STA | ( a* -- v ) | ( -- ) | |||
0x25 | STA* | * | ( a* -- v* ) | ( -- ) | ||
0x45 | STA: | : | ( -- v ) | ( -- ) | ||
0x65 | STA*: | * | : | ( -- v* ) | ( -- ) | |
0x85 | STAr | r | ( -- ) | ( a* -- v ) | ||
0xA5 | STAr* | * | r | ( -- ) | ( a* -- v* ) | |
0xC5 | STAr: | : | r | ( -- ) | ( -- v ) | |
0xE5 | STAr*: | * | : | r | ( -- ) | ( -- v* ) |
LDD
Read a value from the device bus.
The byte p
is popped from the primary stack, and then the value v
is read from the device bus starting at the device port referenced by p
and is pushed to the primary stack.
Signature |
---|
( p! -- v ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x06 | LDD | ( p -- v ) | ( -- ) | |||
0x26 | LDD* | * | ( p -- v* ) | ( -- ) | ||
0x46 | LDD: | : | ( -- v ) | ( -- ) | ||
0x66 | LDD*: | * | : | ( -- v* ) | ( -- ) | |
0x86 | LDDr | r | ( -- ) | ( p -- v ) | ||
0xA6 | LDDr* | * | r | ( -- ) | ( p -- v* ) | |
0xC6 | LDDr: | : | r | ( -- ) | ( -- v ) | |
0xE6 | LDDr*: | * | : | r | ( -- ) | ( -- v* ) |
STD
Write a value to the device bus.
The byte p
is popped from the primary stack, then the value v
is popped from the primary stack, and then the value v
is written to the device bus starting at the device port referenced by p
.
Signature |
---|
( v p! -- ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x07 | STD | ( v p -- ) | ( -- ) | |||
0x27 | STD* | * | ( v* p -- ) | ( -- ) | ||
0x47 | STD: | : | ( v -- ) | ( -- ) | ||
0x67 | STD*: | * | : | ( v* -- ) | ( -- ) | |
0x87 | STDr | r | ( -- ) | ( v p -- ) | ||
0xA7 | STDr* | * | r | ( -- ) | ( v* p -- ) | |
0xC7 | STDr: | : | r | ( -- ) | ( v -- ) | |
0xE7 | STDr*: | * | : | r | ( -- ) | ( v* -- ) |
PSH
Move the top value from one stack to the other.
The value x
is popped from the secondary stack, and then the value x
is pushed to the primary stack.
Signature |
---|
( -- x : x -- ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x08 | PSH | ( -- x ) | ( x -- ) | |||
0x28 | PSH* | * | ( -- x* ) | ( x* -- ) | ||
0x48 | PSH: | : | ( -- l ) | ( -- ) | ||
0x68 | PSH*: | * | : | ( -- l* ) | ( -- ) | |
0x88 | PSHr | r | ( x -- ) | ( -- x ) | ||
0xA8 | PSHr* | * | r | ( x* -- ) | ( -- x* ) | |
0xC8 | PSHr: | : | r | ( -- ) | ( -- l ) | |
0xE8 | PSHr*: | * | : | r | ( -- ) | ( -- l* ) |
POP
Remove the top value of a stack.
The value x
is popped from the primary stack.
Signature |
---|
( x -- ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x09 | POP | ( x -- ) | ( -- ) | |||
0x29 | POP* | * | ( x* -- ) | ( -- ) | ||
0x49 | POP: | : | ( -- ) | ( -- ) | ||
0x69 | POP*: | * | : | ( -- ) | ( -- ) | |
0x89 | POPr | r | ( -- ) | ( x -- ) | ||
0xA9 | POPr* | * | r | ( -- ) | ( x* -- ) | |
0xC9 | POPr: | : | r | ( -- ) | ( -- ) | |
0xE9 | POPr*: | * | : | r | ( -- ) | ( -- ) |
CPY
Copy the top value from one stack to the other.
The value x
is popped from the secondary stack, then the value x
is pushed to the secondary stack, and then the value x
is pushed to the primary stack.
Signature |
---|
( -- x : x -- x ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x0A | CPY | ( -- x ) | ( x -- x ) | |||
0x2A | CPY* | * | ( -- x* ) | ( x* -- x* ) | ||
0x4A | CPY: | : | ( -- l ) | ( -- l ) | ||
0x6A | CPY*: | * | : | ( -- l* ) | ( -- l* ) | |
0x8A | CPYr | r | ( x -- x ) | ( -- x ) | ||
0xAA | CPYr* | * | r | ( x* -- x* ) | ( -- x* ) | |
0xCA | CPYr: | : | r | ( -- l ) | ( -- l ) | |
0xEA | CPYr*: | * | : | r | ( -- l* ) | ( -- l* ) |
SPL
Split packed values into multiple bytes.
The value x
is popped from the primary stack. For each byte b
of x
, starting with the high byte, create a byte y
where the high four bits of b
are the low four bits of y
, and push y
to the primary stack, then create a byte z
where the low four bits of b
are the low four bits of z
, and push z
to the primary stack.
Signature |
---|
( x -- y z ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x0B | SPL | ( x -- y z ) | ( -- ) | |||
0x2B | SPL* | * | ( x* -- y* z* ) | ( -- ) | ||
0x4B | SPL: | : | ( -- y z ) | ( -- ) | ||
0x6B | SPL*: | * | : | ( -- y* z* ) | ( -- ) | |
0x8B | SPLr | r | ( -- ) | ( x -- y z ) | ||
0xAB | SPLr* | * | r | ( -- ) | ( x* -- y* z* ) | |
0xCB | SPLr: | : | r | ( -- ) | ( -- y z ) | |
0xEB | SPLr*: | * | : | r | ( -- ) | ( -- y* z* ) |
DUP
Duplicate the top value of a stack.
The value x
is popped from the primary stack, then the value x
is pushed to the primary stack, and then the value x
is pushed to the primary stack.
Signature |
---|
( x -- x x ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x0C | DUP | ( x -- x x ) | ( -- ) | |||
0x2C | DUP* | * | ( x* -- x* x* ) | ( -- ) | ||
0x4C | DUP: | : | ( -- l l ) | ( -- ) | ||
0x6C | DUP*: | * | : | ( -- l* l* ) | ( -- ) | |
0x8C | DUPr | r | ( -- ) | ( x -- x x ) | ||
0xAC | DUPr* | * | r | ( -- ) | ( x* -- x* x* ) | |
0xCC | DUPr: | : | r | ( -- ) | ( -- l l ) | |
0xEC | DUPr*: | * | : | r | ( -- ) | ( -- l* l* ) |
OVR
Duplicate the second value of a stack.
The value y
is popped from the primary stack, then the value x
is popped from the primary stack, then the value x
is pushed to the primary stack, then the value y
is pushed to the primary stack, and then the value x
is pushed to the primary stack.
Signature |
---|
( x y -- x y x ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x0D | OVR | ( x y -- x y x ) | ( -- ) | |||
0x2D | OVR* | * | ( x* y* -- x* y* x* ) | ( -- ) | ||
0x4D | OVR: | : | ( x -- x l x ) | ( -- ) | ||
0x6D | OVR*: | * | : | ( x* -- x* l* x* ) | ( -- ) | |
0x8D | OVRr | r | ( -- ) | ( x y -- x y x ) | ||
0xAD | OVRr* | * | r | ( -- ) | ( x* y* -- x* y* x* ) | |
0xCD | OVRr: | : | r | ( -- ) | ( x -- x l x ) | |
0xED | OVRr*: | * | : | r | ( -- ) | ( x* -- x* l* x* ) |
SWP
Swap the top two values on a stack.
The value y
is popped from the primary stack, then the value x
is popped from the primary stack, then the value y
is pushed to the primary stack, and then the value x
is pushed to the primary stack.
Signature |
---|
( x y -- y x ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x0E | SWP | ( x y -- y x ) | ( -- ) | |||
0x2E | SWP* | * | ( x* y* -- y* x* ) | ( -- ) | ||
0x4E | SWP: | : | ( x -- l x ) | ( -- ) | ||
0x6E | SWP*: | * | : | ( x* -- l* x* ) | ( -- ) | |
0x8E | SWPr | r | ( -- ) | ( x y -- y x ) | ||
0xAE | SWPr* | * | r | ( -- ) | ( x* y* -- y* x* ) | |
0xCE | SWPr: | : | r | ( -- ) | ( x -- l x ) | |
0xEE | SWPr*: | * | : | r | ( -- ) | ( x* -- l* x* ) |
ROT
Rotate the top three values on a stack.
The value z
is popped from the primary stack, then the value y
is popped from the primary stack, then the value x
is popped from the primary stack, then the value y
is pushed to the primary stack, then the value z
is pushed to the primary stack, and then the value x
is pushed to the primary stack.
Signature |
---|
( x y z -- y z x ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x0F | ROT | ( x y z -- y z x ) | ( -- ) | |||
0x2F | ROT* | * | ( x* y* z* -- y* z* x* ) | ( -- ) | ||
0x4F | ROT: | : | ( x y -- y l x ) | ( -- ) | ||
0x6F | ROT*: | * | : | ( x* y* -- y* l* x* ) | ( -- ) | |
0x8F | ROTr | r | ( -- ) | ( x y z -- y z x ) | ||
0xAF | ROTr* | * | r | ( -- ) | ( x* y* z* -- y* z* x* ) | |
0xCF | ROTr: | : | r | ( -- ) | ( x y -- y l x ) | |
0xEF | ROTr*: | * | : | r | ( -- ) | ( x* y* -- y* l* x* ) |
ADD
Find the sum of two values.
The value y
is popped from the primary stack, then the value x
is popped from the primary stack, and then the value r
is calculated as the wrapped addition of y
to x
and is pushed to the primary stack.
Signature |
---|
( x y -- r ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x10 | ADD | ( x y -- r ) | ( -- ) | |||
0x30 | ADD* | * | ( x* y* -- r* ) | ( -- ) | ||
0x50 | ADD: | : | ( x -- r ) | ( -- ) | ||
0x70 | ADD*: | * | : | ( x* -- r* ) | ( -- ) | |
0x90 | ADDr | r | ( -- ) | ( x y -- r ) | ||
0xB0 | ADDr* | * | r | ( -- ) | ( x* y* -- r* ) | |
0xD0 | ADDr: | : | r | ( -- ) | ( x -- r ) | |
0xF0 | ADDr*: | * | : | r | ( -- ) | ( x* -- r* ) |
SUB
Find the difference of two values.
The value y
is popped from the primary stack, then the value x
is popped from the primary stack, and then the value r
is calculated as the wrapped subtraction of y
from x
and is pushed to the primary stack.
Signature |
---|
( x y -- r ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x11 | SUB | ( x y -- r ) | ( -- ) | |||
0x31 | SUB* | * | ( x* y* -- r* ) | ( -- ) | ||
0x51 | SUB: | : | ( x -- r ) | ( -- ) | ||
0x71 | SUB*: | * | : | ( x* -- r* ) | ( -- ) | |
0x91 | SUBr | r | ( -- ) | ( x y -- r ) | ||
0xB1 | SUBr* | * | r | ( -- ) | ( x* y* -- r* ) | |
0xD1 | SUBr: | : | r | ( -- ) | ( x -- r ) | |
0xF1 | SUBr*: | * | : | r | ( -- ) | ( x* -- r* ) |
INC
Increment a value by 1.
The value x
is popped from the primary stack, and then the value r
is calculated as the wrapped addition of 1 to x
and is pushed to the primary stack.
Signature |
---|
( x -- r ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x12 | INC | ( x -- r ) | ( -- ) | |||
0x32 | INC* | * | ( x* -- r* ) | ( -- ) | ||
0x52 | INC: | : | ( -- r ) | ( -- ) | ||
0x72 | INC*: | * | : | ( -- r* ) | ( -- ) | |
0x92 | INCr | r | ( -- ) | ( x -- r ) | ||
0xB2 | INCr* | * | r | ( -- ) | ( x* -- r* ) | |
0xD2 | INCr: | : | r | ( -- ) | ( -- r ) | |
0xF2 | INCr*: | * | : | r | ( -- ) | ( -- r* ) |
DEC
Decrement a value by 1.
The value x
is popped from the primary stack, and then the value r
is calculated as the wrapped subtraction of 1 from x
and is pushed to the primary stack.
Signature |
---|
( x -- r ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x13 | DEC | ( x -- r ) | ( -- ) | |||
0x33 | DEC* | * | ( x* -- r* ) | ( -- ) | ||
0x53 | DEC: | : | ( -- r ) | ( -- ) | ||
0x73 | DEC*: | * | : | ( -- r* ) | ( -- ) | |
0x93 | DECr | r | ( -- ) | ( x -- r ) | ||
0xB3 | DECr* | * | r | ( -- ) | ( x* -- r* ) | |
0xD3 | DECr: | : | r | ( -- ) | ( -- r ) | |
0xF3 | DECr*: | * | : | r | ( -- ) | ( -- r* ) |
LTH
Test if one value is less than another.
The value y
is popped from the primary stack, and then the value x
is popped from the primary stack. If x
is less than y
, the byte 0xff
is pushed to the primary stack, otherwise the byte 0x00
is pushed to the primary stack.
Signature |
---|
( x y -- t! ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x14 | LTH | ( x y -- t ) | ( -- ) | |||
0x34 | LTH* | * | ( x* y* -- t ) | ( -- ) | ||
0x54 | LTH: | : | ( x -- t ) | ( -- ) | ||
0x74 | LTH*: | * | : | ( x* -- t ) | ( -- ) | |
0x94 | LTHr | r | ( -- ) | ( x y -- t ) | ||
0xB4 | LTHr* | * | r | ( -- ) | ( x* y* -- t ) | |
0xD4 | LTHr: | : | r | ( -- ) | ( x -- t ) | |
0xF4 | LTHr*: | * | : | r | ( -- ) | ( x* -- t ) |
GTH
Test if one value is greater than another.
The value y
is popped from the primary stack, and then the value x
is popped from the primary stack. If x
is greater than y
, the byte 0xff
is pushed to the primary stack, otherwise the byte 0x00
is pushed to the primary stack.
Signature |
---|
( x y -- t! ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x15 | GTH | ( x y -- t ) | ( -- ) | |||
0x35 | GTH* | * | ( x* y* -- t ) | ( -- ) | ||
0x55 | GTH: | : | ( x -- t ) | ( -- ) | ||
0x75 | GTH*: | * | : | ( x* -- t ) | ( -- ) | |
0x95 | GTHr | r | ( -- ) | ( x y -- t ) | ||
0xB5 | GTHr* | * | r | ( -- ) | ( x* y* -- t ) | |
0xD5 | GTHr: | : | r | ( -- ) | ( x -- t ) | |
0xF5 | GTHr*: | * | : | r | ( -- ) | ( x* -- t ) |
EQU
Test if two values are equal.
The value y
is popped from the primary stack, and then the value x
is popped from the primary stack. If x
is equal to y
, the byte 0xff
is pushed to the primary stack, otherwise the byte 0x00
is pushed to the primary stack.
Signature |
---|
( x y -- t! ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x16 | EQU | ( x y -- t ) | ( -- ) | |||
0x36 | EQU* | * | ( x* y* -- t ) | ( -- ) | ||
0x56 | EQU: | : | ( x -- t ) | ( -- ) | ||
0x76 | EQU*: | * | : | ( x* -- t ) | ( -- ) | |
0x96 | EQUr | r | ( -- ) | ( x y -- t ) | ||
0xB6 | EQUr* | * | r | ( -- ) | ( x* y* -- t ) | |
0xD6 | EQUr: | : | r | ( -- ) | ( x -- t ) | |
0xF6 | EQUr*: | * | : | r | ( -- ) | ( x* -- t ) |
NQK
Test if two values are inequal, keeping the values.
The value y
is popped from the primary stack, then the value x
is popped from the primary stack, then the value x
is pushed to the primary stack, and then the value y
is pushed to the primary stack. If x
is not equal to y
, the byte 0xff
is pushed to the primary stack, otherwise the byte 0x00
is pushed to the primary stack.
Signature |
---|
( x y -- x y t! ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x17 | NQK | ( x y -- x y t ) | ( -- ) | |||
0x37 | NQK* | * | ( x* y* -- x* y* t ) | ( -- ) | ||
0x57 | NQK: | : | ( x -- x l t ) | ( -- ) | ||
0x77 | NQK*: | * | : | ( x* -- x* l* t ) | ( -- ) | |
0x97 | NQKr | r | ( -- ) | ( x y -- x y t ) | ||
0xB7 | NQKr* | * | r | ( -- ) | ( x* y* -- x* y* t ) | |
0xD7 | NQKr: | : | r | ( -- ) | ( x -- x l t ) | |
0xF7 | NQKr*: | * | : | r | ( -- ) | ( x* -- x* l* t ) |
IOR
Find the bitwise disjunction of two values. This operation is also known as ‘inclusive-or’.
The value y
is popped from the primary stack, and then the value x
is popped from the primary stack. The value r
is then calculated bitwise, where each bit of r
is set only if at least one of the corresponding bits of x
and y
is set. The value r
is then pushed to the primary stack.
Signature |
---|
( x y -- r ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x18 | IOR | ( x y -- r ) | ( -- ) | |||
0x38 | IOR* | * | ( x* y* -- r* ) | ( -- ) | ||
0x58 | IOR: | : | ( x -- r ) | ( -- ) | ||
0x78 | IOR*: | * | : | ( x* -- r* ) | ( -- ) | |
0x98 | IORr | r | ( -- ) | ( x y -- r ) | ||
0xB8 | IORr* | * | r | ( -- ) | ( x* y* -- r* ) | |
0xD8 | IORr: | : | r | ( -- ) | ( x -- r ) | |
0xF8 | IORr*: | * | : | r | ( -- ) | ( x* -- r* ) |
XOR
Find the bitwise non-equivalence of two values. This operation is also known as ‘exclusive-or’.
The value y
is popped from the primary stack, and then the value x
is popped from the primary stack. The value r
is then calculated bitwise, where each bit of r
is set only if exactly one of the corresponding bits of x
and y
is set. The value r
is then pushed to the primary stack.
Signature |
---|
( x y -- r ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x19 | XOR | ( x y -- r ) | ( -- ) | |||
0x39 | XOR* | * | ( x* y* -- r* ) | ( -- ) | ||
0x59 | XOR: | : | ( x -- r ) | ( -- ) | ||
0x79 | XOR*: | * | : | ( x* -- r* ) | ( -- ) | |
0x99 | XORr | r | ( -- ) | ( x y -- r ) | ||
0xB9 | XORr* | * | r | ( -- ) | ( x* y* -- r* ) | |
0xD9 | XORr: | : | r | ( -- ) | ( x -- r ) | |
0xF9 | XORr*: | * | : | r | ( -- ) | ( x* -- r* ) |
AND
Find the bitwise conjunction of two values. This operation is also known as ‘and’.
The value y
is popped from the primary stack, and then the value x
is popped from the primary stack. The value r
is then calculated bitwise, where each bit of r
is set only if both of the corresponding bits of x
and y
are set. The value r
is then pushed to the primary stack.
Signature |
---|
( x y -- r ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x1A | AND | ( x y -- r ) | ( -- ) | |||
0x3A | AND* | * | ( x* y* -- r* ) | ( -- ) | ||
0x5A | AND: | : | ( x -- r ) | ( -- ) | ||
0x7A | AND*: | * | : | ( x* -- r* ) | ( -- ) | |
0x9A | ANDr | r | ( -- ) | ( x y -- r ) | ||
0xBA | ANDr* | * | r | ( -- ) | ( x* y* -- r* ) | |
0xDA | ANDr: | : | r | ( -- ) | ( x -- r ) | |
0xFA | ANDr*: | * | : | r | ( -- ) | ( x* -- r* ) |
NOT
Find the bitwise compliment of a value. This operation is also known as ‘not’.
The value x
is popped from the primary stack. The value r
is then calculated bitwise, where each bit of r
is set only if the corresponding bit of x
is not set. The value r
is then pushed to the primary stack.
Signature |
---|
( x -- r ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x1B | NOT | ( x -- r ) | ( -- ) | |||
0x3B | NOT* | * | ( x* -- r* ) | ( -- ) | ||
0x5B | NOT: | : | ( -- r ) | ( -- ) | ||
0x7B | NOT*: | * | : | ( -- r* ) | ( -- ) | |
0x9B | NOTr | r | ( -- ) | ( x -- r ) | ||
0xBB | NOTr* | * | r | ( -- ) | ( x* -- r* ) | |
0xDB | NOTr: | : | r | ( -- ) | ( -- r ) | |
0xFB | NOTr*: | * | : | r | ( -- ) | ( -- r* ) |
SHF
Shift the bits of a value.
The byte y
is popped from the primary stack, then the value x
is popped from the primary stack. The value r
is calculated from x
by shifting the bits of x
rightwards by a distance represented by the lower four bits of y
, and then by shifting the resultant bits leftwards by a distance represented by the higher four bits of y
. The value r
is then pushed to the primary stack.
When a value is shifted n
bits in one direction, each bit of the value is set to the state of the bit lying n
bits in the opposite direction. If this would reach past the end of the value, the bit is unset.
Signature |
---|
( x y! -- r ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x1C | SHF | ( x y -- r ) | ( -- ) | |||
0x3C | SHF* | * | ( x* y -- r ) | ( -- ) | ||
0x5C | SHF: | : | ( x -- r ) | ( -- ) | ||
0x7C | SHF*: | * | : | ( x* -- r ) | ( -- ) | |
0x9C | SHFr | r | ( -- ) | ( x y -- r ) | ||
0xBC | SHFr* | * | r | ( -- ) | ( x* y -- r ) | |
0xDC | SHFr: | : | r | ( -- ) | ( x -- r ) | |
0xFC | SHFr*: | * | : | r | ( -- ) | ( x* -- r ) |
SHC
Rotate the bits of a value. This operation is also known as a ‘circular shift’.
The byte y
is popped from the primary stack, then the value x
is popped from the primary stack. The value r
is calculated from x
by rotating the bits of x
rightwards by a distance represented by the lower four bits of y
, and then by rotating the resultant bits leftwards by a distance represented by the higher four bits of y
. The value r
is then pushed to the primary stack.
When a value is rotated n
bits in one direction, each bit of the value is set to the state of the bit lying n
bits in the opposite direction. If this would reach past the end of the value, wrap around to the other end of the value and continue.
Signature |
---|
( x y! -- r ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x1D | SHC | ( x y -- r ) | ( -- ) | |||
0x3D | SHC* | * | ( x* y -- r ) | ( -- ) | ||
0x5D | SHC: | : | ( x -- r ) | ( -- ) | ||
0x7D | SHC*: | * | : | ( x* -- r ) | ( -- ) | |
0x9D | SHCr | r | ( -- ) | ( x y -- r ) | ||
0xBD | SHCr* | * | r | ( -- ) | ( x* y -- r ) | |
0xDD | SHCr: | : | r | ( -- ) | ( x -- r ) | |
0xFD | SHCr*: | * | : | r | ( -- ) | ( x* -- r ) |
TAL
Count the number of set bits in a value. This operation is also known as ‘population count’.
The value x
is popped from the primary stack, and then the value r
is calculated as the number of bits set in x
and is pushed to the primary stack.
Signature |
---|
( x -- r! ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x1E | TAL | ( x -- r ) | ( -- ) | |||
0x3E | TAL* | * | ( x* -- r ) | ( -- ) | ||
0x5E | TAL: | : | ( -- r ) | ( -- ) | ||
0x7E | TAL*: | * | : | ( -- r ) | ( -- ) | |
0x9E | TALr | r | ( -- ) | ( x -- r ) | ||
0xBE | TALr* | * | r | ( -- ) | ( x* -- r ) | |
0xDE | TALr: | : | r | ( -- ) | ( -- r ) | |
0xFE | TALr*: | * | : | r | ( -- ) | ( -- r ) |
REV
Reverse the order of bits in a value.
The value x
is popped from the primary stack. The value r
is then calculated bitwise, where each bit of r
starting from one end of the value is set only if the corresponding bit of x
starting from the opposite end of the value is set. The value r
is then pushed to the primary stack.
Signature |
---|
( x -- r ) |
Instr. | Mnm. | * | : | r | Working stack | Return stack |
---|---|---|---|---|---|---|
0x1F | REV | ( x -- r ) | ( -- ) | |||
0x3F | REV* | * | ( x* -- r* ) | ( -- ) | ||
0x5F | REV: | : | ( -- r ) | ( -- ) | ||
0x7F | REV*: | * | : | ( -- r* ) | ( -- ) | |
0x9F | REVr | r | ( -- ) | ( x -- r ) | ||
0xBF | REVr* | * | r | ( -- ) | ( x* -- r* ) | |
0xDF | REVr: | : | r | ( -- ) | ( -- r ) | |
0xFF | REVr*: | * | : | r | ( -- ) | ( -- r* ) |