/** * @brief AUTO-GENERATED by pygen.ipynb BUT editable by hand! * */ #include #include // provides std::fmod, std::fma and cast support namespace spider { void CPU::SFB() { // TODO: Implement SFB } void CPU::LFB() { // TODO: Implement LFB } void CPU::JUF() { // TODO: Implement JUF } void CPU::JUR() { // TODO: Implement JUR } void CPU::PUSH() { // TODO: Implement PUSH } void CPU::POP() { // TODO: Implement POP } void CPU::ALLOC() { // TODO: Implement ALLOC } void CPU::HFREE() { // TODO: Implement HFREE } void CPU::CALL() { // TODO: Implement CALL } void CPU::RET() { // TODO: Implement RET } void CPU::EDI() { // TODO: Implement EDI } void CPU::SHSS() { // TODO: Implement SHSS } void CPU::FLI() { // TODO: Implement FLI } void CPU::FNEG() { // TODO: Implement FNEG } void CPU::FADD() { // TODO: Implement FADD } void CPU::FSUB() { // TODO: Implement FSUB } // ── 0x054 — FMUL: Float Multiplication ─────────────────────────────────── void CPU::FMUL() { fetchOperSrc(); fetchOperDst(); switch (_size) { case 0b10: _dst->_f32 *= _src->_f32; break; // f32 case 0b11: _dst->_f64 *= _src->_f64; break; // f64 default: break; // invalid size } (this->*_post)(); } // ── 0x055 — FDIV: Float Division ───────────────────────────────────────── void CPU::FDIV() { fetchOperSrc(); fetchOperDst(); switch (_size) { case 0b10: _dst->_f32 /= _src->_f32; break; case 0b11: _dst->_f64 /= _src->_f64; break; default: break; } (this->*_post)(); } // ── 0x056 — FMOD: Float Modulus ────────────────────────────────────────── // C++ has no % for floats — std::fmod performs the equivalent operation void CPU::FMOD() { fetchOperSrc(); fetchOperDst(); switch (_size) { case 0b10: _dst->_f32 = std::fmod(_dst->_f32, _src->_f32); break; case 0b11: _dst->_f64 = std::fmod(_dst->_f64, _src->_f64); break; default: break; } (this->*_post)(); } // ── 0x057 — FDMOD: Float Division and Modulus ──────────────────────────── // dst / src = RX (quotient) * src + RY (remainder) void CPU::FDMOD() { fetchOperSrc(); fetchOperDst(); switch (_size) { case 0b10: { f32 q = static_cast(static_cast(_dst->_f32 / _src->_f32)); f32 r = _dst->_f32 - (q * _src->_f32); RX._f32 = q; RY._f32 = r; break; } case 0b11: { f64 q = static_cast(static_cast(_dst->_f64 / _src->_f64)); f64 r = _dst->_f64 - (q * _src->_f64); RX._f64 = q; RY._f64 = r; break; } default: break; } (this->*_post)(); } // ── 0x058 — FEPS: Set Float Epsilon Value ──────────────────────────────── // Loads the epsilon value into RN (the epsilon register) void CPU::FEPS() { fetchOperDst(); switch (_size) { case 0b10: RN = _dst->_u32; break; // store f32 bits in RN case 0b11: RN = _dst->_u64; break; // store f64 bits in RN default: break; } (this->*_post)(); } // ── 0x059 — FEEP: Float Enable/Disable Epsilon ─────────────────────────── // Bit 12 of RF is the Epsilon Enable flag void CPU::FEEP() { fetchOperDst(); constexpr u64 EPSILON_ENABLE_BIT = (1ULL << 12); if (_dst->_u64) RF |= EPSILON_ENABLE_BIT; // non-zero → enable else RF &= ~EPSILON_ENABLE_BIT; // zero → disable (this->*_post)(); } // ── 0x05A — FEQ: Float Equal ────────────────────────────────────────────── // Sets bit 10 (Zero/Equal flag) in RF if dst == src void CPU::FEQ() { fetchOperSrc(); fetchOperDst(); constexpr u64 ZERO_FLAG = (1ULL << 10); bool equal = false; switch (_size) { case 0b10: equal = (_dst->_f32 == _src->_f32); break; case 0b11: equal = (_dst->_f64 == _src->_f64); break; default: break; } if (equal) RF |= ZERO_FLAG; else RF &= ~ZERO_FLAG; (this->*_post)(); } // ── 0x05B — FNE: Float Not Equal ───────────────────────────────────────── void CPU::FNE() { fetchOperSrc(); fetchOperDst(); constexpr u64 ZERO_FLAG = (1ULL << 10); bool notEqual = false; switch (_size) { case 0b10: notEqual = (_dst->_f32 != _src->_f32); break; case 0b11: notEqual = (_dst->_f64 != _src->_f64); break; default: break; } if (notEqual) RF |= ZERO_FLAG; else RF &= ~ZERO_FLAG; (this->*_post)(); } // ── 0x05C — FGT: Float Greater Than ────────────────────────────────────── // Sets/clears bit 9 (Negative flag) in RF void CPU::FGT() { fetchOperSrc(); fetchOperDst(); constexpr u64 NEGATIVE_FLAG = (1ULL << 9); bool gt = false; switch (_size) { case 0b10: gt = (_dst->_f32 > _src->_f32); break; case 0b11: gt = (_dst->_f64 > _src->_f64); break; default: break; } if (gt) RF &= ~NEGATIVE_FLAG; else RF |= NEGATIVE_FLAG; (this->*_post)(); } // ── 0x05D — FGE: Float Greater or Equal ────────────────────────────────── void CPU::FGE() { fetchOperSrc(); fetchOperDst(); constexpr u64 NEGATIVE_FLAG = (1ULL << 9); constexpr u64 ZERO_FLAG = (1ULL << 10); bool ge = false; bool eq = false; switch (_size) { case 0b10: ge = (_dst->_f32 >= _src->_f32); eq = (_dst->_f32 == _src->_f32); break; case 0b11: ge = (_dst->_f64 >= _src->_f64); eq = (_dst->_f64 == _src->_f64); break; default: break; } if (ge) RF &= ~NEGATIVE_FLAG; else RF |= NEGATIVE_FLAG; if (eq) RF |= ZERO_FLAG; else RF &= ~ZERO_FLAG; (this->*_post)(); } // ── 0x05E — FLT: Float Lower Than ──────────────────────────────────────── void CPU::FLT() { fetchOperSrc(); fetchOperDst(); constexpr u64 NEGATIVE_FLAG = (1ULL << 9); bool lt = false; switch (_size) { case 0b10: lt = (_dst->_f32 < _src->_f32); break; case 0b11: lt = (_dst->_f64 < _src->_f64); break; default: break; } if (lt) RF |= NEGATIVE_FLAG; else RF &= ~NEGATIVE_FLAG; (this->*_post)(); } // ── 0x05F — FLE: Float Lower or Equal ──────────────────────────────────── void CPU::FLE() { fetchOperSrc(); fetchOperDst(); constexpr u64 NEGATIVE_FLAG = (1ULL << 9); constexpr u64 ZERO_FLAG = (1ULL << 10); bool le = false; bool eq = false; switch (_size) { case 0b10: le = (_dst->_f32 <= _src->_f32); eq = (_dst->_f32 == _src->_f32); break; case 0b11: le = (_dst->_f64 <= _src->_f64); eq = (_dst->_f64 == _src->_f64); break; default: break; } if (le) RF &= ~NEGATIVE_FLAG; else RF |= NEGATIVE_FLAG; if (eq) RF |= ZERO_FLAG; else RF &= ~ZERO_FLAG; (this->*_post)(); } }