MCPcopy Create free account
hub / github.com/D7EAD/mkPIVM / VMConfig

Method VMConfig

src/vm_isa.cpp:8–165  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

6
7namespace mkpivm {
8 VMConfig::VMConfig(Arch arch, SeedRng& rng) : arch_{arch}, master_seed_{rng.next()} {
9 // register file shape
10 // need 16 arch gprs + 4 tmps + at least 4 scratch = 24 minimum
11 reg_count_ = static_cast<std::uint8_t>(rng.uniform(24, 32));
12
13 // XReg to slot mapping. random permutation over 0..reg_count_-1 with
14 // the first 16 reserved for x86 gprs
15 std::vector<std::uint8_t> perm(reg_count_);
16 for (std::uint8_t i = 0; i < reg_count_; ++i) perm[i] = i;
17 shuffle_in_place(perm, rng);
18
19 const std::uint8_t gpr_count = arch_native_gpr_count(arch);
20 xreg_to_slot_.fill(0xFF);
21 for (std::uint8_t i = 0; i < gpr_count; ++i) {
22 xreg_to_slot_[i] = perm[i];
23 }
24
25 // four slots for Tmp0..Tmp3. these sit past the arch gprs
26 const std::uint8_t tmp_count = 4;
27 for (std::uint8_t i = 0; i < tmp_count; ++i) {
28 xreg_to_slot_[16 + i] = perm[gpr_count + i];
29 }
30 scratch_slots_.assign(perm.begin() + gpr_count + tmp_count, perm.begin() + reg_count_);
31
32 // VMState layout. fields go in random order
33 auto pad = [&](std::uint16_t cur, std::uint16_t align) {
34 const std::uint16_t over = cur % align;
35 return over ? static_cast<std::uint16_t>(cur + (align - over)) : cur;
36 };
37
38 auto sprinkle_gap = [&](std::uint16_t cur)->std::uint16_t {
39 return cur + static_cast<std::uint16_t>(rng.uniform(0, 7));
40 };
41
42 std::uint16_t cur = static_cast<std::uint16_t>(rng.uniform(0, 31)); // random initial offset
43 cur = pad(cur, 8);
44
45 // reg-slot array.
46 state_.regs_base = cur;
47 state_.regs_total_bytes = static_cast<std::uint16_t>(reg_count_ * 8);
48 cur = static_cast<std::uint16_t>(cur + state_.regs_total_bytes);
49
50 // scalar fields, placed in random order.
51 enum Field { F_OP, F_A, F_B, F_RES, F_W, F_DF, F_CSP, F_RSP, F_BCB, F_DIB, F_BTB, F_BTC, F_TRB, F_EXT, F_CSB, F_END };
52 std::array<std::uint8_t, F_END> order{};
53 for (std::uint8_t i = 0; i < F_END; ++i) order[i] = i;
54 shuffle_in_place(order, rng);
55
56 for (auto f : order) {
57 cur = sprinkle_gap(cur);
58 cur = pad(cur, 8);
59 switch (f) {
60 case F_OP: state_.flags_op = cur; cur += 8; break;
61 case F_A: state_.flags_a = cur; cur += 8; break;
62 case F_B: state_.flags_b = cur; cur += 8; break;
63 case F_RES: state_.flags_result = cur; cur += 8; break;
64 case F_W: state_.flags_width = cur; cur += 8; break;
65 case F_DF: state_.df = cur; cur += 8; break;

Callers

nothing calls this directly

Calls 7

shuffle_in_placeFunction · 0.85
arch_native_gpr_countFunction · 0.85
nextMethod · 0.80
uniformMethod · 0.80
beginMethod · 0.80
pickMethod · 0.80
chanceMethod · 0.80

Tested by

no test coverage detected