more or less almost done with the instr reels.
This commit is contained in:
12
makefile
12
makefile
@@ -14,8 +14,16 @@ OBJEXT := o
|
|||||||
|
|
||||||
#Flags, Libraries and Includes
|
#Flags, Libraries and Includes
|
||||||
ROOT := ./
|
ROOT := ./
|
||||||
CFLAGS := -Wall -std=c++20 -DSPIDER_COMPILING
|
CFLAGS := -std=c++20 -O2 \
|
||||||
LFLAGS := -Wall -std=c++20 -static
|
-Wall -Wextra \
|
||||||
|
-Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align \
|
||||||
|
-Wunused -Woverloaded-virtual -Wconversion \
|
||||||
|
-Wsign-conversion -Wnull-dereference -Wdouble-promotion \
|
||||||
|
-Wformat=2 -Wimplicit-fallthrough -Wsuggest-override \
|
||||||
|
-Wextra-semi -Wduplicated-cond -Wduplicated-branches \
|
||||||
|
-Wlogical-op -Wuseless-cast
|
||||||
|
LFLAGS := -std=c++20 -static-libstdc++ -static-libgcc \
|
||||||
|
-Wl,--fatal-warnings -Wl,--warn-common
|
||||||
LIB :=
|
LIB :=
|
||||||
INC := -I./src/
|
INC := -I./src/
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ namespace spider {
|
|||||||
R6{}, R7{}, R8{}, R9{},
|
R6{}, R7{}, R8{}, R9{},
|
||||||
RF{}, RI{}, RS{}, RZ{},
|
RF{}, RI{}, RS{}, RZ{},
|
||||||
RE{}, RN{}, RV{}, RM{},
|
RE{}, RN{}, RV{}, RM{},
|
||||||
ALU0{}, ALU1{},
|
ALU0{},
|
||||||
|
_dst(nullptr), _src(nullptr),
|
||||||
_ram(nullptr), _reel(nullptr) {
|
_ram(nullptr), _reel(nullptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,8 +66,6 @@ namespace spider {
|
|||||||
* Immediate Addressing Mode
|
* Immediate Addressing Mode
|
||||||
*/
|
*/
|
||||||
void CPU::imm() {
|
void CPU::imm() {
|
||||||
u8 size = 2 << _size;
|
|
||||||
_next = &ALU0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -80,7 +79,7 @@ namespace spider {
|
|||||||
* Register Addressing Mode
|
* Register Addressing Mode
|
||||||
*/
|
*/
|
||||||
void CPU::reg() {
|
void CPU::reg() {
|
||||||
sizeof(CPU);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -42,7 +42,16 @@ namespace spider {
|
|||||||
* This way we don't "write" into constant values, rather
|
* This way we don't "write" into constant values, rather
|
||||||
* we write into a writeable var which is "hidden"
|
* we write into a writeable var which is "hidden"
|
||||||
*/
|
*/
|
||||||
register_t ALU0, ALU1;
|
register_t ALU0;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
register_t* _dst;
|
||||||
|
register_t* _src;
|
||||||
|
};
|
||||||
|
register_t* _opers[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@@ -67,10 +76,6 @@ namespace spider {
|
|||||||
*/
|
*/
|
||||||
InstrReel* _reel;
|
InstrReel* _reel;
|
||||||
|
|
||||||
register_t* _next;
|
|
||||||
u8 _addrm : 6;
|
|
||||||
u8 _size : 2;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CPU();
|
CPU();
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ namespace spider {
|
|||||||
&cpu.R6, &cpu.R7, &cpu.R8, &cpu.R9,
|
&cpu.R6, &cpu.R7, &cpu.R8, &cpu.R9,
|
||||||
//&cpu.RF, &cpu.RI, &cpu.RS, &cpu.RZ,
|
//&cpu.RF, &cpu.RI, &cpu.RS, &cpu.RZ,
|
||||||
//&cpu.RE, &cpu.RN, &cpu.RV, &cpu.RM,
|
//&cpu.RE, &cpu.RN, &cpu.RV, &cpu.RM,
|
||||||
&cpu.ALU0, &cpu.ALU1
|
&cpu.ALU0, &cpu.ALU0
|
||||||
};
|
};
|
||||||
const u64* sys_regs[] = {
|
const u64* sys_regs[] = {
|
||||||
&cpu.RF, &cpu.RI, &cpu.RS, &cpu.RZ,
|
&cpu.RF, &cpu.RI, &cpu.RS, &cpu.RZ,
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <spider/runtime/common.hpp>
|
#include <spider/runtime/common.hpp>
|
||||||
|
|
||||||
|
#include <spider/runtime/cpu/Register.hpp>
|
||||||
|
|
||||||
#include <spider/runtime/native/machine.hpp>
|
#include <spider/runtime/native/machine.hpp>
|
||||||
|
|
||||||
#if __cplusplus >= 202002L
|
#if __cplusplus >= 202002L
|
||||||
|
|||||||
@@ -8,58 +8,10 @@ namespace spider {
|
|||||||
|
|
||||||
// Public Interface //
|
// Public Interface //
|
||||||
|
|
||||||
InstrReel::InstrReel() : _mem(nullptr), _size(0), _offset(0), _total_size(0) {}
|
InstrReel::InstrReel() {}
|
||||||
|
|
||||||
InstrReel::~InstrReel() {}
|
InstrReel::~InstrReel() {}
|
||||||
|
|
||||||
// Instruction abstraction //
|
|
||||||
|
|
||||||
u8 InstrReel::atU8(u64 ip) {
|
|
||||||
// guard against access
|
|
||||||
u64 ip_p = ip - _offset;
|
|
||||||
if(ip_p + 1 > _size) return 0;
|
|
||||||
|
|
||||||
// send byte
|
|
||||||
return _mem[ip];
|
|
||||||
}
|
|
||||||
|
|
||||||
u16 InstrReel::atU16(u64 ip) {
|
|
||||||
// guard against access
|
|
||||||
u64 ip_p = ip - _offset;
|
|
||||||
if(ip_p + 2 > _size) return 0;
|
|
||||||
|
|
||||||
// build a 16-bit big endian number
|
|
||||||
u16 dat;
|
|
||||||
spider::loadLE(&dat, _mem + ip_p);
|
|
||||||
return dat;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 InstrReel::atU32(u64 ip) {
|
|
||||||
// guard against access
|
|
||||||
u64 ip_p = ip - _offset;
|
|
||||||
if(ip_p + 4 > _size) return 0;
|
|
||||||
|
|
||||||
// build a 32-bit big endian number
|
|
||||||
u32 dat;
|
|
||||||
spider::loadLE(&dat, _mem + ip_p);
|
|
||||||
return dat;
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 InstrReel::atU64(u64 ip) {
|
|
||||||
// guard against access
|
|
||||||
u64 ip_p = ip - _offset;
|
|
||||||
if(ip_p + 8 > _size) return 0;
|
|
||||||
|
|
||||||
// build a 64-bit big endian number
|
|
||||||
u64 dat;
|
|
||||||
spider::loadLE(&dat, _mem + ip_p);
|
|
||||||
return dat;
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 InstrReel::size() {
|
|
||||||
return _total_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Static Utils //
|
// Static Utils //
|
||||||
|
|
||||||
u16 InstrReel::unpackInstr(u16 bcode) {
|
u16 InstrReel::unpackInstr(u16 bcode) {
|
||||||
|
|||||||
@@ -9,13 +9,6 @@ namespace spider {
|
|||||||
* Implements an instruction reel.
|
* Implements an instruction reel.
|
||||||
*/
|
*/
|
||||||
class InstrReel {
|
class InstrReel {
|
||||||
protected: // Current accessing range //
|
|
||||||
|
|
||||||
u8* _mem;
|
|
||||||
isize _size;
|
|
||||||
isize _offset;
|
|
||||||
isize _total_size;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
InstrReel();
|
InstrReel();
|
||||||
@@ -30,7 +23,7 @@ namespace spider {
|
|||||||
* Reindexing may occur, continous access
|
* Reindexing may occur, continous access
|
||||||
* may incurr in less penalties.
|
* may incurr in less penalties.
|
||||||
*/
|
*/
|
||||||
virtual u8 atU8(u64 ip);
|
virtual u8 readU8(u64 ip) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains a byte of data at
|
* Obtains a byte of data at
|
||||||
@@ -38,7 +31,7 @@ namespace spider {
|
|||||||
* Reindexing may occur, continous access
|
* Reindexing may occur, continous access
|
||||||
* may incurr in less penalties.
|
* may incurr in less penalties.
|
||||||
*/
|
*/
|
||||||
virtual u16 atU16(u64 ip);
|
virtual u16 readU16(u64 ip) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains a byte of data at
|
* Obtains a byte of data at
|
||||||
@@ -46,7 +39,7 @@ namespace spider {
|
|||||||
* Reindexing may occur, continous access
|
* Reindexing may occur, continous access
|
||||||
* may incurr in less penalties.
|
* may incurr in less penalties.
|
||||||
*/
|
*/
|
||||||
virtual u32 atU32(u64 ip);
|
virtual u32 readU32(u64 ip) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains a byte of data at
|
* Obtains a byte of data at
|
||||||
@@ -54,12 +47,18 @@ namespace spider {
|
|||||||
* Reindexing may occur, continous access
|
* Reindexing may occur, continous access
|
||||||
* may incurr in less penalties.
|
* may incurr in less penalties.
|
||||||
*/
|
*/
|
||||||
virtual u64 atU64(u64 ip);
|
virtual u64 readU64(u64 ip) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a range of data, and
|
||||||
|
* outputs it.
|
||||||
|
*/
|
||||||
|
virtual void readRange(u64 ip, u8* out, u64 length) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current size of the instructions.
|
* Current size of the instructions.
|
||||||
*/
|
*/
|
||||||
virtual u64 size();
|
virtual u64 size() = 0;
|
||||||
|
|
||||||
public: // Static Utils //
|
public: // Static Utils //
|
||||||
|
|
||||||
|
|||||||
@@ -4,20 +4,19 @@
|
|||||||
|
|
||||||
namespace spider {
|
namespace spider {
|
||||||
|
|
||||||
InstrReelDyn::InstrReelDyn(u64 length) : _use_count(0), _block_index(0) {
|
InstrReelDyn::InstrReelDyn(u64 length) : _size(length) {
|
||||||
_total_size = length;
|
// Safe int ceil division
|
||||||
growToFit(length > 0 ? length - 1 : 0);
|
growTo((length >> 8) + ((length & 255) != 0));
|
||||||
selectBlock(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InstrReelDyn::InstrReelDyn(const u8* data, u64 length) {}
|
InstrReelDyn::InstrReelDyn(const u8* data, u64 length) {}
|
||||||
|
|
||||||
InstrReelDyn::InstrReelDyn(const InstrReelDyn& copy) : _use_count(copy._use_count), _block_index(copy._block_index), _blocks(copy._blocks) {
|
InstrReelDyn::InstrReelDyn(const InstrReelDyn& copy)
|
||||||
if (_block_index < _blocks.size()) selectBlock(_block_index);
|
: _blocks(copy._blocks), _size(copy._size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
InstrReelDyn::InstrReelDyn(InstrReelDyn&& move) noexcept : _use_count(move._use_count), _block_index(move._block_index), _blocks(std::move(move._blocks)) {
|
InstrReelDyn::InstrReelDyn(InstrReelDyn&& move) noexcept
|
||||||
if (_block_index < _blocks.size()) selectBlock(_block_index);
|
: _blocks(std::move(move._blocks)), _size(std::move(move._size)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
InstrReelDyn::~InstrReelDyn() {
|
InstrReelDyn::~InstrReelDyn() {
|
||||||
@@ -25,170 +24,183 @@ namespace spider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
InstrReelDyn& InstrReelDyn::operator=(const InstrReelDyn& copy) {
|
InstrReelDyn& InstrReelDyn::operator=(const InstrReelDyn& copy) {
|
||||||
_use_count = copy._use_count;
|
|
||||||
_block_index = copy._block_index;
|
|
||||||
_blocks = copy._blocks;
|
_blocks = copy._blocks;
|
||||||
if (_block_index < _blocks.size()) selectBlock(_block_index);
|
_size = copy._size;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
InstrReelDyn& InstrReelDyn::operator=(InstrReelDyn&& move) noexcept {
|
InstrReelDyn& InstrReelDyn::operator=(InstrReelDyn&& move) noexcept {
|
||||||
_use_count = move._use_count;
|
|
||||||
_block_index = move._block_index;
|
|
||||||
_blocks = std::move(move._blocks);
|
_blocks = std::move(move._blocks);
|
||||||
if (_block_index < _blocks.size()) selectBlock(_block_index);
|
_size = std::move(move._size);
|
||||||
|
|
||||||
move._use_count = 0;
|
|
||||||
move._block_index = 0;
|
|
||||||
move._mem = nullptr;
|
|
||||||
move._offset = 0;
|
|
||||||
move._size = 0;
|
|
||||||
move._total_size = 0;
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstrReelDyn::growToFit(isize index) {
|
void InstrReelDyn::growTo(u64 ip) {
|
||||||
while (_blocks.size() < (index + 1)) {
|
u64 b_index = (ip >> 8) + 1;
|
||||||
|
while (_blocks.size() < b_index) {
|
||||||
_blocks.emplace_back();
|
_blocks.emplace_back();
|
||||||
}
|
}
|
||||||
|
if (ip >= _size) _size = ip + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
isize InstrReelDyn::selectIndex(u64 ip) {
|
std::pair<u64, u8> InstrReelDyn::indexOf(u64 ip) {
|
||||||
return ip / 256;
|
return { ip >> 8, ip & 0xFF }; // { ip / 256, ip % 256 };
|
||||||
}
|
}
|
||||||
|
|
||||||
InstrReelDyn::ReelBlock* InstrReelDyn::selectBlock(isize index) {
|
bool InstrReelDyn::continous(u64 ip0, u64 ip1, u64* b_index, u16* s_index) {
|
||||||
// Update base class cache
|
auto i = indexOf(ip0);
|
||||||
auto ptr = &_blocks[index];
|
*b_index = i.first;
|
||||||
_offset = index * 256;
|
*s_index = i.second;
|
||||||
_mem = ptr->data;
|
return i.first == (ip1 >> 8);
|
||||||
_size = 256;
|
|
||||||
_block_index = index;
|
|
||||||
|
|
||||||
//_blocks[block_idx].access_count++;
|
|
||||||
return ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 InstrReelDyn::atU8(u64 ip) {
|
// Particular Cases
|
||||||
isize j = selectIndex(ip);
|
|
||||||
if (j >= _blocks.size()) return 0;
|
|
||||||
if (j != _block_index) {
|
|
||||||
this->selectBlock(j);
|
|
||||||
}
|
|
||||||
return _mem[ip - _offset];
|
|
||||||
}
|
|
||||||
|
|
||||||
u16 InstrReelDyn::atU16(u64 ip) {
|
|
||||||
isize j0 = selectIndex(ip);
|
|
||||||
isize j1 = selectIndex(ip + 1);
|
|
||||||
if (j1 >= _blocks.size()) return 0;
|
|
||||||
if (j0 == j1 && j0 != _block_index) {
|
|
||||||
selectBlock(j0);
|
|
||||||
}
|
|
||||||
if (j0 == j1 && j0 == _block_index) {
|
|
||||||
u16 dat;
|
|
||||||
spider::loadLE(&dat, _mem);
|
|
||||||
return dat;
|
|
||||||
}
|
|
||||||
|
|
||||||
// general case, first part
|
|
||||||
u16 dat = 0;
|
|
||||||
const u8 size = sizeof(u16);
|
|
||||||
|
|
||||||
// select first block and offset
|
|
||||||
selectBlock(j0);
|
|
||||||
u8 rem = ip % 256;
|
|
||||||
|
|
||||||
for (u8 n = 0; n < size; n++) {
|
|
||||||
dat |= _mem[rem++] << (n * 8);
|
|
||||||
ip++;
|
|
||||||
if (!rem) selectBlock(++j0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dat;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 InstrReelDyn::atU32(u64 ip) {
|
|
||||||
isize j0 = selectIndex(ip);
|
|
||||||
isize j1 = selectIndex(ip + 3);
|
|
||||||
if (j1 >= _blocks.size()) return 0;
|
|
||||||
if (j0 == j1 && j0 != _block_index) {
|
|
||||||
selectBlock(j0);
|
|
||||||
}
|
|
||||||
if (j0 == j1 && j0 == _block_index) {
|
|
||||||
u32 dat;
|
|
||||||
spider::loadLE(&dat, _mem);
|
|
||||||
return dat;
|
|
||||||
}
|
|
||||||
|
|
||||||
// general case, first part
|
|
||||||
u32 dat = 0;
|
|
||||||
const u8 size = sizeof(u32);
|
|
||||||
|
|
||||||
// select first block and offset
|
|
||||||
selectBlock(j0);
|
|
||||||
u8 rem = ip % 256;
|
|
||||||
|
|
||||||
for (u8 n = 0; n < size; n++) {
|
|
||||||
dat |= _mem[rem++] << (n * 8);
|
|
||||||
ip++;
|
|
||||||
if (!rem) selectBlock(++j0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dat;
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 InstrReelDyn::atU64(u64 ip) {
|
|
||||||
isize j0 = selectIndex(ip);
|
|
||||||
isize j1 = selectIndex(ip + 3);
|
|
||||||
if (j1 >= _blocks.size()) return 0;
|
|
||||||
if (j0 == j1 && j0 != _block_index) {
|
|
||||||
selectBlock(j0);
|
|
||||||
}
|
|
||||||
if (j0 == j1 && j0 == _block_index) {
|
|
||||||
u64 dat;
|
|
||||||
spider::loadLE(&dat, _mem);
|
|
||||||
return dat;
|
|
||||||
}
|
|
||||||
|
|
||||||
// general case, first part
|
|
||||||
u64 dat = 0;
|
|
||||||
const u8 size = sizeof(u64);
|
|
||||||
|
|
||||||
// select first block and offset
|
|
||||||
selectBlock(j0);
|
|
||||||
u8 rem = ip % 256;
|
|
||||||
|
|
||||||
for (u8 n = 0; n < size; n++) {
|
|
||||||
dat |= _mem[rem++] << (n * 8);
|
|
||||||
ip++;
|
|
||||||
if (!rem) selectBlock(++j0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dat;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InstrReelDyn::at(u64 ip, u8 dat) {}
|
|
||||||
|
|
||||||
void InstrReelDyn::at(u64 ip, u16 dat) {}
|
|
||||||
|
|
||||||
void InstrReelDyn::at(u64 ip, u32 dat) {}
|
|
||||||
|
|
||||||
void InstrReelDyn::at(u64 ip, u64 dat) {}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Appends instruction at location.
|
* Obtains a byte of data at
|
||||||
|
* the specific location.
|
||||||
|
* Reindexing may occur, continous access
|
||||||
|
* may incurr in less penalties.
|
||||||
*/
|
*/
|
||||||
void InstrReelDyn::append(u64 ip, u16 bc) {}
|
u8 InstrReelDyn::readU8(u64 ip) {
|
||||||
|
if (ip + 1 > _size) return 0;
|
||||||
|
auto i = indexOf(ip);
|
||||||
|
return _blocks[i.first].data[i.second];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains a byte of data at
|
||||||
|
* the specific location.
|
||||||
|
* Reindexing may occur, continous access
|
||||||
|
* may incurr in less penalties.
|
||||||
|
*/
|
||||||
|
u16 InstrReelDyn::readU16(u64 ip) {
|
||||||
|
if (ip + 2 > _size) return 0;
|
||||||
|
|
||||||
|
u16 dat;
|
||||||
|
u64 b_index;
|
||||||
|
u16 s_index;
|
||||||
|
|
||||||
|
if (continous(ip, ip + 1, &b_index, &s_index)) {
|
||||||
|
spider::loadLE(&dat, &_blocks[b_index].data[s_index]);
|
||||||
|
return dat;
|
||||||
|
}
|
||||||
|
|
||||||
|
dat = 0;
|
||||||
|
for (isize i = 0; i < sizeof(dat); i++) {
|
||||||
|
auto& b = _blocks[(b_index + s_index) >> 8];
|
||||||
|
dat |= u16(b.data[s_index++ & 0xFF]) << (i * 8);
|
||||||
|
}
|
||||||
|
return dat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains a byte of data at
|
||||||
|
* the specific location.
|
||||||
|
* Reindexing may occur, continous access
|
||||||
|
* may incurr in less penalties.
|
||||||
|
*/
|
||||||
|
u32 InstrReelDyn::readU32(u64 ip) {
|
||||||
|
if (ip + 4 > _size) return 0;
|
||||||
|
|
||||||
|
u32 dat;
|
||||||
|
u64 b_index;
|
||||||
|
u16 s_index;
|
||||||
|
|
||||||
|
if (continous(ip, ip + 3, &b_index, &s_index)) {
|
||||||
|
spider::loadLE(&dat, &_blocks[b_index].data[s_index]);
|
||||||
|
return dat;
|
||||||
|
}
|
||||||
|
|
||||||
|
dat = 0;
|
||||||
|
for (isize i = 0; i < sizeof(dat); i++) {
|
||||||
|
auto& b = _blocks[(b_index + s_index) >> 8];
|
||||||
|
dat |= u32(b.data[s_index++ & 0xFF]) << (i * 8);
|
||||||
|
}
|
||||||
|
return dat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains a byte of data at
|
||||||
|
* the specific location.
|
||||||
|
* Reindexing may occur, continous access
|
||||||
|
* may incurr in less penalties.
|
||||||
|
*/
|
||||||
|
u64 InstrReelDyn::readU64(u64 ip) {
|
||||||
|
if (ip + 8 > _size) return 0;
|
||||||
|
|
||||||
|
u64 dat;
|
||||||
|
u64 b_index;
|
||||||
|
u16 s_index;
|
||||||
|
|
||||||
|
if (continous(ip, ip + 7, &b_index, &s_index)) {
|
||||||
|
spider::loadLE(&dat, &_blocks[b_index].data[s_index]);
|
||||||
|
return dat;
|
||||||
|
}
|
||||||
|
|
||||||
|
dat = 0;
|
||||||
|
for (isize i = 0; i < sizeof(dat); i++) {
|
||||||
|
auto& b = _blocks[(b_index + s_index) >> 8];
|
||||||
|
dat |= u64(b.data[s_index++ & 0xFF]) << (i * 8);
|
||||||
|
}
|
||||||
|
return dat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a range of data, and
|
||||||
|
* outputs it.
|
||||||
|
*/
|
||||||
|
void InstrReelDyn::readRange(u64 ip, u8* out, u64 length) {
|
||||||
|
if (ip + length > _size) {
|
||||||
|
std::memset(out, 0, length);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 b_index;
|
||||||
|
u16 s_index;
|
||||||
|
|
||||||
|
if (continous(ip, ip + length, &b_index, &s_index)) {
|
||||||
|
std::memcpy(out, &_blocks[b_index].data[s_index], length);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 bytes_read = 0;
|
||||||
|
while (bytes_read < length) {
|
||||||
|
u64 remaining_in_block = 256 - s_index;
|
||||||
|
u64 chunk_size = std::min(remaining_in_block, length - bytes_read);
|
||||||
|
|
||||||
|
// Perform bulk copy for the current segment
|
||||||
|
std::memcpy(out + bytes_read, &_blocks[b_index].data[s_index], chunk_size);
|
||||||
|
|
||||||
|
// Advance pointers
|
||||||
|
bytes_read += chunk_size;
|
||||||
|
b_index++;
|
||||||
|
s_index = 0; // reset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current size of the instructions.
|
||||||
|
*/
|
||||||
|
u64 InstrReelDyn::size() {
|
||||||
|
return _size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mutation //
|
||||||
|
|
||||||
|
// TODO!
|
||||||
|
|
||||||
|
void InstrReelDyn::writeU8(u64 ip, u8 dat) {}
|
||||||
|
|
||||||
|
void InstrReelDyn::writeU16(u64 ip, u16 dat) {}
|
||||||
|
|
||||||
|
void InstrReelDyn::writeU32(u64 ip, u32 dat) {}
|
||||||
|
|
||||||
|
void InstrReelDyn::writeU64(u64 ip, u64 dat) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Appends instruction at the end.
|
* Appends instruction at the end.
|
||||||
*/
|
*/
|
||||||
void InstrReelDyn::append(u16 bc) {}
|
void InstrReelDyn::append(u16 bc) {}
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes instruction at location.
|
|
||||||
*/
|
|
||||||
void InstrReelDyn::remove(u64 ip) {}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,8 @@ namespace spider {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
u64 _use_count;
|
deque<ReelBlock> _blocks;
|
||||||
isize _block_index;
|
u64 _size;
|
||||||
std::deque<ReelBlock> _blocks;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -40,11 +39,11 @@ namespace spider {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
isize selectIndex(u64 ip);
|
std::pair<u64, u8> indexOf(u64 ip);
|
||||||
|
|
||||||
void growToFit(isize index);
|
bool continous(u64 ip0, u64 ip1, u64* b_index, u16* s_index);
|
||||||
|
|
||||||
ReelBlock* selectBlock(isize index);
|
void growTo(u64 ip);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -54,7 +53,7 @@ namespace spider {
|
|||||||
* Reindexing may occur, continous access
|
* Reindexing may occur, continous access
|
||||||
* may incurr in less penalties.
|
* may incurr in less penalties.
|
||||||
*/
|
*/
|
||||||
virtual u8 atU8(u64 ip) override;
|
virtual u8 readU8(u64 ip) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains a byte of data at
|
* Obtains a byte of data at
|
||||||
@@ -62,7 +61,7 @@ namespace spider {
|
|||||||
* Reindexing may occur, continous access
|
* Reindexing may occur, continous access
|
||||||
* may incurr in less penalties.
|
* may incurr in less penalties.
|
||||||
*/
|
*/
|
||||||
virtual u16 atU16(u64 ip) override;
|
virtual u16 readU16(u64 ip) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains a byte of data at
|
* Obtains a byte of data at
|
||||||
@@ -70,7 +69,7 @@ namespace spider {
|
|||||||
* Reindexing may occur, continous access
|
* Reindexing may occur, continous access
|
||||||
* may incurr in less penalties.
|
* may incurr in less penalties.
|
||||||
*/
|
*/
|
||||||
virtual u32 atU32(u64 ip) override;
|
virtual u32 readU32(u64 ip) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains a byte of data at
|
* Obtains a byte of data at
|
||||||
@@ -78,33 +77,34 @@ namespace spider {
|
|||||||
* Reindexing may occur, continous access
|
* Reindexing may occur, continous access
|
||||||
* may incurr in less penalties.
|
* may incurr in less penalties.
|
||||||
*/
|
*/
|
||||||
virtual u64 atU64(u64 ip) override;
|
virtual u64 readU64(u64 ip) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a range of data, and
|
||||||
|
* outputs it.
|
||||||
|
*/
|
||||||
|
virtual void readRange(u64 ip, u8* out, u64 length) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current size of the instructions.
|
||||||
|
*/
|
||||||
|
virtual u64 size() override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void at(u64 ip, u8 dat);
|
void writeU8(u64 ip, u8 dat);
|
||||||
|
|
||||||
void at(u64 ip, u16 dat);
|
void writeU16(u64 ip, u16 dat);
|
||||||
|
|
||||||
void at(u64 ip, u32 dat);
|
void writeU32(u64 ip, u32 dat);
|
||||||
|
|
||||||
void at(u64 ip, u64 dat);
|
void writeU64(u64 ip, u64 dat);
|
||||||
|
|
||||||
/**
|
|
||||||
* Appends instruction at location.
|
|
||||||
*/
|
|
||||||
void append(u64 ip, u16 bc);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Appends instruction at the end.
|
* Appends instruction at the end.
|
||||||
*/
|
*/
|
||||||
void append(u16 bc);
|
void append(u16 bc);
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes instruction at location.
|
|
||||||
*/
|
|
||||||
void remove(u64 ip);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,22 +8,16 @@ namespace spider {
|
|||||||
|
|
||||||
// Constructors & Destructors //
|
// Constructors & Destructors //
|
||||||
|
|
||||||
InstrReelFixed::InstrReelFixed(u64 length) {
|
InstrReelFixed::InstrReelFixed(u64 length)
|
||||||
this->_offset = 0;
|
: _mem(nullptr), _size(length) {
|
||||||
this->_size = length;
|
|
||||||
this->_total_size = length;
|
|
||||||
|
|
||||||
if (_size > 0) {
|
if (_size > 0) {
|
||||||
_mem = new u8[_size];
|
_mem = new u8[_size];
|
||||||
std::memset(_mem, 0, _size);
|
std::memset(_mem, 0, _size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InstrReelFixed::InstrReelFixed(const u8* data, u64 length) {
|
InstrReelFixed::InstrReelFixed(const u8* data, u64 length)
|
||||||
this->_offset = 0;
|
: _mem(nullptr), _size(length) {
|
||||||
this->_size = length;
|
|
||||||
this->_total_size = length;
|
|
||||||
|
|
||||||
if (_size > 0) {
|
if (_size > 0) {
|
||||||
_mem = new u8[_size];
|
_mem = new u8[_size];
|
||||||
std::copy(data, data + _size, _mem);
|
std::copy(data, data + _size, _mem);
|
||||||
@@ -31,29 +25,77 @@ namespace spider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
InstrReelFixed::InstrReelFixed(const InstrReelFixed& other) {
|
InstrReelFixed::InstrReelFixed(const InstrReelFixed& other) {
|
||||||
_offset = other._offset;
|
|
||||||
_size = other._size;
|
_size = other._size;
|
||||||
_total_size = other._total_size;
|
|
||||||
_mem = new u8[_size];
|
_mem = new u8[_size];
|
||||||
std::copy(other._mem, other._mem + _size, _mem);
|
std::copy(other._mem, other._mem + _size, _mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
InstrReelFixed::InstrReelFixed(InstrReelFixed&& other) noexcept {
|
InstrReelFixed::InstrReelFixed(InstrReelFixed&& other) noexcept {
|
||||||
_mem = other._mem;
|
_mem = other._mem;
|
||||||
_offset = other._offset;
|
|
||||||
_size = other._size;
|
_size = other._size;
|
||||||
_total_size = other._total_size;
|
|
||||||
|
|
||||||
other._mem = nullptr;
|
other._mem = nullptr;
|
||||||
other._offset = 0;
|
|
||||||
other._size = 0;
|
other._size = 0;
|
||||||
other._total_size = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InstrReelFixed::~InstrReelFixed() {
|
InstrReelFixed::~InstrReelFixed() {
|
||||||
delete[] _mem;
|
delete[] _mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// General Case(s) //
|
||||||
|
|
||||||
|
// Instruction abstraction //
|
||||||
|
|
||||||
|
u8 InstrReelFixed::readU8(u64 ip) {
|
||||||
|
// guard against access
|
||||||
|
if(ip + 1 > _size) return 0;
|
||||||
|
|
||||||
|
// send byte
|
||||||
|
return _mem[ip];
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 InstrReelFixed::readU16(u64 ip) {
|
||||||
|
// guard against access
|
||||||
|
if(ip + 2 > _size) return 0;
|
||||||
|
|
||||||
|
// build a 16-bit big endian number
|
||||||
|
u16 dat;
|
||||||
|
spider::loadLE(&dat, _mem + ip);
|
||||||
|
return dat;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 InstrReelFixed::readU32(u64 ip) {
|
||||||
|
// guard against access
|
||||||
|
if(ip + 4 > _size) return 0;
|
||||||
|
|
||||||
|
// build a 32-bit big endian number
|
||||||
|
u32 dat;
|
||||||
|
spider::loadLE(&dat, _mem + ip);
|
||||||
|
return dat;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 InstrReelFixed::readU64(u64 ip) {
|
||||||
|
// guard against access
|
||||||
|
if(ip + 8 > _size) return 0;
|
||||||
|
|
||||||
|
// build a 64-bit big endian number
|
||||||
|
u64 dat;
|
||||||
|
spider::loadLE(&dat, _mem + ip);
|
||||||
|
return dat;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InstrReelFixed::readRange(u64 ip, u8* out, u64 length) {
|
||||||
|
if(ip + length > _size) {
|
||||||
|
std::memset(out, 0, length);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::memcpy(out, _mem + ip, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 InstrReelFixed::size() {
|
||||||
|
return _size;
|
||||||
|
}
|
||||||
|
|
||||||
// Assign Operators //
|
// Assign Operators //
|
||||||
|
|
||||||
InstrReelFixed& InstrReelFixed::operator=(const InstrReelFixed& other) {
|
InstrReelFixed& InstrReelFixed::operator=(const InstrReelFixed& other) {
|
||||||
@@ -64,9 +106,7 @@ namespace spider {
|
|||||||
|
|
||||||
delete[] _mem;
|
delete[] _mem;
|
||||||
_mem = new_mem;
|
_mem = new_mem;
|
||||||
_offset = other._offset;
|
|
||||||
_size = other._size;
|
_size = other._size;
|
||||||
_total_size = other._total_size;
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -77,36 +117,32 @@ namespace spider {
|
|||||||
delete[] _mem;
|
delete[] _mem;
|
||||||
|
|
||||||
_mem = other._mem; // steal
|
_mem = other._mem; // steal
|
||||||
_offset = other._offset;
|
|
||||||
_size = other._size;
|
_size = other._size;
|
||||||
_total_size = other._total_size;
|
|
||||||
|
|
||||||
other._mem = nullptr; // leave as husk
|
other._mem = nullptr; // leave as husk
|
||||||
other._offset = 0;
|
|
||||||
other._size = 0;
|
other._size = 0;
|
||||||
other._total_size = 0;
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Misc //
|
// Misc //
|
||||||
|
|
||||||
void InstrReelFixed::at(u64 ip, u8 dat) {
|
void InstrReelFixed::writeU8(u64 ip, u8 dat) {
|
||||||
if(ip + 1 > _size) return;
|
if(ip + 1 > _size) return;
|
||||||
_mem[ip] = dat;
|
_mem[ip] = dat;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstrReelFixed::at(u64 ip, u16 dat) {
|
void InstrReelFixed::writeU16(u64 ip, u16 dat) {
|
||||||
if(ip + 2 > _size) return;
|
if(ip + 2 > _size) return;
|
||||||
spider::storeLE(dat, _mem + ip);
|
spider::storeLE(dat, _mem + ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstrReelFixed::at(u64 ip, u32 dat) {
|
void InstrReelFixed::writeU32(u64 ip, u32 dat) {
|
||||||
if(ip + 4 > _size) return;
|
if(ip + 4 > _size) return;
|
||||||
spider::storeLE(dat, _mem + ip);
|
spider::storeLE(dat, _mem + ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstrReelFixed::at(u64 ip, u64 dat) {
|
void InstrReelFixed::writeU64(u64 ip, u64 dat) {
|
||||||
if(ip + 8 > _size) return;
|
if(ip + 8 > _size) return;
|
||||||
spider::storeLE(dat, _mem + ip);
|
spider::storeLE(dat, _mem + ip);
|
||||||
}
|
}
|
||||||
@@ -120,7 +156,6 @@ namespace spider {
|
|||||||
delete[] _mem;
|
delete[] _mem;
|
||||||
_mem = nullptr;
|
_mem = nullptr;
|
||||||
_size = 0;
|
_size = 0;
|
||||||
_total_size = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +178,6 @@ namespace spider {
|
|||||||
delete[] _mem;
|
delete[] _mem;
|
||||||
_mem = new_mem;
|
_mem = new_mem;
|
||||||
_size = new_size;
|
_size = new_size;
|
||||||
_total_size = new_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ namespace spider {
|
|||||||
* Implements an instruction reel.
|
* Implements an instruction reel.
|
||||||
*/
|
*/
|
||||||
class InstrReelFixed : public InstrReel {
|
class InstrReelFixed : public InstrReel {
|
||||||
|
private:
|
||||||
|
u8* _mem;
|
||||||
|
u64 _size;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
InstrReelFixed(u64 length);
|
InstrReelFixed(u64 length);
|
||||||
@@ -28,13 +32,58 @@ namespace spider {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void at(u64 ip, u8 dat);
|
/**
|
||||||
|
* Obtains a byte of data at
|
||||||
|
* the specific location.
|
||||||
|
* Reindexing may occur, continous access
|
||||||
|
* may incurr in less penalties.
|
||||||
|
*/
|
||||||
|
virtual u8 readU8(u64 ip) override;
|
||||||
|
|
||||||
void at(u64 ip, u16 dat);
|
/**
|
||||||
|
* Obtains a byte of data at
|
||||||
|
* the specific location.
|
||||||
|
* Reindexing may occur, continous access
|
||||||
|
* may incurr in less penalties.
|
||||||
|
*/
|
||||||
|
virtual u16 readU16(u64 ip) override;
|
||||||
|
|
||||||
void at(u64 ip, u32 dat);
|
/**
|
||||||
|
* Obtains a byte of data at
|
||||||
|
* the specific location.
|
||||||
|
* Reindexing may occur, continous access
|
||||||
|
* may incurr in less penalties.
|
||||||
|
*/
|
||||||
|
virtual u32 readU32(u64 ip) override;
|
||||||
|
|
||||||
void at(u64 ip, u64 dat);
|
/**
|
||||||
|
* Obtains a byte of data at
|
||||||
|
* the specific location.
|
||||||
|
* Reindexing may occur, continous access
|
||||||
|
* may incurr in less penalties.
|
||||||
|
*/
|
||||||
|
virtual u64 readU64(u64 ip) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a range of data, and
|
||||||
|
* outputs it.
|
||||||
|
*/
|
||||||
|
virtual void readRange(u64 ip, u8* out, u64 length) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current size of the instructions.
|
||||||
|
*/
|
||||||
|
virtual u64 size() override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void writeU8(u64 ip, u8 dat);
|
||||||
|
|
||||||
|
void writeU16(u64 ip, u16 dat);
|
||||||
|
|
||||||
|
void writeU32(u64 ip, u32 dat);
|
||||||
|
|
||||||
|
void writeU64(u64 ip, u64 dat);
|
||||||
|
|
||||||
void resize(u64 new_size);
|
void resize(u64 new_size);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user