#pragma once #include #include namespace spider { class CPU { public: // Helper types using Fn = void (CPU::*)(); public: // Flag Register Constants // static constexpr const u64 FLAG_ENABLE = 0b0000000000000000000000000000000000000000000000000000000000000001; static constexpr const u64 FLAG_INTERRUPT_SIGNAL = 0b0000000000000000000000000000000000000000000000000000000000000010; static constexpr const u64 FLAG_INTERRUPT_REQUEST = 0b0000000000000000000000000000000000000000000000000000000000000100; static constexpr const u64 FLAG_EXCEPTION = 0b0000000000000000000000000000000000000000000000000000000000001000; static constexpr const u64 FLAG_MEMORY_MODE = 0b0000000000000000000000000000000000000000000000000000000000110000; public: // Map of addressing modes & Instructions static CPU::Fn addrModes[]; static CPU::Fn instrMap[]; public: // General Purpose Registers union { register_t GPR[16]; struct { register_t RA, RB, RC, RD, RX, RY, R0, R1, R2, R3, R4, R5, R6, R7, R8, R9; }; }; public: // System Registers u64 RF; u64 RI; u64 RS; u64 RZ; u64 RE; u64 RN; // Epsilo(n) u64 RV; u64 RM; public: /** * These are private registers, which are only used * whenever constant things are used. * This way we don't "write" into constant values, rather * we write into a writeable var which is "hidden" */ register_t ALU0, ALU1; union { struct { register_t* _dst; register_t* _src; register_t* _alu; }; register_t* _opers[2]; }; // Holds the current instruction opcode u16 _opcode : 9; // Holds the current addressing modes, // before they were used u8 _addrm : 5; // Holds the current instruction size. u8 _size : 2; // On _post that are not no-ops, it must // write back DST to this memory location. u64 _store; // Post execution callback CPU::Fn _post; private: /** * Pointer to the current RAM hooked into * the CPU. * * It is unproved whether having the RAM directly * into the CPU is better than not, or whether a * virtual BUS is better. * * Alas, this way we can have a CPU state switch * between memory and instruction banks. */ RAM* _ram; /** * Pointer to the current Instruction Reel * hooked into the CPU. * * Ditto as RAM. */ InstrReel* _reel; public: CPU(); CPU(const CPU& other) = default; CPU(CPU&& other) noexcept = default; ~CPU(); public: CPU& operator=(const CPU& other) = default; CPU& operator=(CPU&& other) noexcept = default; public: void hookRAM(RAM* ram); void hookInstrReel(InstrReel* reel); constexpr u64 getFlag(u64 mask); public: /** * Fetches the instruction from the * reel, and advances IR by two. */ void fetchInstr(); /** * Fetches the destination operand, * by calling the appropriate addressing * mode. * * Will read the bottom 3 bits. * For instructions with two operands, * call Src first. * * The internal variable _addrm * will not be modified. It will * be important when writing * back the result. */ void fetchOperDst(); /** * Fetches the source operand. * * For use in two operand instructions. * * Will read the bottom 3 bits. It will * then shift the _addrm 3 spaces * to ensure it aligns with the DST * next. * * Additionally, it will add 1 to _addrm * to account with */ 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 /** * Implied Addressing Mode */ void imp(); // Kept as it is a no-op /** * Immediate Addressing Mode */ void imm(); /** * Absolute Addressing Mode */ void abs(); /** * Register Addressing Mode */ void reg(); /** * Indrect Addressing Mode */ void ind(); /** * Pointer Addressing Mode */ void ptr(); /** * Indexed Addressing Mode */ void idx(); /** * Scaled Addressing Mode */ void sca(); /** * Displaced Addressing Mode */ void dis(); /** * Post-Write Action */ void psw(); public: // // // [System] 0x000 — NOP: No Operation // Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00 // Operation: Nothing void NOP(); // [System] 0x001 — SPDR: Will place the Spider version of the interpreter in RA // Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00 // Operation: (Spider Version) -> RA void SPDR(); // [System] 0x002 — MMODE: Set Memory Mode // Params: 1 | AddrMask1: 05 AddrMask2: 00 | TypeMask: 01 // Operation: Dst -> Memory Mode Bits void MMODE(); // [System] 0x003 — INT: Interrupt // 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: 08 // Operation: Dst -> RV void LRV(); // [System] 0x005 — FSR: Fetch System Register // 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: 08 // Operation: Instruction Register -> Dst void FIR(); // [System] 0x007 — FZR: Fetch Stack Base Register // 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: 08 // Operation: Src -> System Register at Dst void LSR(); // [System] 0x009 — FVR: Fetch Interrupt Vector Register // Params: 1 | AddrMask1: 04 AddrMask2: 00 | TypeMask: 08 // Operation: Interrupt Vector Register -> Dst void FVR(); // [Memory] 0x00A — MOV: Moves values // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Src -> Dst void MOV(); // [Memory] 0x00B — MOR: Moves registers // 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: 08 // Operation: Array from X to Y, by A amount void AMOV(); // [Memory] 0x00D — SWP: Swap registers // 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: 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: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F // Operation: ~ Dst -> Dst void COM(); // [Integer] 0x011 — NEG: Two's complement // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F // Operation: - Dst -> Dst void NEG(); // [Integer] 0x012 — EXS: Extend Sign // 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: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F // Operation: Dst + 1 -> Dst void INC(); // [Integer] 0x014 — DEC: Decrement // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F // Operation: Dst - 1 -> Dst void DEC(); // [Integer] 0x015 — ADD: Addition // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Dst + Src -> Dst void ADD(); // [Integer] 0x016 — SUB: Subtraction // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Dst - Src-> Dst void SUB(); // [Integer] 0x017 — MUL: Multiplication // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Signed Dst * Src -> Dst void MUL(); // [Integer] 0x018 — UMUL: Unsigned Multiplication // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Unsigned Dst * Src -> Dst void UMUL(); // [Integer] 0x019 — DIV: Division // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Signed Dst / Src -> Dst void DIV(); // [Integer] 0x01A — UDIV: Unsigned Division // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Unsigned Dst / Src -> Dst void UDIV(); // [Integer] 0x01B — MOD: Modulus // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Signed Dst % Src -> Dst void MOD(); // [Integer] 0x01C — UMOD: Unsigned Modulus // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Unsigned Dst % Src -> Dst void UMOD(); // [Integer] 0x01D — DMOD: Division and Modulus // 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: 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: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F // Operation: Flags of Dst - void FBT(); // [Bit Wise] 0x020 — STB: Set Bit // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Src# bit is set on Dst void STB(); // [Bit Wise] 0x021 — CRB: Clear Bit // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Src# bit is cleared on Dst void CRB(); // [Bit Wise] 0x022 — TSB: Test Bit // 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: 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: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F // Operation: Tests Dst == 0, updates Equal Flag void NOT(); // [Bit Wise] 0x025 — AND: Boolean AND operation // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Dst AND Src into Dst void AND(); // [Bit Wise] 0x026 — OR: Boolean OR operation // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Dst OR Src into Dst void OR(); // [Bit Wise] 0x027 — XOR: Boolean XOR operation // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Dst XOR Src into Dst void XOR(); // [Bit Wise] 0x028 — SHL: Arithmetic Shift Left // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Dst << Src into Dst void SHL(); // [Bit Wise] 0x029 — SHR: Arithmetic Shift Right // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Dst >> Src into Dst void SHR(); // [Bit Wise] 0x02A — SSR: Signed Shift Right // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Dst >>> Src into Dst void SSR(); // [Bit Wise] 0x02B — ROL: Rotate Left // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Dst ROL Src into Dst void ROL(); // [Bit Wise] 0x02C — ROR: Rotate Right // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Dst ROR Src into Dst void ROR(); // [Bit Wise] 0x02D — CNT: Counts bits // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F // Operation: # of 1's into Dst void CNT(); // [Boolean] 0x030 — EQ: Equal // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Dst == Src into Dst void EQ(); // [Boolean] 0x031 — NE: Not Equal // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Dst != Src into Dst void NE(); // [Boolean] 0x032 — GT: Greater Than // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Dst > Src into Dst void GT(); // [Boolean] 0x033 — GE: Greater or Equal Than // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Dst >= Src into Dst void GE(); // [Boolean] 0x034 — LT: Lower Than // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Dst < Src into Dst void LT(); // [Boolean] 0x035 — LE: Lower or Equal Than // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Dst <= Src into Dst void LE(); // [Branch] 0x038 — JMP: Jump to absolute position // 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: 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: 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: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: Dst -> Instruction Register IF Src void JIF(); // [Branch] 0x03C — JMR: Jump Relative // 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: 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: 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: 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: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: void SFB(); // [System] 0x041 — LFB: Load (User) Flag Bit // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: void LFB(); // [Branch] 0x042 — JUF: Jump to absolute position, if user flag is true // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: void JUF(); // [Branch] 0x043 — JUR: Jump to relative position, if user flag is true // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0F // Operation: void JUR(); // [Memory] 0x044 — PUSH: Push to stack // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F // Operation: Dst -> pushed into stack void PUSH(); // [Memory] 0x045 — POP: Pop from stack // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F // Operation: popped from stack -> Dst void POP(); // [Memory] 0x046 — ALLOC: Allocate to heap // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F // Operation: Dst -> heap ptr of size Dst void ALLOC(); // [Memory] 0x047 — HFREE: Delete from heap // 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: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F // Operation: Performs a function call, step XX void CALL(); // [Branch] 0x04B — RET: Return from a function // Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 0F // Operation: Undoes a function call, step XX void RET(); // [System] 0x04C — EDI: Enable/Disable External Interrupts // 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: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0F // Operation: bool( Dst ) -> Hot Swap Signal Bit void SHSS(); // [Floating Point] 0x050 — FLI: Float Load Immediate // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C // Operation: void FLI(); // [Floating Point] 0x051 — FNEG: Float negate // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C // Operation: - Dst -> Dst void FNEG(); // [Floating Point] 0x052 — FADD: Float add // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C // Operation: Dst + Src -> Dst void FADD(); // [Floating Point] 0x053 — FSUB: Float subtract // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C // Operation: Dst - Src-> Dst void FSUB(); // [Floating Point] 0x054 — FMUL: Float multiplication // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C // Operation: Dst * Src -> Dst void FMUL(); // [Floating Point] 0x055 — FDIV: Float division // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C // Operation: Dst / Src -> Dst void FDIV(); // [Floating Point] 0x056 — FMOD: Float modulus // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C // Operation: Dst % Src -> Dst void FMOD(); // [Floating Point] 0x057 — FDMOD: Float division and modulus // 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: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C // Operation: Dst -> Epsilon Register void FEPS(); // [Floating Point] 0x059 — FEEP: Float Enable/Disable Epsilon // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C // Operation: bool( Dst ) -> Epsilon Enable Bit void FEEP(); // [Boolean] 0x05A — FEQ: Float Equal // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C // Operation: Dst == Src into Dst void FEQ(); // [Boolean] 0x05B — FNE: Float Not Equal // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C // Operation: Dst != Src into Dst void FNE(); // [Boolean] 0x05C — FGT: Float Greater Than // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C // Operation: Dst > Src into Dst void FGT(); // [Boolean] 0x05D — FGE: Float Greater or Equal Than // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C // Operation: Dst >= Src into Dst void FGE(); // [Boolean] 0x05E — FLT: Float Lower Than // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C // Operation: Dst < Src into Dst void FLT(); // [Boolean] 0x05F — FLE: Float Lower or Equal Than // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C // Operation: Dst <= Src into Dst void FLE(); // [Casts] 0x060 — F2D: F32 (Float) to F64 (Double) // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00 // Operation: (cast) Dst -> Dst void F2D(); // [Casts] 0x061 — D2F: F64 (Double) to F32 (Float) // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00 // Operation: (cast) Dst -> Dst void D2F(); // [Casts] 0x062 — I2F: I32 (Integer) to F32 (Float) // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00 // Operation: (cast) Dst -> Dst void I2F(); // [Casts] 0x063 — I2D: I32 (Integer) to F64 (Double) // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00 // Operation: (cast) Dst -> Dst void I2D(); // [Casts] 0x064 — L2F: I64 (Long) to F32 (Float) // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00 // Operation: (cast) Dst -> Dst void L2F(); // [Casts] 0x065 — L2D: I64 (Long) to F64 (Double) // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00 // Operation: (cast) Dst -> Dst void L2D(); // [Casts] 0x066 — F2I: F32 (Float) to I32 (Integer) // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00 // Operation: (cast) Dst -> Dst void F2I(); // [Casts] 0x067 — F2L: F32 (Float) to I64 (Long) // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00 // Operation: (cast) Dst -> Dst void F2L(); // [Casts] 0x068 — D2I: F64 (Double) to I32 (Integer) // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00 // Operation: (cast) Dst -> Dst void D2I(); // [Casts] 0x069 — D2L: F64 (Double) to I64 (Long) // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 00 // Operation: (cast) Dst -> Dst void D2L(); // [Trigonometric] 0x06C — SIN: Sine Function // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C // Operation: sin( Dst ) -> Dst void SIN(); // [Trigonometric] 0x06D — COS: Cosine Function // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C // Operation: cos( Dst ) -> Dst void COS(); // [Trigonometric] 0x06E — TAN: Tangent Function // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C // Operation: tan( Dst ) -> Dst void TAN(); // [Trigonometric] 0x06F — ASIN: Arc Sine Function // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C // Operation: asin( Dst ) -> Dst void ASIN(); // [Trigonometric] 0x070 — ACOS: Arc Cosine Function // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C // Operation: acos( Dst ) -> Dst void ACOS(); // [Trigonometric] 0x071 — ATAN: Arc Tangent Function // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C // Operation: atan( Dst ) -> Dst void ATAN(); // [Trigonometric] 0x072 — ATAN2: Arc Tangent Function with 2 Arguments // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C // Operation: atan( Dst, Src ) -> Dst void ATAN2(); // [Exponential] 0x074 — EXP: Exponential Function // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C // Operation: exp( Dst ) -> Dst void EXP(); // [Exponential] 0x075 — LOG: Natural Logarithm // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C // Operation: ln( Dst ) -> Dst void LOG(); // [Exponential] 0x076 — LOGAB: Logarithm A of B // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C // Operation: log( Dst, Src ) -> Dst void LOGAB(); // [Exponential] 0x077 — POW: Power Function // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C // Operation: pow( Dst, Src ) -> Dst void POW(); // [Exponential] 0x078 — SQRT: Square Root // Params: 1 | AddrMask1: FF AddrMask2: 00 | TypeMask: 0C // Operation: sqrt( Dst ) -> Dst void SQRT(); // [Exponential] 0x079 — ROOT: General Root // Params: 2 | AddrMask1: 1E AddrMask2: FF | TypeMask: 0C // Operation: pow( Dst, 1 / Src ) -> Dst void ROOT(); // [Integer] 0x07C — ADC: Add with Carry // Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00 // Operation: Dst + Src + Flags.Carry -> Dst, Flags.Carry void ADC(); // [Integer] 0x07D — SWC: Subtract with Carry (Borrow) // Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00 // Operation: Dst - Src - Flags.Carry -> Dst, Flags.Carry void SWC(); // [Integer] 0x07E — MWO: Multiply with Overflow // Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00 // Operation: Signed Dst * Src -> Dst, Flags.Carry void MWO(); // [Integer] 0x07F — UMO: Unsigned Multiply with Overflow // Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00 // Operation: Unsigned Dst * Src -> Dst, Flags.Carry void UMO(); // [Matrix] 0x080 — MADD: Matrix Addition // Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00 // Operation: void MADD(); // [Matrix] 0x081 — MSUB: Matrix Subtraction // Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00 // Operation: void MSUB(); // [Matrix] 0x082 — MMUL: Matrix Multiply // Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00 // Operation: void MMUL(); // [Matrix] 0x083 — MINV: Matrix Inverse // Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00 // Operation: void MINV(); // [Matrix] 0x084 — MTRA: Matrix Transpose // Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00 // Operation: void MTRA(); // [Matrix] 0x085 — MDET: Matrix Determinant // Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00 // 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: void XADD(); // [SIMD] 0x08B — XSUB: SIMD Subtract // Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00 // Operation: void XSUB(); // [SIMD] 0x08C — XAMA: SIMD Alternate Multiply-Add // Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00 // Operation: void XAMA(); // [SIMD] 0x08D — XMUL: SIMD Multiply // Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00 // Operation: void XMUL(); // [SIMD] 0x08E — XDIV: SIMD Divide // Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00 // Operation: void XDIV(); // [Easter Eggs] 0x0F0 — UPY: Will place "YUPI" in memory // Params: 0 | AddrMask1: 00 AddrMask2: 00 | TypeMask: 00 // Operation: void UPY(); // // }; }