2 Commits

Author SHA1 Message Date
c6fdb59791 Merge pull request 'Add InstrMap.cpp generation to pygen' (#2) from diego/instrmap into main
Reviewed-on: #2
2026-03-25 16:34:43 +00:00
Diego De Gante Pérez
291aa0a949 Add InstrMap.cpp generation to pygen 2026-03-25 10:18:29 -06:00
5 changed files with 1187 additions and 257 deletions

View File

@@ -16,107 +16,107 @@ constexpr u8 ADDR_MODE_MASKS[][2] = {
{ 0x1E, 0x00 }, // FIR
{ 0x1E, 0x00 }, // FZR
{ 0x1E, 0x1F }, // LSR
{ 0x00, 0x00 }, // FVR
{ 0x00, 0x00 }, // MOV
{ 0x00, 0x00 }, // MOR
{ 0x04, 0x00 }, // FVR
{ 0x1E, 0xFF }, // MOV
{ 0x04, 0x04 }, // MOR
{ 0x00, 0x00 }, // AMOV
{ 0x04, 0x04 }, // SWP
{ 0x04, 0x00 }, // AHM
{ 0x00, 0x00 }, // COM
{ 0x00, 0x00 }, // NEG
{ 0x00, 0x00 }, // EXS
{ 0x00, 0x00 }, // INC
{ 0x00, 0x00 }, // DEC
{ 0x00, 0x00 }, // ADD
{ 0x00, 0x00 }, // SUB
{ 0x00, 0x00 }, // MUL
{ 0x00, 0x00 }, // UMUL
{ 0x00, 0x00 }, // DIV
{ 0x00, 0x00 }, // UDIV
{ 0x00, 0x00 }, // MOD
{ 0x00, 0x00 }, // UMOD
{ 0x00, 0x00 }, // DMOD
{ 0x00, 0x00 }, // UDMD
{ 0x00, 0x00 }, // FBT
{ 0x00, 0x00 }, // STB
{ 0x00, 0x00 }, // CRB
{ 0x00, 0x00 }, // TSB
{ 0x00, 0x00 }, // BOOL
{ 0x00, 0x00 }, // NOT
{ 0x00, 0x00 }, // AND
{ 0x00, 0x00 }, // OR
{ 0x00, 0x00 }, // XOR
{ 0x00, 0x00 }, // SHL
{ 0x00, 0x00 }, // SHR
{ 0x00, 0x00 }, // SSR
{ 0x00, 0x00 }, // ROL
{ 0x00, 0x00 }, // ROR
{ 0x00, 0x00 }, // CNT
{ 0x00, 0x00 }, // EQ
{ 0x00, 0x00 }, // NE
{ 0x00, 0x00 }, // GT
{ 0x00, 0x00 }, // GE
{ 0x00, 0x00 }, // LT
{ 0x00, 0x00 }, // LE
{ 0x00, 0x00 }, // JMP
{ 0x00, 0x00 }, // JEQ
{ 0x00, 0x00 }, // JNE
{ 0x00, 0x00 }, // JIF
{ 0x00, 0x00 }, // JMR
{ 0x00, 0x00 }, // JER
{ 0x00, 0x00 }, // JNR
{ 0x00, 0x00 }, // JIR
{ 0x00, 0x00 }, // SFB
{ 0x00, 0x00 }, // LFB
{ 0x00, 0x00 }, // JUF
{ 0x00, 0x00 }, // JUR
{ 0x00, 0x00 }, // PUSH
{ 0x00, 0x00 }, // POP
{ 0x00, 0x00 }, // ALLOC
{ 0x00, 0x00 }, // HFREE
{ 0x00, 0x00 }, // CALL
{ 0xFF, 0x00 }, // COM
{ 0xFF, 0x00 }, // NEG
{ 0xFF, 0x00 }, // EXS
{ 0xFF, 0x00 }, // INC
{ 0xFF, 0x00 }, // DEC
{ 0x1E, 0xFF }, // ADD
{ 0x1E, 0xFF }, // SUB
{ 0x1E, 0xFF }, // MUL
{ 0x1E, 0xFF }, // UMUL
{ 0x1E, 0xFF }, // DIV
{ 0x1E, 0xFF }, // UDIV
{ 0x1E, 0xFF }, // MOD
{ 0x1E, 0xFF }, // UMOD
{ 0x1E, 0xFF }, // DMOD
{ 0x1E, 0xFF }, // UDMD
{ 0xFF, 0x00 }, // FBT
{ 0x1E, 0xFF }, // STB
{ 0x1E, 0xFF }, // CRB
{ 0x1E, 0xFF }, // TSB
{ 0xFF, 0x00 }, // BOOL
{ 0xFF, 0x00 }, // NOT
{ 0x1E, 0xFF }, // AND
{ 0x1E, 0xFF }, // OR
{ 0x1E, 0xFF }, // XOR
{ 0x1E, 0xFF }, // SHL
{ 0x1E, 0xFF }, // SHR
{ 0x1E, 0xFF }, // SSR
{ 0x1E, 0xFF }, // ROL
{ 0x1E, 0xFF }, // ROR
{ 0xFF, 0x00 }, // CNT
{ 0x1E, 0xFF }, // EQ
{ 0x1E, 0xFF }, // NE
{ 0x1E, 0xFF }, // GT
{ 0x1E, 0xFF }, // GE
{ 0x1E, 0xFF }, // LT
{ 0x1E, 0xFF }, // LE
{ 0xFF, 0x00 }, // JMP
{ 0xFF, 0x00 }, // JEQ
{ 0xFF, 0x00 }, // JNE
{ 0x1E, 0xFF }, // JIF
{ 0xFF, 0x00 }, // JMR
{ 0xFF, 0x00 }, // JER
{ 0xFF, 0x00 }, // JNR
{ 0x1E, 0xFF }, // JIR
{ 0x1E, 0xFF }, // SFB
{ 0x1E, 0xFF }, // LFB
{ 0x1E, 0xFF }, // JUF
{ 0x1E, 0xFF }, // JUR
{ 0xFF, 0x00 }, // PUSH
{ 0xFF, 0x00 }, // POP
{ 0xFF, 0x00 }, // ALLOC
{ 0xFF, 0x00 }, // HFREE
{ 0xFF, 0x00 }, // CALL
{ 0x00, 0x00 }, // RET
{ 0x00, 0x00 }, // EDI
{ 0x00, 0x00 }, // SHSS
{ 0x00, 0x00 }, // FLI
{ 0x00, 0x00 }, // FNEG
{ 0x00, 0x00 }, // FADD
{ 0x00, 0x00 }, // FSUB
{ 0x00, 0x00 }, // FMUL
{ 0x00, 0x00 }, // FDIV
{ 0x00, 0x00 }, // FMOD
{ 0x00, 0x00 }, // FDMOD
{ 0x00, 0x00 }, // FEPS
{ 0x00, 0x00 }, // FEEP
{ 0x00, 0x00 }, // FEQ
{ 0x00, 0x00 }, // FNE
{ 0x00, 0x00 }, // FGT
{ 0x00, 0x00 }, // FGE
{ 0x00, 0x00 }, // FLT
{ 0x00, 0x00 }, // FLE
{ 0x00, 0x00 }, // F2D
{ 0x00, 0x00 }, // D2F
{ 0x00, 0x00 }, // I2F
{ 0x00, 0x00 }, // I2D
{ 0x00, 0x00 }, // L2F
{ 0x00, 0x00 }, // L2D
{ 0x00, 0x00 }, // F2I
{ 0x00, 0x00 }, // F2L
{ 0x00, 0x00 }, // D2I
{ 0x00, 0x00 }, // D2L
{ 0x00, 0x00 }, // SIN
{ 0x00, 0x00 }, // COS
{ 0x00, 0x00 }, // TAN
{ 0x00, 0x00 }, // ASIN
{ 0x00, 0x00 }, // ACOS
{ 0x00, 0x00 }, // ATAN
{ 0x00, 0x00 }, // ATAN2
{ 0x00, 0x00 }, // EXP
{ 0x00, 0x00 }, // LOG
{ 0x00, 0x00 }, // LOGAB
{ 0x00, 0x00 }, // POW
{ 0x00, 0x00 }, // SQRT
{ 0x00, 0x00 }, // ROOT
{ 0xFF, 0x00 }, // EDI
{ 0xFF, 0x00 }, // SHSS
{ 0xFF, 0x00 }, // FLI
{ 0xFF, 0x00 }, // FNEG
{ 0x1E, 0xFF }, // FADD
{ 0x1E, 0xFF }, // FSUB
{ 0x1E, 0xFF }, // FMUL
{ 0x1E, 0xFF }, // FDIV
{ 0x1E, 0xFF }, // FMOD
{ 0x1E, 0xFF }, // FDMOD
{ 0xFF, 0x00 }, // FEPS
{ 0xFF, 0x00 }, // FEEP
{ 0x1E, 0xFF }, // FEQ
{ 0x1E, 0xFF }, // FNE
{ 0x1E, 0xFF }, // FGT
{ 0x1E, 0xFF }, // FGE
{ 0x1E, 0xFF }, // FLT
{ 0x1E, 0xFF }, // FLE
{ 0xFF, 0x00 }, // F2D
{ 0xFF, 0x00 }, // D2F
{ 0xFF, 0x00 }, // I2F
{ 0xFF, 0x00 }, // I2D
{ 0xFF, 0x00 }, // L2F
{ 0xFF, 0x00 }, // L2D
{ 0xFF, 0x00 }, // F2I
{ 0xFF, 0x00 }, // F2L
{ 0xFF, 0x00 }, // D2I
{ 0xFF, 0x00 }, // D2L
{ 0xFF, 0x00 }, // SIN
{ 0xFF, 0x00 }, // COS
{ 0xFF, 0x00 }, // TAN
{ 0xFF, 0x00 }, // ASIN
{ 0xFF, 0x00 }, // ACOS
{ 0xFF, 0x00 }, // ATAN
{ 0x1E, 0xFF }, // ATAN2
{ 0xFF, 0x00 }, // EXP
{ 0xFF, 0x00 }, // LOG
{ 0x1E, 0xFF }, // LOGAB
{ 0x1E, 0xFF }, // POW
{ 0xFF, 0x00 }, // SQRT
{ 0x1E, 0xFF }, // ROOT
{ 0x00, 0x00 }, // ADC
{ 0x00, 0x00 }, // SWC
{ 0x00, 0x00 }, // MWO
@@ -127,6 +127,8 @@ constexpr u8 ADDR_MODE_MASKS[][2] = {
{ 0x00, 0x00 }, // MINV
{ 0x00, 0x00 }, // MTRA
{ 0x00, 0x00 }, // MDET
{ 0x00, 0x00 }, // QMKA
{ 0x00, 0x00 }, // QMUL
{ 0x00, 0x00 }, // XADD
{ 0x00, 0x00 }, // XSUB
{ 0x00, 0x00 }, // XAMA
@@ -140,18 +142,18 @@ constexpr u8 TYPE_SIZE_MASKS[] = {
0x00, // NOP
0x00, // SPDR
0x01, // MMODE
0x0F, // INT
0x0C, // LRV
0x0F, // FSR
0x0F, // FIR
0x0F, // FZR
0x0F, // LSR
0x0F, // FVR
0x00, // MOV
0x00, // MOR
0x00, // AMOV
0x00, // SWP
0x0F, // AHM
0x08, // INT
0x08, // LRV
0x08, // FSR
0x08, // FIR
0x08, // FZR
0x08, // LSR
0x08, // FVR
0x0F, // MOV
0x08, // MOR
0x08, // AMOV
0x08, // SWP
0x08, // AHM
0x0F, // COM
0x0F, // NEG
0x0F, // EXS
@@ -208,22 +210,22 @@ constexpr u8 TYPE_SIZE_MASKS[] = {
0x0F, // RET
0x0F, // EDI
0x0F, // SHSS
0x00, // FLI
0x00, // FNEG
0x00, // FADD
0x00, // FSUB
0x00, // FMUL
0x00, // FDIV
0x00, // FMOD
0x00, // FDMOD
0x00, // FEPS
0x00, // FEEP
0x00, // FEQ
0x00, // FNE
0x00, // FGT
0x00, // FGE
0x00, // FLT
0x00, // FLE
0x0C, // FLI
0x0C, // FNEG
0x0C, // FADD
0x0C, // FSUB
0x0C, // FMUL
0x0C, // FDIV
0x0C, // FMOD
0x0C, // FDMOD
0x0C, // FEPS
0x0C, // FEEP
0x0C, // FEQ
0x0C, // FNE
0x0C, // FGT
0x0C, // FGE
0x0C, // FLT
0x0C, // FLE
0x00, // F2D
0x00, // D2F
0x00, // I2F
@@ -234,19 +236,19 @@ constexpr u8 TYPE_SIZE_MASKS[] = {
0x00, // F2L
0x00, // D2I
0x00, // D2L
0x00, // SIN
0x00, // COS
0x00, // TAN
0x00, // ASIN
0x00, // ACOS
0x00, // ATAN
0x00, // ATAN2
0x00, // EXP
0x00, // LOG
0x00, // LOGAB
0x00, // POW
0x00, // SQRT
0x00, // ROOT
0x0C, // SIN
0x0C, // COS
0x0C, // TAN
0x0C, // ASIN
0x0C, // ACOS
0x0C, // ATAN
0x0C, // ATAN2
0x0C, // EXP
0x0C, // LOG
0x0C, // LOGAB
0x0C, // POW
0x0C, // SQRT
0x0C, // ROOT
0x00, // ADC
0x00, // SWC
0x00, // MWO
@@ -257,6 +259,8 @@ constexpr u8 TYPE_SIZE_MASKS[] = {
0x00, // MINV
0x00, // MTRA
0x00, // MDET
0x00, // QMKA
0x00, // QMUL
0x00, // XADD
0x00, // XSUB
0x00, // XAMA

Binary file not shown.

View File

@@ -15,7 +15,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 34,
"id": "b0fcd533",
"metadata": {},
"outputs": [
@@ -68,7 +68,7 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 35,
"id": "b33de8ac",
"metadata": {},
"outputs": [
@@ -144,7 +144,7 @@
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 36,
"id": "58645013",
"metadata": {},
"outputs": [
@@ -152,7 +152,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Real instructions : 126\n",
"Real instructions : 128\n",
"Reserved slots : 14\n",
"Duplicate check : PASSED\n",
"\n",
@@ -163,13 +163,14 @@
"Bit Wise 14\n",
"Boolean 12\n",
"Branch 12\n",
"Casts 10\n",
"Floating Point 10\n",
"Casts 10\n",
"Memory 9\n",
"Trigonometric 7\n",
"Exponential 6\n",
"Matrix 6\n",
"SIMD 5\n",
"Quaternion 2\n",
"Easter Eggs 1\n",
"\n",
"First 5 instructions:\n",
@@ -177,8 +178,8 @@
"0 000 NOP System 0 00 00\n",
"1 001 SPDR System 0 00 00\n",
"2 002 MMODE System 1 05 01\n",
"3 003 INT System 1 1F 0F\n",
"4 004 LRV System 1 1F 0C\n"
"3 003 INT System 1 1F 08\n",
"4 004 LRV System 1 1F 08\n"
]
}
],
@@ -214,6 +215,7 @@
" 'dis', # addressing mode: Displaced\n",
" 'addr_mask_1', # accepted addressing mode mask for param 1\n",
" 'addr_mask_2', # accepted addressing mode mask for param 2\n",
" 'ignores_addrm',# whether the instruction ignores addressing modes\n",
" 'B', # type size: Byte (1 byte) supported?\n",
" 'S', # type size: Short (2 bytes) supported?\n",
" 'I', # type size: Int (4 bytes) supported?\n",
@@ -221,6 +223,7 @@
" 'F', # type size: Float supported?\n",
" 'D', # type size: Double supported?\n",
" 'type_mask', # combined type size mask as hex string\n",
" 'expensive', # marks computationally expensive instructions\n",
" 'operation', # human-readable description of what the instruction does\n",
" 'skip_2', # trailing empty column\n",
"]\n",
@@ -280,7 +283,7 @@
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": 37,
"id": "452bc76c",
"metadata": {},
"outputs": [
@@ -289,7 +292,7 @@
"output_type": "stream",
"text": [
"Masks written to: .//autogen/InstructionMasks.hpp\n",
"Lines generated : 268\n"
"Lines generated : 272\n"
]
}
],
@@ -354,7 +357,7 @@
},
{
"cell_type": "code",
"execution_count": 8,
"execution_count": 38,
"id": "5aaebef0",
"metadata": {},
"outputs": [
@@ -362,7 +365,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Instructions formatted: 126\n",
"Instructions formatted: 128\n",
"\n",
"--- Preview (first 2 instructions) ---\n",
" // [System] 0x000 — NOP: No Operation\n",
@@ -377,7 +380,7 @@
"\n",
"\n",
"CPU.hpp updated successfully at: .//src//spider/runtime/cpu/CPU.hpp\n",
"Total lines in updated file: 674\n"
"Total lines in updated file: 792\n"
]
}
],
@@ -445,6 +448,171 @@
"print(f'\\nCPU.hpp updated successfully at: {CPU_HPP_PATH}')\n",
"print(f'Total lines in updated file: {len(updated.splitlines())}')\n"
]
},
{
"cell_type": "code",
"execution_count": 39,
"id": "instrmap_gen",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"InstrMap.cpp written to: .//src//spider/runtime/cpu/InstrMap.cpp\n",
" Size : 34,246 bytes\n",
" Array entries : 512 (128 populated, 384 nullptr)\n",
" Switch cases : 128\n",
" Line endings : LF-only verified\n"
]
}
],
"source": [
"# ── Generate InstrMap.cpp ────────────────────────────────────────────────────\n",
"# Produces two dispatch implementations in one file:\n",
"# 1. CPUInstr InstrMap[512] — array of member-function pointers\n",
"# 2. void CPU::execute(u16) — switch/case version\n",
"#\n",
"# Both use UPPERCASE method names matching the mnemonic column.\n",
"\n",
"TABLE_SIZE = 512 # 9-bit opcode space\n",
"\n",
"# Build opcode -> mnemonic lookup from the cleaned instruction DataFrame.\n",
"opcode_to_mnem: dict[int, str] = {}\n",
"opcode_to_name: dict[int, str] = {}\n",
"opcode_to_group: dict[int, str] = {}\n",
"\n",
"for _, row in instrs_df.iterrows():\n",
" bc = str(row['byte_code']).strip()\n",
" opc = int(bc, 16)\n",
" opcode_to_mnem[opc] = str(row['mnemonic']).strip()\n",
" opcode_to_name[opc] = str(row['name']).strip()\n",
" opcode_to_group[opc] = str(row['group']).strip()\n",
"\n",
"# Also track reserved slots for annotation.\n",
"reserved_opcodes: set[int] = set()\n",
"for _, row in reserved_df.iterrows():\n",
" bc = str(row['byte_code']).strip()\n",
" if bc and bc != 'nan':\n",
" reserved_opcodes.add(int(bc, 16))\n",
"\n",
"# ── Assemble the file ───────────────────────────────────────────────────────\n",
"L = []\n",
"L.append('/**')\n",
"L.append(' * @file InstrMap.cpp')\n",
"L.append(' * @brief Spider VM instruction dispatch — array and switch implementations.')\n",
"L.append(' *')\n",
"L.append(' * AUTO-GENERATED by pygen.ipynb — DO NOT EDIT BY HAND.')\n",
"L.append(' *')\n",
"L.append(' * This file provides two equivalent dispatch mechanisms:')\n",
"L.append(' *')\n",
"L.append(' * 1. InstrMap[] — A lookup table of member-function pointers indexed by')\n",
"L.append(' * opcode. O(1) dispatch; suitable for platforms where')\n",
"L.append(' * indirect calls through function pointers are efficient.')\n",
"L.append(' *')\n",
"L.append(' * 2. CPU::execute(u16) — A switch/case over every opcode. Lets the')\n",
"L.append(' * compiler emit a jump table or branch tree; may be')\n",
"L.append(' * preferable on microcontrollers or when link-time')\n",
"L.append(' * optimisation can inline the handlers.')\n",
"L.append(' *')\n",
"L.append(' */')\n",
"L.append('')\n",
"L.append('#include \"CPU.hpp\"')\n",
"L.append('')\n",
"L.append('namespace spider {')\n",
"L.append('')\n",
"\n",
"# ── Version 1: Array: ────────────────────────────────────────────────────────\n",
"L.append('// =============================================================')\n",
"L.append('// Version 1 — Lookup table of member-function pointers')\n",
"L.append('// =============================================================')\n",
"L.append('')\n",
"L.append('/** Pointer-to-member type for a zero-argument CPU instruction. */')\n",
"L.append('using CPUInstr = void (CPU::*)();')\n",
"L.append('')\n",
"L.append('/**')\n",
"L.append(f' * Instruction dispatch table ({TABLE_SIZE} entries, 9-bit opcode space).')\n",
"L.append(' *')\n",
"L.append(' * Usage:')\n",
"L.append(' * u16 opcode = fetch();')\n",
"L.append(' * CPUInstr fn = InstrMap[opcode];')\n",
"L.append(' * if (fn) (cpu.*fn)();')\n",
"L.append(' */')\n",
"L.append(f'CPUInstr InstrMap[{TABLE_SIZE}] = {{')\n",
"\n",
"for opc in range(TABLE_SIZE):\n",
" mnem = opcode_to_mnem.get(opc)\n",
" if mnem:\n",
" name = opcode_to_name[opc]\n",
" L.append(f' &CPU::{mnem + \",\":<28s}// 0x{opc:03X} — {name}')\n",
" else:\n",
" tag = ''\n",
" if opc in reserved_opcodes:\n",
" tag = ' (reserved)'\n",
" L.append(f' {\"nullptr,\":<28s}// 0x{opc:03X}{tag}')\n",
"\n",
"L.append('};')\n",
"L.append('')\n",
"L.append('')\n",
"\n",
"# ── Version 2: Switch ──────────────────────────────────────────────────────\n",
"L.append('// =============================================================')\n",
"L.append('// Version 2 — Switch dispatch')\n",
"L.append('// =============================================================')\n",
"L.append('')\n",
"L.append('/**')\n",
"L.append(' * Execute the instruction identified by @p opcode.')\n",
"L.append(' *')\n",
"L.append(' * This is functionally equivalent to the InstrMap[] table above')\n",
"L.append(' * but expressed as a switch so the compiler can choose the best')\n",
"L.append(' * lowering strategy (jump table, binary search, etc.).')\n",
"L.append(' *')\n",
"L.append(' * @param opcode 9-bit instruction opcode (0x000 0x1FF).')\n",
"L.append(' */')\n",
"L.append('void CPU::execute(u16 opcode) {')\n",
"L.append(' switch (opcode) {')\n",
"\n",
"last_group = None\n",
"for opc in sorted(opcode_to_mnem.keys()):\n",
" mnem = opcode_to_mnem[opc]\n",
" group = opcode_to_group[opc]\n",
" if group != last_group:\n",
" L.append('')\n",
" L.append(f' // ── {group} ' + '─' * max(1, 44 - len(group)))\n",
" last_group = group\n",
" L.append(f' case 0x{opc:03X}: {mnem}(); break;')\n",
"\n",
"L.append('')\n",
"L.append(' default:')\n",
"L.append(' break;')\n",
"L.append(' }')\n",
"L.append('}')\n",
"L.append('')\n",
"L.append('} // namespace spider')\n",
"L.append('')\n",
"\n",
"INSTRMAP_SRC = '\\n'.join(L)\n",
"\n",
"# ── Write to file ───────────────────────────────────────────────────────────\n",
"INSTRMAP_PATH = f'{SRC_ROOT}/spider/runtime/cpu/InstrMap.cpp'\n",
"\n",
"with open(INSTRMAP_PATH, 'wb') as f:\n",
" f.write(INSTRMAP_SRC.encode('utf-8'))\n",
"\n",
"# Verify LF-only\n",
"with open(INSTRMAP_PATH, 'rb') as f:\n",
" raw_bytes = f.read()\n",
"assert b'\\r' not in raw_bytes, 'CRLF detected in InstrMap.cpp!'\n",
"\n",
"array_count = INSTRMAP_SRC.count('&CPU::')\n",
"switch_count = INSTRMAP_SRC.count('case 0x')\n",
"\n",
"print(f'InstrMap.cpp written to: {INSTRMAP_PATH}')\n",
"print(f' Size : {len(raw_bytes):,} bytes')\n",
"print(f' Array entries : {TABLE_SIZE} ({array_count} populated, {TABLE_SIZE - array_count} nullptr)')\n",
"print(f' Switch cases : {switch_count}')\n",
"print(f' Line endings : LF-only verified')\n"
]
}
],
"metadata": {
@@ -463,7 +631,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.13.7"
"version": "3.10.5"
}
},
"nbformat": 4,

View File

@@ -234,327 +234,327 @@ namespace spider {
void MMODE();
// [System] 0x003 — INT: Interrupt
// Params: 1 | AddrMask1: 1F AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: 1F AddrMask2: 00 | TypeMask: 08
// Operation: Performs system interrupt no. (Dst) (See table)
void INT();
// [System] 0x004 — LRV: Load Interrupt Vector Register
// Params: 1 | AddrMask1: 1F AddrMask2: 00 | TypeMask: 0C
// Params: 1 | AddrMask1: 1F AddrMask2: 00 | TypeMask: 08
// Operation: Dst -> RV
void LRV();
// [System] 0x005 — FSR: Fetch System Register
// Params: 1 | AddrMask1: 1E AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: 1E AddrMask2: 00 | TypeMask: 08
// Operation: System Register at Dst -> Dst
void FSR();
// [System] 0x006 — FIR: Fetch Instruction Register
// Params: 1 | AddrMask1: 1E AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: 1E AddrMask2: 00 | TypeMask: 08
// Operation: Instruction Register -> Dst
void FIR();
// [System] 0x007 — FZR: Fetch Stack Base Register
// Params: 1 | AddrMask1: 1E AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: 1E AddrMask2: 00 | TypeMask: 08
// Operation: Stack Base Register -> Dst
void FZR();
// [System] 0x008 — LSR: Load System Register
// Params: 2 | AddrMask1: 1E AddrMask2: 1F | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: 1F | TypeMask: 08
// Operation: Src -> System Register at Dst
void LSR();
// [System] 0x009 — FVR: Fetch Interrupt Vector Register
// Params: 1 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: 04 AddrMask2: 00 | TypeMask: 08
// Operation: Interrupt Vector Register -> Dst
void FVR();
// [Memory] 0x00A — MOV: Moves values
// Params: 2 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Src -> Dst
void MOV();
// [Memory] 0x00B — MOR: Moves registers
// Params: 2 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 2 | AddrMask1: 04 AddrMask2: 04 | TypeMask: 08
// Operation: R Scr -> R Dst
void MOR();
// [Memory] 0x00C — AMOV: Array Move, uses X and Y as ptrs, A as amount
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 08
// Operation: Array from X to Y, by A amount
void AMOV();
// [Memory] 0x00D — SWP: Swap registers
// Params: 2 | AddrMask1: 04 AddrMask2: 04 | TypeMask: 00
// Params: 2 | AddrMask1: 04 AddrMask2: 04 | TypeMask: 08
// Operation: Src <-> Dst
void SWP();
// [Memory] 0x00E — AHM: Ask Host for Memory
// Params: 1 | AddrMask1: 04 AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: 04 AddrMask2: 00 | TypeMask: 08
// Operation: Asks the host for a specific size of memory. Responds with 0 or 1
void AHM();
// [Integer] 0x010 — COM: One's complement
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
// Operation: ~ Dst -> Dst
void COM();
// [Integer] 0x011 — NEG: Two's complement
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
// Operation: - Dst -> Dst
void NEG();
// [Integer] 0x012 — EXS: Extend Sign
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
// Operation: Last bit is copied and expanded for the next int size
void EXS();
// [Integer] 0x013 — INC: Increment
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
// Operation: Dst + 1 -> Dst
void INC();
// [Integer] 0x014 — DEC: Decrement
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
// Operation: Dst - 1 -> Dst
void DEC();
// [Integer] 0x015 — ADD: Addition
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Dst + Src -> Dst
void ADD();
// [Integer] 0x016 — SUB: Subtraction
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Dst - Src-> Dst
void SUB();
// [Integer] 0x017 — MUL: Multiplication
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Signed Dst * Src -> Dst
void MUL();
// [Integer] 0x018 — UMUL: Unsigned Multiplication
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Unsigned Dst * Src -> Dst
void UMUL();
// [Integer] 0x019 — DIV: Division
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Signed Dst / Src -> Dst
void DIV();
// [Integer] 0x01A — UDIV: Unsigned Division
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Unsigned Dst / Src -> Dst
void UDIV();
// [Integer] 0x01B — MOD: Modulus
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Signed Dst % Src -> Dst
void MOD();
// [Integer] 0x01C — UMOD: Unsigned Modulus
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Unsigned Dst % Src -> Dst
void UMOD();
// [Integer] 0x01D — DMOD: Division and Modulus
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Signed Dst / Src -> X, Dst % Src -> Y
void DMOD();
// [Integer] 0x01E — UDMD: Unsigned Division and Modulus
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Unsigned Dst / Src -> X, Dst % Src -> Y
void UDMD();
// [System] 0x01F — FBT: Test and update Flag Register (Integer) Bits
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
// Operation: Flags of Dst -
void FBT();
// [Bit Wise] 0x020 — STB: Set Bit
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Src# bit is set on Dst
void STB();
// [Bit Wise] 0x021 — CRB: Clear Bit
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Src# bit is cleared on Dst
void CRB();
// [Bit Wise] 0x022 — TSB: Test Bit
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Src# bit is tested against Dst, updates Equal Flag
void TSB();
// [Bit Wise] 0x023 — BOOL: Sets the booleaness of a value
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
// Operation: Tests Dst != 0, updates Equal Flag
void BOOL();
// [Bit Wise] 0x024 — NOT: Sets the inverse booleaness of a value (! BOOL)
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
// Operation: Tests Dst == 0, updates Equal Flag
void NOT();
// [Bit Wise] 0x025 — AND: Boolean AND operation
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Dst AND Src into Dst
void AND();
// [Bit Wise] 0x026 — OR: Boolean OR operation
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Dst OR Src into Dst
void OR();
// [Bit Wise] 0x027 — XOR: Boolean XOR operation
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Dst XOR Src into Dst
void XOR();
// [Bit Wise] 0x028 — SHL: Arithmetic Shift Left
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Dst << Src into Dst
void SHL();
// [Bit Wise] 0x029 — SHR: Arithmetic Shift Right
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Dst >> Src into Dst
void SHR();
// [Bit Wise] 0x02A — SSR: Signed Shift Right
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Dst >>> Src into Dst
void SSR();
// [Bit Wise] 0x02B — ROL: Rotate Left
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Dst ROL Src into Dst
void ROL();
// [Bit Wise] 0x02C — ROR: Rotate Right
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Dst ROR Src into Dst
void ROR();
// [Bit Wise] 0x02D — CNT: Counts bits
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
// Operation: # of 1's into Dst
void CNT();
// [Boolean] 0x030 — EQ: Equal
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Dst == Src into Dst
void EQ();
// [Boolean] 0x031 — NE: Not Equal
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Dst != Src into Dst
void NE();
// [Boolean] 0x032 — GT: Greater Than
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Dst > Src into Dst
void GT();
// [Boolean] 0x033 — GE: Greater or Equal Than
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Dst >= Src into Dst
void GE();
// [Boolean] 0x034 — LT: Lower Than
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Dst < Src into Dst
void LT();
// [Boolean] 0x035 — LE: Lower or Equal Than
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Dst <= Src into Dst
void LE();
// [Branch] 0x038 — JMP: Jump to absolute position
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
// Operation: Dst -> Instruction Register
void JMP();
// [Branch] 0x039 — JEQ: Jumps to position if EQ flag is set
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
// Operation: Dst -> Instruction Register IF Flags.EQ
void JEQ();
// [Branch] 0x03A — JNE: Jumps to position if EQ flag is cleared
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
// Operation: Dst -> Instruction Register IF NOT Flags.EQ
void JNE();
// [Branch] 0x03B — JIF: Jumps if value provided is booleanly true
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Dst -> Instruction Register IF Src
void JIF();
// [Branch] 0x03C — JMR: Jump Relative
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
// Operation: Dst + Instruction Register -> Instruction Register
void JMR();
// [Branch] 0x03D — JER: Jumps to relative position if EQ flag is set
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
// Operation: Dst + Instruction Register -> Instruction Register IF Flags.EQ
void JER();
// [Branch] 0x03E — JNR: Jumps to relative position if EQ flag is cleared
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
// Operation: Dst + Instruction Register -> Instruction Register IF NOT Flags.EQ
void JNR();
// [Branch] 0x03F — JIR: Jumps to relative position if value provided is booleanly true
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation: Dst + Instruction Register -> Instruction Register IF Src
void JIR();
// [System] 0x040 — SFB: Store (User) Flag Bit
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation:
void SFB();
// [System] 0x041 — LFB: Load (User) Flag Bit
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation:
void LFB();
// [Branch] 0x042 — JUF: Jump to absolute position, if user flag is true
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation:
void JUF();
// [Branch] 0x043 — JUR: Jump to relative position, if user flag is true
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F
// Operation:
void JUR();
// [Memory] 0x044 — PUSH: Push to stack
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
// Operation: Dst -> pushed into stack
void PUSH();
// [Memory] 0x045 — POP: Pop from stack
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
// Operation: popped from stack -> Dst
void POP();
// [Memory] 0x046 — ALLOC: Allocate to heap
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
// Operation: Dst -> heap ptr of size Dst
void ALLOC();
// [Memory] 0x047 — HFREE: Delete from heap
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
// Operation: Frees heap ptr in Dst
void HFREE();
// [Branch] 0x04A — CALL: Call function at instruction index
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
// Operation: Performs a function call, step XX
void CALL();
@@ -564,207 +564,207 @@ namespace spider {
void RET();
// [System] 0x04C — EDI: Enable/Disable External Interrupts
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
// Operation: bool( Dst ) -> Enable External Interrupts Bit
void EDI();
// [System] 0x04D — SHSS: Set Hotswap Signal Bit
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F
// Operation: bool( Dst ) -> Hot Swap Signal Bit
void SHSS();
// [Floating Point] 0x050 — FLI: Float Load Immediate
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
// Operation:
void FLI();
// [Floating Point] 0x051 — FNEG: Float negate
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
// Operation: - Dst -> Dst
void FNEG();
// [Floating Point] 0x052 — FADD: Float add
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
// Operation: Dst + Src -> Dst
void FADD();
// [Floating Point] 0x053 — FSUB: Float subtract
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
// Operation: Dst - Src-> Dst
void FSUB();
// [Floating Point] 0x054 — FMUL: Float multiplication
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
// Operation: Dst * Src -> Dst
void FMUL();
// [Floating Point] 0x055 — FDIV: Float division
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
// Operation: Dst / Src -> Dst
void FDIV();
// [Floating Point] 0x056 — FMOD: Float modulus
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
// Operation: Dst % Src -> Dst
void FMOD();
// [Floating Point] 0x057 — FDMOD: Float division and modulus
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
// Operation: Dst / Src -> X, Dst % Src -> Y
void FDMOD();
// [Floating Point] 0x058 — FEPS: Sets the float epsilon value, for comparison
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
// Operation: Dst -> Epsilon Register
void FEPS();
// [Floating Point] 0x059 — FEEP: Float Enable/Disable Epsilon
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
// Operation: bool( Dst ) -> Epsilon Enable Bit
void FEEP();
// [Boolean] 0x05A — FEQ: Float Equal
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
// Operation: Dst == Src into Dst
void FEQ();
// [Boolean] 0x05B — FNE: Float Not Equal
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
// Operation: Dst != Src into Dst
void FNE();
// [Boolean] 0x05C — FGT: Float Greater Than
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
// Operation: Dst > Src into Dst
void FGT();
// [Boolean] 0x05D — FGE: Float Greater or Equal Than
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
// Operation: Dst >= Src into Dst
void FGE();
// [Boolean] 0x05E — FLT: Float Lower Than
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
// Operation: Dst < Src into Dst
void FLT();
// [Boolean] 0x05F — FLE: Float Lower or Equal Than
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
// Operation: Dst <= Src into Dst
void FLE();
// [Casts] 0x060 — F2D: F32 (Float) to F64 (Double)
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00
// Operation: (cast) Dst -> Dst
void F2D();
// [Casts] 0x061 — D2F: F64 (Double) to F32 (Float)
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00
// Operation: (cast) Dst -> Dst
void D2F();
// [Casts] 0x062 — I2F: I32 (Integer) to F32 (Float)
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00
// Operation: (cast) Dst -> Dst
void I2F();
// [Casts] 0x063 — I2D: I32 (Integer) to F64 (Double)
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00
// Operation: (cast) Dst -> Dst
void I2D();
// [Casts] 0x064 — L2F: I64 (Long) to F32 (Float)
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00
// Operation: (cast) Dst -> Dst
void L2F();
// [Casts] 0x065 — L2D: I64 (Long) to F64 (Double)
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00
// Operation: (cast) Dst -> Dst
void L2D();
// [Casts] 0x066 — F2I: F32 (Float) to I32 (Integer)
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00
// Operation: (cast) Dst -> Dst
void F2I();
// [Casts] 0x067 — F2L: F32 (Float) to I64 (Long)
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00
// Operation: (cast) Dst -> Dst
void F2L();
// [Casts] 0x068 — D2I: F64 (Double) to I32 (Integer)
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00
// Operation: (cast) Dst -> Dst
void D2I();
// [Casts] 0x069 — D2L: F64 (Double) to I64 (Long)
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00
// Operation: (cast) Dst -> Dst
void D2L();
// [Trigonometric] 0x06C — SIN: Sine Function
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
// Operation: sin( Dst ) -> Dst
void SIN();
// [Trigonometric] 0x06D — COS: Cosine Function
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
// Operation: cos( Dst ) -> Dst
void COS();
// [Trigonometric] 0x06E — TAN: Tangent Function
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
// Operation: tan( Dst ) -> Dst
void TAN();
// [Trigonometric] 0x06F — ASIN: Arc Sine Function
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
// Operation: asin( Dst ) -> Dst
void ASIN();
// [Trigonometric] 0x070 — ACOS: Arc Cosine Function
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
// Operation: acos( Dst ) -> Dst
void ACOS();
// [Trigonometric] 0x071 — ATAN: Arc Tangent Function
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
// Operation: atan( Dst ) -> Dst
void ATAN();
// [Trigonometric] 0x072 — ATAN2: Arc Tangent Function with 2 Arguments
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
// Operation: atan( Dst, Src ) -> Dst
void ATAN2();
// [Exponential] 0x074 — EXP: Exponential Function
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
// Operation: exp( Dst ) -> Dst
void EXP();
// [Exponential] 0x075 — LOG: Natural Logarithm
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
// Operation: ln( Dst ) -> Dst
void LOG();
// [Exponential] 0x076 — LOGAB: Logarithm A of B
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
// Operation: log( Dst, Src ) -> Dst
void LOGAB();
// [Exponential] 0x077 — POW: Power Function
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
// Operation: pow( Dst, Src ) -> Dst
void POW();
// [Exponential] 0x078 — SQRT: Square Root
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C
// Operation: sqrt( Dst ) -> Dst
void SQRT();
// [Exponential] 0x079 — ROOT: General Root
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C
// Operation: pow( Dst, 1 / Src ) -> Dst
void ROOT();
@@ -818,6 +818,16 @@ namespace spider {
// Operation:
void MDET();
// [Quaternion] 0x086 — QMKA: Quaternion Make from Angles
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Operation:
void QMKA();
// [Quaternion] 0x087 — QMUL: Quaternion Multiply
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Operation:
void QMUL();
// [SIMD] 0x08A — XADD: SIMD Addition
// Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00
// Operation:

View File

@@ -0,0 +1,748 @@
/**
* @file InstrMap.cpp
* @brief Spider VM instruction dispatch — array and switch implementations.
*
* AUTO-GENERATED by pygen.ipynb — DO NOT EDIT BY HAND.
*
* This file provides two equivalent dispatch mechanisms:
*
* 1. InstrMap[] — A lookup table of member-function pointers indexed by
* opcode. O(1) dispatch; suitable for platforms where
* indirect calls through function pointers are efficient.
*
* 2. CPU::execute(u16) — A switch/case over every opcode. Lets the
* compiler emit a jump table or branch tree; may be
* preferable on microcontrollers or when link-time
* optimisation can inline the handlers.
*
*/
#include "CPU.hpp"
namespace spider {
// =============================================================
// Version 1 — Lookup table of member-function pointers
// =============================================================
/** Pointer-to-member type for a zero-argument CPU instruction. */
using CPUInstr = void (CPU::*)();
/**
* Instruction dispatch table (512 entries, 9-bit opcode space).
*
* Usage:
* u16 opcode = fetch();
* CPUInstr fn = InstrMap[opcode];
* if (fn) (cpu.*fn)();
*/
CPUInstr InstrMap[512] = {
&CPU::NOP, // 0x000 — No Operation
&CPU::SPDR, // 0x001 — Will place the Spider version of the interpreter in RA
&CPU::MMODE, // 0x002 — Set Memory Mode
&CPU::INT, // 0x003 — Interrupt
&CPU::LRV, // 0x004 — Load Interrupt Vector Register
&CPU::FSR, // 0x005 — Fetch System Register
&CPU::FIR, // 0x006 — Fetch Instruction Register
&CPU::FZR, // 0x007 — Fetch Stack Base Register
&CPU::LSR, // 0x008 — Load System Register
&CPU::FVR, // 0x009 — Fetch Interrupt Vector Register
&CPU::MOV, // 0x00A — Moves values
&CPU::MOR, // 0x00B — Moves registers
&CPU::AMOV, // 0x00C — Array Move, uses X and Y as ptrs, A as amount
&CPU::SWP, // 0x00D — Swap registers
&CPU::AHM, // 0x00E — Ask Host for Memory
nullptr, // 0x00F (reserved)
&CPU::COM, // 0x010 — One's complement
&CPU::NEG, // 0x011 — Two's complement
&CPU::EXS, // 0x012 — Extend Sign
&CPU::INC, // 0x013 — Increment
&CPU::DEC, // 0x014 — Decrement
&CPU::ADD, // 0x015 — Addition
&CPU::SUB, // 0x016 — Subtraction
&CPU::MUL, // 0x017 — Multiplication
&CPU::UMUL, // 0x018 — Unsigned Multiplication
&CPU::DIV, // 0x019 — Division
&CPU::UDIV, // 0x01A — Unsigned Division
&CPU::MOD, // 0x01B — Modulus
&CPU::UMOD, // 0x01C — Unsigned Modulus
&CPU::DMOD, // 0x01D — Division and Modulus
&CPU::UDMD, // 0x01E — Unsigned Division and Modulus
&CPU::FBT, // 0x01F — Test and update Flag Register (Integer) Bits
&CPU::STB, // 0x020 — Set Bit
&CPU::CRB, // 0x021 — Clear Bit
&CPU::TSB, // 0x022 — Test Bit
&CPU::BOOL, // 0x023 — Sets the booleaness of a value
&CPU::NOT, // 0x024 — Sets the inverse booleaness of a value (! BOOL)
&CPU::AND, // 0x025 — Boolean AND operation
&CPU::OR, // 0x026 — Boolean OR operation
&CPU::XOR, // 0x027 — Boolean XOR operation
&CPU::SHL, // 0x028 — Arithmetic Shift Left
&CPU::SHR, // 0x029 — Arithmetic Shift Right
&CPU::SSR, // 0x02A — Signed Shift Right
&CPU::ROL, // 0x02B — Rotate Left
&CPU::ROR, // 0x02C — Rotate Right
&CPU::CNT, // 0x02D — Counts bits
nullptr, // 0x02E (reserved)
nullptr, // 0x02F (reserved)
&CPU::EQ, // 0x030 — Equal
&CPU::NE, // 0x031 — Not Equal
&CPU::GT, // 0x032 — Greater Than
&CPU::GE, // 0x033 — Greater or Equal Than
&CPU::LT, // 0x034 — Lower Than
&CPU::LE, // 0x035 — Lower or Equal Than
nullptr, // 0x036 (reserved)
nullptr, // 0x037 (reserved)
&CPU::JMP, // 0x038 — Jump to absolute position
&CPU::JEQ, // 0x039 — Jumps to position if EQ flag is set
&CPU::JNE, // 0x03A — Jumps to position if EQ flag is cleared
&CPU::JIF, // 0x03B — Jumps if value provided is booleanly true
&CPU::JMR, // 0x03C — Jump Relative
&CPU::JER, // 0x03D — Jumps to relative position if EQ flag is set
&CPU::JNR, // 0x03E — Jumps to relative position if EQ flag is cleared
&CPU::JIR, // 0x03F — Jumps to relative position if value provided is booleanly true
&CPU::SFB, // 0x040 — Store (User) Flag Bit
&CPU::LFB, // 0x041 — Load (User) Flag Bit
&CPU::JUF, // 0x042 — Jump to absolute position, if user flag is true
&CPU::JUR, // 0x043 — Jump to relative position, if user flag is true
&CPU::PUSH, // 0x044 — Push to stack
&CPU::POP, // 0x045 — Pop from stack
&CPU::ALLOC, // 0x046 — Allocate to heap
&CPU::HFREE, // 0x047 — Delete from heap
nullptr, // 0x048 (reserved)
nullptr, // 0x049 (reserved)
&CPU::CALL, // 0x04A — Call function at instruction index
&CPU::RET, // 0x04B — Return from a function
&CPU::EDI, // 0x04C — Enable/Disable External Interrupts
&CPU::SHSS, // 0x04D — Set Hotswap Signal Bit
nullptr, // 0x04E (reserved)
nullptr, // 0x04F (reserved)
&CPU::FLI, // 0x050 — Float Load Immediate
&CPU::FNEG, // 0x051 — Float negate
&CPU::FADD, // 0x052 — Float add
&CPU::FSUB, // 0x053 — Float subtract
&CPU::FMUL, // 0x054 — Float multiplication
&CPU::FDIV, // 0x055 — Float division
&CPU::FMOD, // 0x056 — Float modulus
&CPU::FDMOD, // 0x057 — Float division and modulus
&CPU::FEPS, // 0x058 — Sets the float epsilon value, for comparison
&CPU::FEEP, // 0x059 — Float Enable/Disable Epsilon
&CPU::FEQ, // 0x05A — Float Equal
&CPU::FNE, // 0x05B — Float Not Equal
&CPU::FGT, // 0x05C — Float Greater Than
&CPU::FGE, // 0x05D — Float Greater or Equal Than
&CPU::FLT, // 0x05E — Float Lower Than
&CPU::FLE, // 0x05F — Float Lower or Equal Than
&CPU::F2D, // 0x060 — F32 (Float) to F64 (Double)
&CPU::D2F, // 0x061 — F64 (Double) to F32 (Float)
&CPU::I2F, // 0x062 — I32 (Integer) to F32 (Float)
&CPU::I2D, // 0x063 — I32 (Integer) to F64 (Double)
&CPU::L2F, // 0x064 — I64 (Long) to F32 (Float)
&CPU::L2D, // 0x065 — I64 (Long) to F64 (Double)
&CPU::F2I, // 0x066 — F32 (Float) to I32 (Integer)
&CPU::F2L, // 0x067 — F32 (Float) to I64 (Long)
&CPU::D2I, // 0x068 — F64 (Double) to I32 (Integer)
&CPU::D2L, // 0x069 — F64 (Double) to I64 (Long)
nullptr, // 0x06A (reserved)
nullptr, // 0x06B (reserved)
&CPU::SIN, // 0x06C — Sine Function
&CPU::COS, // 0x06D — Cosine Function
&CPU::TAN, // 0x06E — Tangent Function
&CPU::ASIN, // 0x06F — Arc Sine Function
&CPU::ACOS, // 0x070 — Arc Cosine Function
&CPU::ATAN, // 0x071 — Arc Tangent Function
&CPU::ATAN2, // 0x072 — Arc Tangent Function with 2 Arguments
nullptr, // 0x073 (reserved)
&CPU::EXP, // 0x074 — Exponential Function
&CPU::LOG, // 0x075 — Natural Logarithm
&CPU::LOGAB, // 0x076 — Logarithm A of B
&CPU::POW, // 0x077 — Power Function
&CPU::SQRT, // 0x078 — Square Root
&CPU::ROOT, // 0x079 — General Root
nullptr, // 0x07A (reserved)
nullptr, // 0x07B (reserved)
&CPU::ADC, // 0x07C — Add with Carry
&CPU::SWC, // 0x07D — Subtract with Carry (Borrow)
&CPU::MWO, // 0x07E — Multiply with Overflow
&CPU::UMO, // 0x07F — Unsigned Multiply with Overflow
&CPU::MADD, // 0x080 — Matrix Addition
&CPU::MSUB, // 0x081 — Matrix Subtraction
&CPU::MMUL, // 0x082 — Matrix Multiply
&CPU::MINV, // 0x083 — Matrix Inverse
&CPU::MTRA, // 0x084 — Matrix Transpose
&CPU::MDET, // 0x085 — Matrix Determinant
&CPU::QMKA, // 0x086 — Quaternion Make from Angles
&CPU::QMUL, // 0x087 — Quaternion Multiply
nullptr, // 0x088
nullptr, // 0x089
&CPU::XADD, // 0x08A — SIMD Addition
&CPU::XSUB, // 0x08B — SIMD Subtract
&CPU::XAMA, // 0x08C — SIMD Alternate Multiply-Add
&CPU::XMUL, // 0x08D — SIMD Multiply
&CPU::XDIV, // 0x08E — SIMD Divide
nullptr, // 0x08F
nullptr, // 0x090
nullptr, // 0x091
nullptr, // 0x092
nullptr, // 0x093
nullptr, // 0x094
nullptr, // 0x095
nullptr, // 0x096
nullptr, // 0x097
nullptr, // 0x098
nullptr, // 0x099
nullptr, // 0x09A
nullptr, // 0x09B
nullptr, // 0x09C
nullptr, // 0x09D
nullptr, // 0x09E
nullptr, // 0x09F
nullptr, // 0x0A0
nullptr, // 0x0A1
nullptr, // 0x0A2
nullptr, // 0x0A3
nullptr, // 0x0A4
nullptr, // 0x0A5
nullptr, // 0x0A6
nullptr, // 0x0A7
nullptr, // 0x0A8
nullptr, // 0x0A9
nullptr, // 0x0AA
nullptr, // 0x0AB
nullptr, // 0x0AC
nullptr, // 0x0AD
nullptr, // 0x0AE
nullptr, // 0x0AF
nullptr, // 0x0B0
nullptr, // 0x0B1
nullptr, // 0x0B2
nullptr, // 0x0B3
nullptr, // 0x0B4
nullptr, // 0x0B5
nullptr, // 0x0B6
nullptr, // 0x0B7
nullptr, // 0x0B8
nullptr, // 0x0B9
nullptr, // 0x0BA
nullptr, // 0x0BB
nullptr, // 0x0BC
nullptr, // 0x0BD
nullptr, // 0x0BE
nullptr, // 0x0BF
nullptr, // 0x0C0
nullptr, // 0x0C1
nullptr, // 0x0C2
nullptr, // 0x0C3
nullptr, // 0x0C4
nullptr, // 0x0C5
nullptr, // 0x0C6
nullptr, // 0x0C7
nullptr, // 0x0C8
nullptr, // 0x0C9
nullptr, // 0x0CA
nullptr, // 0x0CB
nullptr, // 0x0CC
nullptr, // 0x0CD
nullptr, // 0x0CE
nullptr, // 0x0CF
nullptr, // 0x0D0
nullptr, // 0x0D1
nullptr, // 0x0D2
nullptr, // 0x0D3
nullptr, // 0x0D4
nullptr, // 0x0D5
nullptr, // 0x0D6
nullptr, // 0x0D7
nullptr, // 0x0D8
nullptr, // 0x0D9
nullptr, // 0x0DA
nullptr, // 0x0DB
nullptr, // 0x0DC
nullptr, // 0x0DD
nullptr, // 0x0DE
nullptr, // 0x0DF
nullptr, // 0x0E0
nullptr, // 0x0E1
nullptr, // 0x0E2
nullptr, // 0x0E3
nullptr, // 0x0E4
nullptr, // 0x0E5
nullptr, // 0x0E6
nullptr, // 0x0E7
nullptr, // 0x0E8
nullptr, // 0x0E9
nullptr, // 0x0EA
nullptr, // 0x0EB
nullptr, // 0x0EC
nullptr, // 0x0ED
nullptr, // 0x0EE
nullptr, // 0x0EF
&CPU::UPY, // 0x0F0 — Will place "YUPI" in memory
nullptr, // 0x0F1
nullptr, // 0x0F2
nullptr, // 0x0F3
nullptr, // 0x0F4
nullptr, // 0x0F5
nullptr, // 0x0F6
nullptr, // 0x0F7
nullptr, // 0x0F8
nullptr, // 0x0F9
nullptr, // 0x0FA
nullptr, // 0x0FB
nullptr, // 0x0FC
nullptr, // 0x0FD
nullptr, // 0x0FE
nullptr, // 0x0FF
nullptr, // 0x100
nullptr, // 0x101
nullptr, // 0x102
nullptr, // 0x103
nullptr, // 0x104
nullptr, // 0x105
nullptr, // 0x106
nullptr, // 0x107
nullptr, // 0x108
nullptr, // 0x109
nullptr, // 0x10A
nullptr, // 0x10B
nullptr, // 0x10C
nullptr, // 0x10D
nullptr, // 0x10E
nullptr, // 0x10F
nullptr, // 0x110
nullptr, // 0x111
nullptr, // 0x112
nullptr, // 0x113
nullptr, // 0x114
nullptr, // 0x115
nullptr, // 0x116
nullptr, // 0x117
nullptr, // 0x118
nullptr, // 0x119
nullptr, // 0x11A
nullptr, // 0x11B
nullptr, // 0x11C
nullptr, // 0x11D
nullptr, // 0x11E
nullptr, // 0x11F
nullptr, // 0x120
nullptr, // 0x121
nullptr, // 0x122
nullptr, // 0x123
nullptr, // 0x124
nullptr, // 0x125
nullptr, // 0x126
nullptr, // 0x127
nullptr, // 0x128
nullptr, // 0x129
nullptr, // 0x12A
nullptr, // 0x12B
nullptr, // 0x12C
nullptr, // 0x12D
nullptr, // 0x12E
nullptr, // 0x12F
nullptr, // 0x130
nullptr, // 0x131
nullptr, // 0x132
nullptr, // 0x133
nullptr, // 0x134
nullptr, // 0x135
nullptr, // 0x136
nullptr, // 0x137
nullptr, // 0x138
nullptr, // 0x139
nullptr, // 0x13A
nullptr, // 0x13B
nullptr, // 0x13C
nullptr, // 0x13D
nullptr, // 0x13E
nullptr, // 0x13F
nullptr, // 0x140
nullptr, // 0x141
nullptr, // 0x142
nullptr, // 0x143
nullptr, // 0x144
nullptr, // 0x145
nullptr, // 0x146
nullptr, // 0x147
nullptr, // 0x148
nullptr, // 0x149
nullptr, // 0x14A
nullptr, // 0x14B
nullptr, // 0x14C
nullptr, // 0x14D
nullptr, // 0x14E
nullptr, // 0x14F
nullptr, // 0x150
nullptr, // 0x151
nullptr, // 0x152
nullptr, // 0x153
nullptr, // 0x154
nullptr, // 0x155
nullptr, // 0x156
nullptr, // 0x157
nullptr, // 0x158
nullptr, // 0x159
nullptr, // 0x15A
nullptr, // 0x15B
nullptr, // 0x15C
nullptr, // 0x15D
nullptr, // 0x15E
nullptr, // 0x15F
nullptr, // 0x160
nullptr, // 0x161
nullptr, // 0x162
nullptr, // 0x163
nullptr, // 0x164
nullptr, // 0x165
nullptr, // 0x166
nullptr, // 0x167
nullptr, // 0x168
nullptr, // 0x169
nullptr, // 0x16A
nullptr, // 0x16B
nullptr, // 0x16C
nullptr, // 0x16D
nullptr, // 0x16E
nullptr, // 0x16F
nullptr, // 0x170
nullptr, // 0x171
nullptr, // 0x172
nullptr, // 0x173
nullptr, // 0x174
nullptr, // 0x175
nullptr, // 0x176
nullptr, // 0x177
nullptr, // 0x178
nullptr, // 0x179
nullptr, // 0x17A
nullptr, // 0x17B
nullptr, // 0x17C
nullptr, // 0x17D
nullptr, // 0x17E
nullptr, // 0x17F
nullptr, // 0x180
nullptr, // 0x181
nullptr, // 0x182
nullptr, // 0x183
nullptr, // 0x184
nullptr, // 0x185
nullptr, // 0x186
nullptr, // 0x187
nullptr, // 0x188
nullptr, // 0x189
nullptr, // 0x18A
nullptr, // 0x18B
nullptr, // 0x18C
nullptr, // 0x18D
nullptr, // 0x18E
nullptr, // 0x18F
nullptr, // 0x190
nullptr, // 0x191
nullptr, // 0x192
nullptr, // 0x193
nullptr, // 0x194
nullptr, // 0x195
nullptr, // 0x196
nullptr, // 0x197
nullptr, // 0x198
nullptr, // 0x199
nullptr, // 0x19A
nullptr, // 0x19B
nullptr, // 0x19C
nullptr, // 0x19D
nullptr, // 0x19E
nullptr, // 0x19F
nullptr, // 0x1A0
nullptr, // 0x1A1
nullptr, // 0x1A2
nullptr, // 0x1A3
nullptr, // 0x1A4
nullptr, // 0x1A5
nullptr, // 0x1A6
nullptr, // 0x1A7
nullptr, // 0x1A8
nullptr, // 0x1A9
nullptr, // 0x1AA
nullptr, // 0x1AB
nullptr, // 0x1AC
nullptr, // 0x1AD
nullptr, // 0x1AE
nullptr, // 0x1AF
nullptr, // 0x1B0
nullptr, // 0x1B1
nullptr, // 0x1B2
nullptr, // 0x1B3
nullptr, // 0x1B4
nullptr, // 0x1B5
nullptr, // 0x1B6
nullptr, // 0x1B7
nullptr, // 0x1B8
nullptr, // 0x1B9
nullptr, // 0x1BA
nullptr, // 0x1BB
nullptr, // 0x1BC
nullptr, // 0x1BD
nullptr, // 0x1BE
nullptr, // 0x1BF
nullptr, // 0x1C0
nullptr, // 0x1C1
nullptr, // 0x1C2
nullptr, // 0x1C3
nullptr, // 0x1C4
nullptr, // 0x1C5
nullptr, // 0x1C6
nullptr, // 0x1C7
nullptr, // 0x1C8
nullptr, // 0x1C9
nullptr, // 0x1CA
nullptr, // 0x1CB
nullptr, // 0x1CC
nullptr, // 0x1CD
nullptr, // 0x1CE
nullptr, // 0x1CF
nullptr, // 0x1D0
nullptr, // 0x1D1
nullptr, // 0x1D2
nullptr, // 0x1D3
nullptr, // 0x1D4
nullptr, // 0x1D5
nullptr, // 0x1D6
nullptr, // 0x1D7
nullptr, // 0x1D8
nullptr, // 0x1D9
nullptr, // 0x1DA
nullptr, // 0x1DB
nullptr, // 0x1DC
nullptr, // 0x1DD
nullptr, // 0x1DE
nullptr, // 0x1DF
nullptr, // 0x1E0
nullptr, // 0x1E1
nullptr, // 0x1E2
nullptr, // 0x1E3
nullptr, // 0x1E4
nullptr, // 0x1E5
nullptr, // 0x1E6
nullptr, // 0x1E7
nullptr, // 0x1E8
nullptr, // 0x1E9
nullptr, // 0x1EA
nullptr, // 0x1EB
nullptr, // 0x1EC
nullptr, // 0x1ED
nullptr, // 0x1EE
nullptr, // 0x1EF
nullptr, // 0x1F0
nullptr, // 0x1F1
nullptr, // 0x1F2
nullptr, // 0x1F3
nullptr, // 0x1F4
nullptr, // 0x1F5
nullptr, // 0x1F6
nullptr, // 0x1F7
nullptr, // 0x1F8
nullptr, // 0x1F9
nullptr, // 0x1FA
nullptr, // 0x1FB
nullptr, // 0x1FC
nullptr, // 0x1FD
nullptr, // 0x1FE
nullptr, // 0x1FF
};
// =============================================================
// Version 2 — Switch dispatch
// =============================================================
/**
* Execute the instruction identified by @p opcode.
*
* This is functionally equivalent to the InstrMap[] table above
* but expressed as a switch so the compiler can choose the best
* lowering strategy (jump table, binary search, etc.).
*
* @param opcode 9-bit instruction opcode (0x000 0x1FF).
*/
void CPU::execute(u16 opcode) {
switch (opcode) {
// ── System ──────────────────────────────────────
case 0x000: NOP(); break;
case 0x001: SPDR(); break;
case 0x002: MMODE(); break;
case 0x003: INT(); break;
case 0x004: LRV(); break;
case 0x005: FSR(); break;
case 0x006: FIR(); break;
case 0x007: FZR(); break;
case 0x008: LSR(); break;
case 0x009: FVR(); break;
// ── Memory ──────────────────────────────────────
case 0x00A: MOV(); break;
case 0x00B: MOR(); break;
case 0x00C: AMOV(); break;
case 0x00D: SWP(); break;
case 0x00E: AHM(); break;
// ── Integer ─────────────────────────────────────
case 0x010: COM(); break;
case 0x011: NEG(); break;
case 0x012: EXS(); break;
case 0x013: INC(); break;
case 0x014: DEC(); break;
case 0x015: ADD(); break;
case 0x016: SUB(); break;
case 0x017: MUL(); break;
case 0x018: UMUL(); break;
case 0x019: DIV(); break;
case 0x01A: UDIV(); break;
case 0x01B: MOD(); break;
case 0x01C: UMOD(); break;
case 0x01D: DMOD(); break;
case 0x01E: UDMD(); break;
// ── System ──────────────────────────────────────
case 0x01F: FBT(); break;
// ── Bit Wise ────────────────────────────────────
case 0x020: STB(); break;
case 0x021: CRB(); break;
case 0x022: TSB(); break;
case 0x023: BOOL(); break;
case 0x024: NOT(); break;
case 0x025: AND(); break;
case 0x026: OR(); break;
case 0x027: XOR(); break;
case 0x028: SHL(); break;
case 0x029: SHR(); break;
case 0x02A: SSR(); break;
case 0x02B: ROL(); break;
case 0x02C: ROR(); break;
case 0x02D: CNT(); break;
// ── Boolean ─────────────────────────────────────
case 0x030: EQ(); break;
case 0x031: NE(); break;
case 0x032: GT(); break;
case 0x033: GE(); break;
case 0x034: LT(); break;
case 0x035: LE(); break;
// ── Branch ──────────────────────────────────────
case 0x038: JMP(); break;
case 0x039: JEQ(); break;
case 0x03A: JNE(); break;
case 0x03B: JIF(); break;
case 0x03C: JMR(); break;
case 0x03D: JER(); break;
case 0x03E: JNR(); break;
case 0x03F: JIR(); break;
// ── System ──────────────────────────────────────
case 0x040: SFB(); break;
case 0x041: LFB(); break;
// ── Branch ──────────────────────────────────────
case 0x042: JUF(); break;
case 0x043: JUR(); break;
// ── Memory ──────────────────────────────────────
case 0x044: PUSH(); break;
case 0x045: POP(); break;
case 0x046: ALLOC(); break;
case 0x047: HFREE(); break;
// ── Branch ──────────────────────────────────────
case 0x04A: CALL(); break;
case 0x04B: RET(); break;
// ── System ──────────────────────────────────────
case 0x04C: EDI(); break;
case 0x04D: SHSS(); break;
// ── Floating Point ──────────────────────────────
case 0x050: FLI(); break;
case 0x051: FNEG(); break;
case 0x052: FADD(); break;
case 0x053: FSUB(); break;
case 0x054: FMUL(); break;
case 0x055: FDIV(); break;
case 0x056: FMOD(); break;
case 0x057: FDMOD(); break;
case 0x058: FEPS(); break;
case 0x059: FEEP(); break;
// ── Boolean ─────────────────────────────────────
case 0x05A: FEQ(); break;
case 0x05B: FNE(); break;
case 0x05C: FGT(); break;
case 0x05D: FGE(); break;
case 0x05E: FLT(); break;
case 0x05F: FLE(); break;
// ── Casts ───────────────────────────────────────
case 0x060: F2D(); break;
case 0x061: D2F(); break;
case 0x062: I2F(); break;
case 0x063: I2D(); break;
case 0x064: L2F(); break;
case 0x065: L2D(); break;
case 0x066: F2I(); break;
case 0x067: F2L(); break;
case 0x068: D2I(); break;
case 0x069: D2L(); break;
// ── Trigonometric ───────────────────────────────
case 0x06C: SIN(); break;
case 0x06D: COS(); break;
case 0x06E: TAN(); break;
case 0x06F: ASIN(); break;
case 0x070: ACOS(); break;
case 0x071: ATAN(); break;
case 0x072: ATAN2(); break;
// ── Exponential ─────────────────────────────────
case 0x074: EXP(); break;
case 0x075: LOG(); break;
case 0x076: LOGAB(); break;
case 0x077: POW(); break;
case 0x078: SQRT(); break;
case 0x079: ROOT(); break;
// ── Integer ─────────────────────────────────────
case 0x07C: ADC(); break;
case 0x07D: SWC(); break;
case 0x07E: MWO(); break;
case 0x07F: UMO(); break;
// ── Matrix ──────────────────────────────────────
case 0x080: MADD(); break;
case 0x081: MSUB(); break;
case 0x082: MMUL(); break;
case 0x083: MINV(); break;
case 0x084: MTRA(); break;
case 0x085: MDET(); break;
// ── Quaternion ──────────────────────────────────
case 0x086: QMKA(); break;
case 0x087: QMUL(); break;
// ── SIMD ────────────────────────────────────────
case 0x08A: XADD(); break;
case 0x08B: XSUB(); break;
case 0x08C: XAMA(); break;
case 0x08D: XMUL(); break;
case 0x08E: XDIV(); break;
// ── Easter Eggs ─────────────────────────────────
case 0x0F0: UPY(); break;
default:
break;
}
}
} // namespace spider