diff --git a/pygen.ipynb b/pygen.ipynb index ac955c4..d3d354b 100644 --- a/pygen.ipynb +++ b/pygen.ipynb @@ -15,7 +15,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 1, "id": "b0fcd533", "metadata": {}, "outputs": [ @@ -68,7 +68,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 2, "id": "b33de8ac", "metadata": {}, "outputs": [ @@ -144,7 +144,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 3, "id": "58645013", "metadata": {}, "outputs": [ @@ -283,7 +283,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 4, "id": "452bc76c", "metadata": {}, "outputs": [ @@ -357,7 +357,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 5, "id": "5aaebef0", "metadata": {}, "outputs": [ @@ -380,7 +380,7 @@ "\n", "\n", "CPU.hpp updated successfully at: .//src//spider/runtime/cpu/CPU.hpp\n", - "Total lines in updated file: 792\n" + "Total lines in updated file: 883\n" ] } ], @@ -451,7 +451,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 8, "id": "instrmap_gen", "metadata": {}, "outputs": [ @@ -459,8 +459,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "InstrMap.cpp written to: .//src//spider/runtime/cpu/InstrMap.cpp\n", - " Size : 34,246 bytes\n", + "InstrMap.cpp written to: .//src//spider/runtime/instr/InstrMap.cpp\n", + " Size : 34,157 bytes\n", " Array entries : 512 (128 populated, 384 nullptr)\n", " Switch cases : 128\n", " Line endings : LF-only verified\n" @@ -516,8 +516,8 @@ "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('') # [CHANGE] Use absolute path to make paths more explicit\n", + "L.append('#include ')\n", "L.append('')\n", "L.append('namespace spider {')\n", "L.append('')\n", @@ -527,18 +527,19 @@ "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", + "# [CHANGE] Use CPU::Fn Instead\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(' * CPU::Fn fn = InstrMap[opcode];')\n", "L.append(' * if (fn) (cpu.*fn)();')\n", - "L.append(' */')\n", - "L.append(f'CPUInstr InstrMap[{TABLE_SIZE}] = {{')\n", + "L.append(' */') # [CHANGE] Made it part of the CPU & avoided explicit size.\n", + "L.append(f'CPU::Fn CPU::instrMap[] = {{')\n", "\n", "for opc in range(TABLE_SIZE):\n", " mnem = opcode_to_mnem.get(opc)\n", @@ -567,10 +568,10 @@ "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(' * @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", + "L.append('void CPU::executeSwLk() {')\n", + "L.append(' switch (_opcode) {')\n", "\n", "last_group = None\n", "for opc in sorted(opcode_to_mnem.keys()):\n", @@ -594,7 +595,8 @@ "INSTRMAP_SRC = '\\n'.join(L)\n", "\n", "# ── Write to file ───────────────────────────────────────────────────────────\n", - "INSTRMAP_PATH = f'{SRC_ROOT}/spider/runtime/cpu/InstrMap.cpp'\n", + "# [CHANGE] Write this in the instructions folder to avoid CPU file bloat\n", + "INSTRMAP_PATH = f'{SRC_ROOT}/spider/runtime/instr/InstrMap.cpp'\n", "\n", "with open(INSTRMAP_PATH, 'wb') as f:\n", " f.write(INSTRMAP_SRC.encode('utf-8'))\n", @@ -631,7 +633,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.5" + "version": "3.13.7" } }, "nbformat": 4, diff --git a/src/spider/runtime/cpu/CPU.cpp b/src/spider/runtime/cpu/CPU.cpp index 17366ff..3308b8f 100644 --- a/src/spider/runtime/cpu/CPU.cpp +++ b/src/spider/runtime/cpu/CPU.cpp @@ -22,7 +22,7 @@ namespace spider { RE{}, RN{}, RV{}, RM{}, ALU0{}, ALU1{}, _dst(nullptr), _src(nullptr), - _instr(0), _addrm(0), _size(0), + _opcode(0), _addrm(0), _size(0), _store(0), _post(&CPU::imp), _ram(nullptr), _reel(nullptr) { } @@ -67,7 +67,7 @@ namespace spider { void CPU::fetchInstr() { u16 i = _reel->readU16(RI); - _instr = (i >> 7) & 0x1FF; + _opcode = (i >> 7) & 0x1FF; _addrm = (i >> 2) & 0x1F; _size = i & 0x3; RI += 2; @@ -79,7 +79,7 @@ namespace spider { _opers[1] = _opers[0]; // call specific addressing mode - (this->*(CPU::addrModes[_addrm & 0x7]))(); + (this->*(CPU::addrModes[_addrm]))(); } void CPU::fetchOperSrc() { @@ -87,13 +87,17 @@ namespace spider { _alu = &ALU1; // call specific addressing mode - (this->*(CPU::addrModes[_addrm & 0x7]))(); + (this->*(CPU::addrModes[_addrm]))(); // modify the _addrm register _addrm >>= 3; _addrm++; } + void CPU::execute() { + (this->*(CPU::addrModes[_opcode]))(); + } + // Addressing Modes // /** diff --git a/src/spider/runtime/cpu/CPU.hpp b/src/spider/runtime/cpu/CPU.hpp index 057c7ba..a2e8aa5 100644 --- a/src/spider/runtime/cpu/CPU.hpp +++ b/src/spider/runtime/cpu/CPU.hpp @@ -16,9 +16,10 @@ namespace spider { static constexpr const u64 FLAG_EXCEPTION = 0b0000000000000000000000000000000000000000000000000000000000001000; static constexpr const u64 FLAG_MEMORY_MODE = 0b0000000000000000000000000000000000000000000000000000000000110000; - public: // Map of addressing modes + public: // Map of addressing modes & Instructions static CPU::Fn addrModes[]; + static CPU::Fn instrMap[]; public: // General Purpose Registers union { @@ -61,7 +62,7 @@ namespace spider { }; // Holds the current instruction opcode - u16 _instr : 9; + u16 _opcode : 9; // Holds the current addressing modes, // before they were used @@ -163,6 +164,23 @@ namespace spider { */ void fetchOperSrc(); + /** + * Executes an opcode, by means of directly + * accessing the instruction map and + * calling that function pointer. + */ + void execute(); + + /** + * Executes an opcode, by means of using + * a large switch statement. Only suitable + * for environments where the instruction + * map is not possible. + * + * This has yet to be proved!!! + */ + void executeSwLk(); + public: // Addressing Modes /** @@ -862,4 +880,4 @@ namespace spider { }; -} \ No newline at end of file +} diff --git a/src/spider/runtime/cpu/InstrMap.cpp b/src/spider/runtime/instr/InstrMap.cpp similarity index 99% rename from src/spider/runtime/cpu/InstrMap.cpp rename to src/spider/runtime/instr/InstrMap.cpp index ce2ce93..6d3e5de 100644 --- a/src/spider/runtime/cpu/InstrMap.cpp +++ b/src/spider/runtime/instr/InstrMap.cpp @@ -17,7 +17,7 @@ * */ -#include "CPU.hpp" +#include namespace spider { @@ -25,18 +25,16 @@ 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]; + * CPU::Fn fn = InstrMap[opcode]; * if (fn) (cpu.*fn)(); */ -CPUInstr InstrMap[512] = { +CPU::Fn CPU::instrMap[] = { &CPU::NOP, // 0x000 — No Operation &CPU::SPDR, // 0x001 — Will place the Spider version of the interpreter in RA &CPU::MMODE, // 0x002 — Set Memory Mode @@ -563,10 +561,10 @@ CPUInstr InstrMap[512] = { * 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). + * @param opcode 9-bit instruction opcode (0x000 - 0x1FF). */ -void CPU::execute(u16 opcode) { - switch (opcode) { +void CPU::executeSwLk() { + switch (_opcode) { // ── System ────────────────────────────────────── case 0x000: NOP(); break;