/** * @brief AUTO-GENERATED by pygen.ipynb BUT editable by hand! * */ #include namespace spider { void CPU::STB() { fetchOperSrc(); fetchOperDst(); switch(_size){ case 0b00: //byte _dst->_u8 |= (1 << _src->_u8); break; case 0b01: //short _dst->_u16 |= (1 << _src->_u16); break; case 0b10: //int _dst->_u32 |= (1 << _src->_u32); break; case 0b11: //long _dst->_u64 |= (1 << _src->_u64); break; } } void CPU::CRB() { fetchOperSrc(); fetchOperDst(); switch(_size){ case 0b00: //byte _dst->_u8 &= u8(~(u8(1) << _src->_u8)); break; case 0b01: //short _dst->_u16 &= u16(~(u16(1) << _src->_u16)); break; case 0b10: //int _dst->_u32 &= ~(u32(1) << _src->_u32); break; case 0b11: //long _dst->_u64 &= ~(u64(1) << _src->_u64); break; } } void CPU::TSB() { fetchOperSrc(); fetchOperDst(); u64 s, d; switch(_size) { case 0b00: // byte s = _src->_u8; d = _dst->_u8; break; case 0b01: // short s = _src->_u16; d = _dst->_u16; break; case 0b10: // int s = _src->_u32; d = _dst->_u32; break; case 0b11: // long s = _src->_u64; d = _dst->_u64; break; } d >>= s; d &= 1; } void CPU::BOOL() { fetchOperDst(); switch(_size){ case 0b00: // byte _dst->_u8 = _dst->_u8 != 0; break; case 0b01: // short _dst->_u16 = _dst->_u16 != 0; break; case 0b10: // int _dst->_u32 = _dst->_u32 != 0; break; case 0b11: // long _dst->_u64 = _dst->_u64 != 0; break; } } // ── 0x024 — NOT: Tests Dst == 0, updates Equal Flag ── void CPU::NOT() { fetchOperDst(); bool isZero = false; switch(_size) { case 0b00: isZero = (_dst->_u8 == 0); break; case 0b01: isZero = (_dst->_u16 == 0); break; case 0b10: isZero = (_dst->_u32 == 0); break; case 0b11: isZero = (_dst->_u64 == 0); break; } if (isZero) { RF |= CPU::FLAG_EQUAL; // Si es 0, el resultado de !0 es true (1), actualizamos bandera // Dependiendo de la implementación de BOOL, podrías querer guardar el resultado en Dst _dst->_u64 = 1; } else { RF &= ~CPU::FLAG_EQUAL; _dst->_u64 = 0; } } // ── 0x025 — AND void CPU::AND() { fetchOperSrc(); fetchOperDst(); switch(_size) { case 0b00: _dst->_u8 &= _src->_u8; break; case 0b01: _dst->_u16 &= _src->_u16; break; case 0b10: _dst->_u32 &= _src->_u32; break; case 0b11: _dst->_u64 &= _src->_u64; break; } } // ── 0x026 — OR void CPU::OR() { fetchOperSrc(); fetchOperDst(); switch(_size) { case 0b00: _dst->_u8 |= _src->_u8; break; case 0b01: _dst->_u16 |= _src->_u16; break; case 0b10: _dst->_u32 |= _src->_u32; break; case 0b11: _dst->_u64 |= _src->_u64; break; } } // ── 0x027 — XOR void CPU::XOR() { fetchOperSrc(); fetchOperDst(); switch(_size) { case 0b00: _dst->_u8 ^= _src->_u8; break; case 0b01: _dst->_u16 ^= _src->_u16; break; case 0b10: _dst->_u32 ^= _src->_u32; break; case 0b11: _dst->_u64 ^= _src->_u64; break; } } // ── 0x028 — SHL void CPU::SHL() { fetchOperSrc(); fetchOperDst(); switch(_size) { case 0b00: _dst->_u8 <<= _src->_u8; break; case 0b01: _dst->_u16 <<= _src->_u16; break; case 0b10: _dst->_u32 <<= _src->_u32; break; case 0b11: _dst->_u64 <<= _src->_u64; break; } } // ── 0x029 — SHR void CPU::SHR() { fetchOperSrc(); fetchOperDst(); switch(_size) { case 0b00: _dst->_u8 >>= _src->_u8; break; case 0b01: _dst->_u16 >>= _src->_u16; break; case 0b10: _dst->_u32 >>= _src->_u32; break; case 0b11: _dst->_u64 >>= _src->_u64; break; } } // ── 0x02A — SSR void CPU::SSR() { fetchOperSrc(); fetchOperDst(); switch(_size) { case 0b00: _dst->_i8 >>= _src->_u8; break; case 0b01: _dst->_i16 >>= _src->_u8; break; case 0b10: _dst->_i32 >>= _src->_u8; break; case 0b11: _dst->_i64 >>= _src->_u8; break; } } // ── 0x02B — ROL: Rotate Left ── void CPU::ROL() { fetchOperSrc(); fetchOperDst(); switch(_size) { case 0b00: _dst->_u8 = (_dst->_u8 << _src->_u8) | (_dst->_u8 >> (8 - _src->_u8)); break; case 0b01: _dst->_u16 = (_dst->_u16 << _src->_u8) | (_dst->_u16 >> (16 - _src->_u8)); break; case 0b10: _dst->_u32 = (_dst->_u32 << _src->_u8) | (_dst->_u32 >> (32 - _src->_u8)); break; case 0b11: _dst->_u64 = (_dst->_u64 << _src->_u8) | (_dst->_u64 >> (64 - _src->_u8)); break; } } // ── 0x02C — ROR: Rotate Right ── void CPU::ROR() { fetchOperSrc(); fetchOperDst(); switch(_size) { case 0b00: _dst->_u8 = (_dst->_u8 >> _src->_u8) | (_dst->_u8 << (8 - _src->_u8)); break; case 0b01: _dst->_u16 = (_dst->_u16 >> _src->_u8) | (_dst->_u16 << (16 - _src->_u8)); break; case 0b10: _dst->_u32 = (_dst->_u32 >> _src->_u8) | (_dst->_u32 << (32 - _src->_u8)); break; case 0b11: _dst->_u64 = (_dst->_u64 >> _src->_u8) | (_dst->_u64 << (64 - _src->_u8)); break; } } // ── 0x02D — CNT: Counts bits (# of 1's into Dst) ── void CPU::CNT() { fetchOperDst(); switch(_size) { // C++20 cross compatible version!! case 0b00: _dst->_u8 = u8( std::popcount(_dst->_u8) ); break; case 0b01: _dst->_u16 = u16(std::popcount(_dst->_u16)); break; case 0b10: _dst->_u32 = u32(std::popcount(_dst->_u32)); break; case 0b11: _dst->_u64 = u64(std::popcount(_dst->_u64)); break; } } void CPU::EQ() { fetchOperSrc(); fetchOperDst(); bool res = false; switch(_size) { case 0b00: res = (_dst->_u8 == _src->_u8); break; case 0b01: res = (_dst->_u16 == _src->_u16); break; case 0b10: res = (_dst->_u32 == _src->_u32); break; case 0b11: res = (_dst->_u64 == _src->_u64); break; } _dst->_u64 = res ? 1 : 0; } void CPU::NE() { fetchOperSrc(); fetchOperDst(); bool res = false; switch(_size) { case 0b00: res = (_dst->_u8 != _src->_u8); break; case 0b01: res = (_dst->_u16 != _src->_u16); break; case 0b10: res = (_dst->_u32 != _src->_u32); break; case 0b11: res = (_dst->_u64 != _src->_u64); break; } _dst->_u64 = res ? 1 : 0; } void CPU::GT() { fetchOperSrc(); fetchOperDst(); bool res = false; switch(_size) { case 0b00: res = (_dst->_i8 > _src->_i8); break; case 0b01: res = (_dst->_i16 > _src->_i16); break; case 0b10: res = (_dst->_i32 > _src->_i32); break; case 0b11: res = (_dst->_i64 > _src->_i64); break; } _dst->_u64 = res ? 1 : 0; } void CPU::GE() { fetchOperSrc(); fetchOperDst(); bool res = false; switch(_size) { case 0b00: res = (_dst->_i8 >= _src->_i8); break; case 0b01: res = (_dst->_i16 >= _src->_i16); break; case 0b10: res = (_dst->_i32 >= _src->_i32); break; case 0b11: res = (_dst->_i64 >= _src->_i64); break; } _dst->_u64 = res ? 1 : 0; } void CPU::LT() { fetchOperSrc(); fetchOperDst(); bool res = false; switch(_size) { case 0b00: res = (_dst->_i8 < _src->_i8); break; case 0b01: res = (_dst->_i16 < _src->_i16); break; case 0b10: res = (_dst->_i32 < _src->_i32); break; case 0b11: res = (_dst->_i64 < _src->_i64); break; } _dst->_u64 = res ? 1 : 0; } void CPU::LE() { fetchOperSrc(); fetchOperDst(); bool res = false; switch(_size) { case 0b00: res = (_dst->_i8 <= _src->_i8); break; case 0b01: res = (_dst->_i16 <= _src->_i16); break; case 0b10: res = (_dst->_i32 <= _src->_i32); break; case 0b11: res = (_dst->_i64 <= _src->_i64); break; } _dst->_u64 = res ? 1 : 0; } void CPU::GTU() { fetchOperSrc(); fetchOperDst(); bool res = false; switch(_size) { case 0b00: res = (_dst->_u8 > _src->_u8); break; case 0b01: res = (_dst->_u16 > _src->_u16); break; case 0b10: res = (_dst->_u32 > _src->_u32); break; case 0b11: res = (_dst->_u64 > _src->_u64); break; } _dst->_u64 = res ? 1 : 0; } void CPU::GEU() { fetchOperSrc(); fetchOperDst(); bool res = false; switch(_size) { case 0b00: res = (_dst->_u8 >= _src->_u8); break; case 0b01: res = (_dst->_u16 >= _src->_u16); break; case 0b10: res = (_dst->_u32 >= _src->_u32); break; case 0b11: res = (_dst->_u64 >= _src->_u64); break; } _dst->_u64 = res ? 1 : 0; } void CPU::LTU() { fetchOperSrc(); fetchOperDst(); bool res = false; switch(_size) { case 0b00: res = (_dst->_u8 < _src->_u8); break; case 0b01: res = (_dst->_u16 < _src->_u16); break; case 0b10: res = (_dst->_u32 < _src->_u32); break; case 0b11: res = (_dst->_u64 < _src->_u64); break; } _dst->_u64 = res ? 1 : 0; } void CPU::LEU() { fetchOperSrc(); fetchOperDst(); bool res = false; switch(_size) { case 0b00: res = (_dst->_u8 <= _src->_u8); break; case 0b01: res = (_dst->_u16 <= _src->_u16); break; case 0b10: res = (_dst->_u32 <= _src->_u32); break; case 0b11: res = (_dst->_u64 <= _src->_u64); break; } _dst->_u64 = res ? 1 : 0; } // ── 0x038 — JMP: Dst -> Instruction Register (PC) ── // The IR adds 1 at the end, so we subtract 1 to compensate. void CPU::JMP() { fetchOperDst(); u64 target; switch(_size) { case 0b00: target = static_cast(_dst->_u8); break; case 0b01: target = static_cast(_dst->_u16); break; case 0b10: target = static_cast(_dst->_u32); break; case 0b11: target = _dst->_u64; break; } RI = target - 1; } // ── 0x039 — JEQ: Jump if EQ flag is set ── void CPU::JEQ() { fetchOperDst(); if (RF & CPU::FLAG_EQUAL) { u64 target; switch(_size) { case 0b00: target = static_cast(_dst->_u8); break; case 0b01: target = static_cast(_dst->_u16); break; case 0b10: target = static_cast(_dst->_u32); break; case 0b11: target = _dst->_u64; break; } RI = target - 1; } } // ── 0x03A — JNE: Jumps if EQ flag is cleared ── void CPU::JNE() { fetchOperDst(); if (!(RF & CPU::FLAG_EQUAL)) { u64 target; switch(_size) { case 0b00: target = static_cast(_dst->_u8); break; case 0b01: target = static_cast(_dst->_u16); break; case 0b10: target = static_cast(_dst->_u32); break; case 0b11: target = _dst->_u64; break; } RI = target - 1; } } // ── 0x03B — JIF: Jumps if Src is booleanly true ── void CPU::JIF() { fetchOperSrc(); fetchOperDst(); if (_src->_u64 != 0) { u64 target; switch(_size) { case 0b00: target = static_cast(_dst->_u8); break; case 0b01: target = static_cast(_dst->_u16); break; case 0b10: target = static_cast(_dst->_u32); break; case 0b11: target = _dst->_u64; break; } RI = target - 1; } } // ── 0x03C — JMR: Dst + Instruction Register -> Instruction Register ── void CPU::JMR() { fetchOperDst(); i64 offset; switch (_size) { case 0b00: offset = static_cast(_dst->_i8); break; // 1 byte case 0b01: offset = static_cast(_dst->_i16); break; // 2 bytes case 0b10: offset = static_cast(_dst->_i32); break; // 4 bytes case 0b11: offset = _dst->_i64; break; // 8 bytes } RI = static_cast(static_cast(RI) + offset); } // ── 0x03D — JER: Dst + Instruction Register -> Instruction Register IF Flags.EQ ── void CPU::JER() { fetchOperDst(); if (RF & CPU::FLAG_EQUAL) { i64 offset; switch (_size) { case 0b00: offset = static_cast(_dst->_i8); break; case 0b01: offset = static_cast(_dst->_i16); break; case 0b10: offset = static_cast(_dst->_i32); break; case 0b11: offset = _dst->_i64; break; } RI = static_cast(static_cast(RI) + offset); } } // ── 0x03E — JNR: Dst + Instruction Register -> Instruction Register IF NOT Flags.EQ ── void CPU::JNR() { fetchOperDst(); if (!(RF & CPU::FLAG_EQUAL)) { i64 offset; switch (_size) { case 0b00: offset = static_cast(_dst->_i8); break; case 0b01: offset = static_cast(_dst->_i16); break; case 0b10: offset = static_cast(_dst->_i32); break; case 0b11: offset = _dst->_i64; break; } RI = static_cast(static_cast(RI) + offset); } } // ── 0x03F — JIR: Dst + Instruction Register -> Instruction Register IF Src ── void CPU::JIR() { fetchOperSrc(); fetchOperDst(); if (_src->_u64 != 0) { i64 offset; switch (_size) { case 0b00: offset = static_cast(_dst->_i8); break; case 0b01: offset = static_cast(_dst->_i16); break; case 0b10: offset = static_cast(_dst->_i32); break; case 0b11: offset = _dst->_i64; break; } RI = static_cast(static_cast(RI) + offset); } } }