HoleyBytes ISA Specification
Bytecode format
- All numbers are encoded little-endian
- There is 256 registers, they are represented by a byte
- Immediate values are 64 bit
Instruction encoding
- Instruction parameters are packed (no alignment)
- [opcode, …parameters…]
Instruction parameter types
- B = Byte
- D = Doubleword (64 bits)
- H = Halfword (16 bits)
Name |
Size |
BBBB |
32 bits |
BBB |
24 bits |
BBDH |
96 bits |
BBDB |
88 bits |
BBD |
80 bits |
BB |
16 bits |
BD |
72 bits |
D |
64 bits |
N |
0 bits |
Instructions
#n
: register in parameter n
imm #n
: for immediate in parameter n
P ← V
: Set register P to value V
[x]
: Address x
No-op
Opcode |
Name |
Action |
0 |
NOP |
Do nothing |
Integer binary ops.
Opcode |
Name |
Action |
1 |
ADD |
Wrapping addition |
2 |
SUB |
Wrapping subtraction |
3 |
MUL |
Wrapping multiplication |
4 |
AND |
Bitand |
5 |
OR |
Bitor |
6 |
XOR |
Bitxor |
7 |
SL |
Unsigned left bitshift |
8 |
SR |
Unsigned right bitshift |
9 |
SRS |
Signed right bitshift |
Comparsion
Opcode |
Name |
Action |
10 |
CMP |
Signed comparsion |
11 |
CMPU |
Unsigned comparsion |
Comparsion table
#1 op #2 |
Result |
< |
-1 |
= |
0 |
> |
1 |
Division-remainder
- Type BBBB
- In case of
#3
is zero, the resulting value is all-ones
#0 ← #2 ÷ #3
#1 ← #2 % #3
Opcode |
Name |
Action |
12 |
DIR |
Divide and remainder combinated |
Negations
Opcode |
Name |
Action |
13 |
NEG |
Bit negation |
14 |
NOT |
Logical negation |
Integer immediate binary ops.
- Type BBD
#0 ← #1 <op> imm #2
Opcode |
Name |
Action |
18 |
ADDI |
Wrapping addition |
19 |
MULI |
Wrapping subtraction |
20 |
ANDI |
Bitand |
21 |
ORI |
Bitor |
22 |
XORI |
Bitxor |
23 |
SLI |
Unsigned left bitshift |
24 |
SRI |
Unsigned right bitshift |
25 |
SRSI |
Signed right bitshift |
Comparsion
- Comparsion is the same as when RRR type
Opcode |
Name |
Action |
26 |
CMPI |
Signed comparsion |
27 |
CMPUI |
Unsigned comparsion |
Register value set / copy
Copy
Opcode |
Name |
Action |
28 |
CP |
Copy |
Swap
Opcode |
Name |
Action |
29 |
SWA |
Swap |
Load immediate
Opcode |
Name |
Action |
30 |
LI |
Load immediate |
Memory operations
- Type BBDH
- If loaded/store value exceeds one register size, continue accessing following registers
Load / Store
Opcode |
Name |
Action |
31 |
LD |
#0 ← [#1 + imm #3], copy imm #4 bytes |
32 |
ST |
[#1 + imm #3] ← #0, copy imm #4 bytes |
Block copy
- Block copy source and target can overlap
Memory copy
Opcode |
Name |
Action |
33 |
BMC |
[#0] ← [#1], copy imm #2 bytes |
Register copy
- Type BBB
- Copy a block a register to another location (again, overflowing to following registers)
Opcode |
Name |
Action |
34 |
BRC |
#0 ← #1, copy imm #2 registers |
Control flow
Unconditional jump
Opcode |
Name |
Action |
35 |
JMP |
Jump at #0 + imm #1 |
Conditional jumps
- Type BBD
- Jump at
imm #2
if #0 <op> #1
Opcode |
Name |
Comparsion |
36 |
JEQ |
= |
37 |
JNE |
≠ |
38 |
JLT |
< (signed) |
39 |
JGT |
> (signed) |
40 |
JLTU |
< (unsigned) |
41 |
JGTU |
> (unsigned) |
Environment call
Opcode |
Name |
Action |
42 |
ECALL |
Cause an trap to the host environment |
Floating point operations
Opcode |
Name |
Action |
43 |
ADDF |
Addition |
44 |
MULF |
Multiplication |
Division-remainder
Opcode |
Name |
Action |
45 |
DIRF |
Same flow applies as for integer DIR |
Floating point immediate operations
- Type BBD
#0 ← #1 <op> imm #2
Opcode |
Name |
Action |
46 |
ADDFI |
Addition |
47 |
MULFI |
Multiplication |
Registers
- There is 255 registers + one zero register (with index 0)
- Reading from zero register yields zero
- Writing to zero register is a no-op
Memory
- Addresses are 64 bit
- Memory implementation is arbitrary
- In case of accessing invalid address:
- Program shall trap (LoadAccessEx, StoreAccessEx) with parameter of accessed address
- Value of register when trapped is undefined
Recommendations
- Leave address
0x0
as invalid
- If paging used:
- Leave first page invalid
- Pages should be at least 4 KiB
Program execution
- The way of program execution is implementation defined
- The order of instruction is arbitrary, as long all observable
effects are applied in the program's order
Program validation
- Invalid program should cause runtime error:
- The form of error is arbitrary. Can be a trap or an interpreter-specified error
- It shall not be handleable from within the program
- Executing invalid opcode should trap
- Program can be validaded either before execution or when executing
Traps
Name |
Parameters |
Cause |
LoadAccessEx |
Accessed address |
Loading invalid address |
StoreAccessEx |
Accessed address |
Storing to invalid address |
InvalidOpcode |
Loaded opcode |
Executing invalid opcode |
Ecall |
None |
Ecall instruction |
Assembly
HoleyBytes assembly format is not defined, this is just a weak description
of hbasm
syntax.
- Opcode names correspond to specified opcode names, lowercase (
nop
)
- Parameters are separated by comma (
addi r0, r0, 1
)
- Instructions are separated by either line feed or semicolon
- Registers are represented by
r
followed by the number (r10
)
- Labels are defined by label name followed with colon (
loop:
)
- Labels are references simply by their name (
print
)
- Immediates are entered plainly. Negative numbers supported.