Skip to content

Commit

Permalink
#8 change capability representation to store only necessary bits for …
Browse files Browse the repository at this point in the history
…the type
  • Loading branch information
hakase56557 committed Aug 18, 2023
1 parent 35fd7b3 commit 4c472d8
Show file tree
Hide file tree
Showing 6 changed files with 292 additions and 85 deletions.
1 change: 0 additions & 1 deletion src/arch/riscvcapstone/base_types.hh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ struct uint128_t {
uint128_t() = default;
};


static_assert(sizeof(uint128_t) == 16);
static_assert(std::is_aggregate_v<uint128_t>);

Expand Down
166 changes: 98 additions & 68 deletions src/arch/riscvcapstone/isa/decoder.isa

Large diffs are not rendered by default.

67 changes: 65 additions & 2 deletions src/arch/riscvcapstone/o3/cap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ CompressedCapBound::decode(uint64_t addr) const {
uint8_t Lcarry;
uint8_t Lmsb;

DPRINTF(Cap, "Addr %llx, (%llx, %llx, %llx, %llx, %llx)",
DPRINTX(Cap, "Addr %llx, (%llx, %llx, %llx, %llx, %llx)",
addr, bE, b, tE, t, iE);

if(iE == 0) {
Expand Down Expand Up @@ -106,7 +106,7 @@ CompressedCapBound::end(uint64_t addr) const {
CompressedCapBound::
CompressedCapBound(uint64_t base, uint64_t top, uint64_t addr) {
assert(top >= base);
DPRINTF(Cap, "(%llx, %llx, %llx)",
DPRINTX(Cap, "(%llx, %llx, %llx)",
base, top, addr);

uint64_t len = top - base;
Expand Down Expand Up @@ -181,6 +181,69 @@ CompressedCap::setAddresses(uint64_t start, uint64_t end, uint64_t cursor) {
return *this;
}

NewCap::NewCap(uint128_t c) {
__uint128_t v;
memcpy(&v, &c, sizeof(c));
_type = (v >> 94) & ((1 << 3) - 1);
_node_id = (v >> 97) & ((1 << 31) - 1);

CapType type = static_cast<CapType>(_type);

if(type == CapType::LIN || type == CapType::NONLIN || type == CapType::REV || type == CapType::UNINIT) {
_cursor = v & ((1 << 64) - 1);
uint32_t bound = (v >> 64) & ((1 << 27) - 1);
DPRINTX(Cap, "Decode: bound = %x\n", bound);
CompressedCapBound cb(bound);
_start = cb.start(_cursor);
_end = cb.end(_cursor);
DPRINTX(Cap, "Decode: start = %x, end = %x\n", _start, _end);
DPRINTX(Cap, "Decode: cursor = %x\n", _cursor);
_perm = (v >> 91) & ((1 << 3) - 1);
} else {
_start = v & ((1 << 64) - 1);

if(type == CapType::SEALED) {
_async = (v >> 92) & ((1 << 2) - 1);
} else {
uint64_t cursor_offset = (v >> 64) & ((1 << 23) - 1);
_cursor = _start + cursor_offset;

if(type == CapType::SEALEDRET) {
_reg = (v >> 87) & ((1 << 5) - 1);
_async = (v >> 92) & ((1 << 2) - 1);
}
}
}
}

NewCap::operator uint128_t() const {
__uint128_t v = 0;

CapType type = static_cast<CapType>(_type);

if(type == CapType::LIN || type == CapType::NONLIN || type == CapType::REV || type == CapType::UNINIT) {
uint32_t bound = CompressedCapBound(_start, _end, _cursor).toRaw();
v = __uint128_t(_cursor) | (__uint128_t(bound) << 64) | (__uint128_t(_perm) << 91) | (__uint128_t(_type) << 94) | (__uint128_t(_node_id) << 97);
DPRINTX(Cap, "Encode: bound = %x\n", bound);
} else {
if(type == CapType::SEALED) {
v = __uint128_t(_start) | (__uint128_t(_async) << 92) | (__uint128_t(_type) << 94) | (__uint128_t(_node_id) << 97);
} else {
uint64_t cursor_offset = (_cursor - _start) & ((1 << 23) - 1);
uint8_t reg_5bits = _reg & ((1 << 5) - 1);

if (type == CapType::SEALEDRET) {
v = __uint128_t(_start) | (__uint128_t(cursor_offset) << 64) | (__uint128_t(reg_5bits) << 87) | (__uint128_t(_async) << 92) | (__uint128_t(_type) << 94) | (__uint128_t(_node_id) << 97);
} else { //CapType::EXIT
v = __uint128_t(_start) | (__uint128_t(cursor_offset) << 64) | (__uint128_t(reg_5bits) << 94) | (__uint128_t(_node_id) << 97);
}
}
}

uint128_t* c = new uint128_t;
memcpy(c, &v, sizeof(v));
return *c;
}
}
}
}
124 changes: 117 additions & 7 deletions src/arch/riscvcapstone/o3/cap.hh
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,17 @@ enum class CapType {
EXIT = 6
};

inline bool operator<=(CapPerm lhs, CapPerm rhs) {
enum class CapAsync {
SYNC = 0,
EXCEPT = 1,
INTERRUPT = 2
};

inline bool decreasing_perms(CapPerm lhs, CapPerm rhs) {
uint8_t lhs_i = static_cast<uint8_t>(lhs);
uint8_t rhs_i = static_cast<uint8_t>(rhs);

while(lhs_i && rhs_i) {
while(lhs_i || rhs_i) {
if(!(rhs_i & 1) && (lhs_i & 1))
return false;

Expand All @@ -78,17 +84,120 @@ inline bool operator<=(CapPerm lhs, CapPerm rhs) {
* TODO: can consider defining a separate more ergonomic representation and only
* translate into this when storing it in memory
* */

class NewCap {
private:
uint64_t _cursor;
uint64_t _start, _end;
uint8_t _perm;
uint8_t _type;
NodeID _node_id;
uint8_t _async;
uint8_t _reg;

public:
NewCap() = default;

NewCap(uint128_t c);

CapPerm perm() const {
return static_cast<CapPerm>(_perm);
}

CapType type() const {
return static_cast<CapType>(_type);
}

uint64_t cursor() const {
return _cursor;
}

uint64_t start() const {
return _start;
}

uint64_t end() const {
return _end;
}

NodeID nodeId() const {
return _node_id;
}

CapAsync async() const {
return static_cast<CapAsync>(_async);
}

NewCap& setBound(uint64_t start, uint64_t end) {
_start = start;
_end = end;
return *this;
}

NewCap& setCursor(uint64_t cursor) {
_cursor = cursor;
return *this;
}

NewCap& setAddresses(uint64_t start, uint64_t end, uint64_t cursor) {
_start = start;
_end = end;
_cursor = cursor;
return *this;
}

NewCap& setPerm(CapPerm perm) {
_perm = static_cast<uint8_t>(perm);
return *this;
}

NewCap& setType(CapType type) {
_type = static_cast<uint8_t>(type);
return *this;
}

NewCap& setNodeId(NodeID node_id) {
_node_id = node_id;
return *this;
}

NewCap& setAsync(CapAsync async) {
_async = static_cast<uint8_t>(async);
return *this;
}

NewCap& setReg(uint8_t reg) {
_reg = reg;
return *this;
}

bool hasReadPerm() {
return (_perm >> 2) & 1;
}

bool hasWritePerm() {
return (_perm >> 1) & 1;
}

bool hasExecPerm() {
return _perm & 1;
}

operator uint128_t() const;

void reset() {
setAddresses(0, 0, 0);
}
};

class CompressedCap {
private:
// bool valid: 1;
uint64_t _cursor;
//CompressedCapBound compressedBound;
uint32_t _bound: 27;
uint8_t _perm: 3;
uint8_t _type: 3;
NodeID _node_id: 31;
// uint8_t async: 2;
// uint8_t reg: 5;

//CompressedCap& setBound(const AddrRange& addr_range) {
//this->setBound(addr_range.start(), addr_range.end());
Expand Down Expand Up @@ -272,12 +381,13 @@ static_assert(sizeof(UncompressedCap) == (CAPSTONE_UNCOMPRESSED_CAP_SIZE >> 3));
static_assert(sizeof(CompressedCap) == (CAPSTONE_COMPRESSED_CAP_SIZE >> 3));

#ifdef CAPSTONE_USE_UNCOMPRESSED
using Cap = UncompressedCap;
// using Cap = UncompressedCap;
const size_t CAPSTONE_CAP_SIZE = CAPSTONE_UNCOMPRESSED_CAP_SIZE;
#else
using Cap = CompressedCap;
// using Cap = CompressedCap;
const size_t CAPSTONE_CAP_SIZE = CAPSTONE_COMPRESSED_CAP_SIZE;
#endif
using Cap = NewCap;

inline bool
capInBound(const Cap& cap) {
Expand Down
15 changes: 8 additions & 7 deletions src/base/types.hh
Original file line number Diff line number Diff line change
Expand Up @@ -185,16 +185,13 @@ using ConstTagRef = std::vector<bool>::const_reference;
struct RegVal {
using Cap = gem5::RiscvcapstoneISA::o3::Cap;
union {
Cap cap;
uint128_t cap;
uint64_t intv;
} val;
RegVal() { }
RegVal(uint64_t v) {
val.intv = v;
}
RegVal(const Cap& cap) {
val.cap = cap;
}
#ifdef CAPSTONE_USE_UNCOMPRESSED
RegVal(uint256_t v)
#else
Expand All @@ -213,14 +210,19 @@ struct RegVal {
return val.intv == other.val.intv;
}

Cap& capVal() {
uint128_t& rawCapVal() {
return val.cap;
}

const Cap& capVal() const {
const uint128_t& rawCapVal() const {
return val.cap;
}

Cap capVal() {
Cap* cap = new Cap(val.cap);
return *cap;
}

uint64_t& intVal() {
return val.intv;
}
Expand All @@ -229,7 +231,6 @@ struct RegVal {
return val.intv;
}


operator uint64_t&() {
return val.intv;
}
Expand Down
4 changes: 4 additions & 0 deletions src/sim/insttracer.hh
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,10 @@ class InstRecord
{
return;
}
void setData(uint128_t& c)
{
return;
}
#endif

void
Expand Down

0 comments on commit 4c472d8

Please sign in to comment.