README.md
July 24, 2025 ยท View on GitHub
OSMX64 is a 64-bit multi-core SoC architecture designed to be fast, efficient, and low-cost.
Registers
Registers store data which can be accessed at any time. These include special registers for
| Name | Size | Purpose |
|---|---|---|
x0 | 64 bits | Read-only, always 0 |
x1-x15 | 64 bits | General purpose, read-write |
f0-f7 | 32 bits | IEEE 754 single-precision number |
d0-d7 | 64 bits | IEEE 754 double-precision number |
v0-v7 | 512 bits | SIMD vector data |
pc | 64 bits | Program counter, 0 on startup |
sp | 64 bits | Stack pointer |
fp | 64 bits | Frame pointer |
ptp | 64 bits | Page tree pointer |
Link Registers
The link registers are for storing specific return addresses from a subroutine
| Name | Size | Purpose |
|---|---|---|
blr | 64 bits | Branch Link Register |
ilr | 64 bits | Interrupt Link Register |
When calling a subroutine, it will need to know where to return to when the execution finishes. To achieve this, we use the branch link register (BLR). In situations where an interrupt has occurred on the system, the CPU would need to know where to return to from the interrupt context, in cases such as this, we'd use the Interrupt Link Register (ILR).
Internal Registers
Only accessed by the CPU for certain instructions. Cannot be directly read/written.
| Name | Size | Purpose |
|---|---|---|
rp | 64 bits | Return pointer for branches |
ins | 64 bits | Current instruction at pc |
Special Registers
OSMX64 provides "special" control registers that may vary depending on the chip revision. These registers typically include chip-specific mode/control bits to configure the processor for certain modes of operations, etc. These registers cannot be accessed via the "mov" instruction and instead rely on independent wrs/rrs (i.e., special register write / special register read) instructions.
Common Special Registers
| Name | Size | Purpose |
|---|---|---|
SR_STATE | 64 bits | Processor state bits |
SR_STATE
| Bit | Meaning | Purpose |
|---|---|---|
| 0 | Reserved | Must be zero |
| 1 | Supervisor | Supervisor mode enable |
| 2 | Carry | Arithmetic carry flag |
| 3-31 | Reserved (must be 0) | Must be zero |
Supervisor bit
The supervisor bit may only be writable in a privileged mode of execution and is therefore readonly in user contexts (writes ignored). It may be unset by system software to transition the processor into a user context. This bit may only transition from a 0 to a 1 during an interrupt/trap, therefore manually writing a 1 to this bit is ignored by the processor.
Carry bit
Indicates whether an arithmetic operation has resulted in a carry/borrow.
Instructions
Special Register Access
Special registers are identified with a 16-bit Special Register ID (SRID) and can be accessed through two special instructions.
| Mnemonic | Effect |
|---|---|
wrs srid: r/imm, val: r | SREGS[srid] = val |
rrs dest: r, srid: r/imm | dest = SREGS[srid] |
Bitwise Instructions
Bitwise logic operations can write to all registers except v0-v7, x0 and pc. Can read from all registers except v0-v7.
| Mnemonic | Effect |
|---|---|
and dst: r, reg: r, val: r/imm | dst = dst & val |
or dst: r, reg: r, val: r/imm | dst = dst | val |
xor dst: r, reg: r, val: r/imm | dst = dst ^ val |
mrob dst: r: mask [bit]: imm | Fill byte of 'dst' with 'mask' |
mrow dst: r: mask [bit]: imm | Fill word of 'dst' with 'mask' |
mrod dst: r: mask [bit]: imm | Fill dword of 'dst' with 'mask' |
mroq dst: r: mask [bit]: imm | Fill qword of 'dst' with 'mask' |
Example
/* Set x1 to 5 */
mov x1, #5
/* Ands x1 (which equals 5) with 1 */
and x1, x1, #1
/* x1 now equals 1 */
Data Movement Instructions
| Mnemonic | Effect |
|---|---|
mov dst: r, src: r/imm | dst = src |
stb src: r, [dst: r/m, offset: r/imm] | 1-byte store to memory at dst |
stw src: r, [dst: r/m, offset: r/imm] | 2-byte store to memory at dst |
std src: r, [dst: r/m, offset: r/imm] | 4-byte store to memory at dst |
stq src: r, [dst: r/m, offset: r/imm] | 8-byte store to memory at dst |
ldb dst: r, [src: r/m, offset: r/imm] | 1-byte load from memory at src |
ldw dst: r, [src: r/m, offset: r/imm] | 2-byte load from memory at src |
ldd dst: r, [src: r/m, offset: r/imm] | 4-byte load from memory at src |
ldq dst: r, [src: r/m, offset: r/imm] | 8-byte load from memory at src |
Example
/* Set x1 to 7 */
mov x1, #7
/* Write to memory pointed by sp */
stq x1, [sp]
/* Write to memory pointed by sp + 8 */
stq x1, [sp, #8]
/* Write to memory pointed by sp + x2 */
mov x2, #16
stq x1, [sp, x2]
Arithmetic Instructions
Arithmetic operations can write to all registers except v0-v7, x0 and pc. Can read from all registers except v0-v7.
| Mnemonic | Effect |
|---|---|
add dst: r, val: r/imm | dst = dst + val |
sub dst: r, val: r/imm | dst = dst - val |
mul dst: r, val: r/imm | dst = dst * val |
div dst: r, val: r/imm | dst = dst / val |
inc dst: r | dst = dst + 1 |
dec dst: r | dst = dst - 1 |
Example
/* Set x1 to 5 */
mov x1, #5
/* Increment x1 */
inc x1
/* x1 now equals 6 */
Control Flow Instructions
Control flow instructions are used to control which instructions the CPU executes, allowing for the concept of procedures and conditional execution.
| Mnemonic | Effect |
|---|---|
hlt | Execution halted |
br dst: r | pc = dst |
brl dst: r | rp = pc + size of opcode, then pc = dst |
bret | pc = rp |
beq a: r/m, b: r/m/imm, dst: r/m/imm | Iff a = b, pc = dst |
bne a: r/m, b: r/m/imm, dst: r/m/imm | Iff a != b, pc = dst |
blt a: r/m, b: r/m/imm, dst: r/m/imm | Iff a < b, pc = dst |
bgt a: r/m, b: r/m/imm, dst: r/m/imm | Iff a > b, pc = dst |
ble a: r/m, b: r/m/imm, dst: r/m/imm | Iff a <= b, pc = dst |
bge a: r/m, b: r/m/imm, dst: r/m/imm | Iff a >= b, pc = dst |
Example
/* Subtract x2 from x1 */
sub x1, x1, x2
beq x1, #0, zero
mov x1, #2
zero:
mov x1, #3
/* Iff x1 - x2 = 0, x1 equals 3 */
/* Iff x1 - x1 != 0, x1 equals 2 */
Opcode list
NOP:0x00ADD:0x01SUB:0x02MUL:0x03DIV:0x04INC:0x05DEC:0x06OR:0x07XOR:0x08AND:0x09NOT:0x0ASLL:0x0BSRL:0x0CMOV_IMM:0x0DHLT:0x0EBR:0x0FMROB:0x10MROW:0x11MROD:0x12MROQ:0x13
Copyright (c) 2024 Quinn Stephens and Ian Marco Moffett. All rights reserved.