History

Alter register address decoding using a lookup table instead of single function with multiple switch blocks. Reduced scheduler sleep time during tool dispatch setting.

arr committed 10 years ago

Commit 824a71a1 parent fcc75fd7 files · +500 −86Browse files

Showing the changes to src/vm/thread.cpp (1 of 7 files). Show all

Unified · Split

src/vm/thread.cpp+3−78
@@ -20,87 +20,12 @@ using namespace disvm::runtime; · 19 unmodified lines
20 20
21namespace21namespace
22{22{
23#include "address_decoding.inc"
24
23 // Update VM registers based on the instruction.25 // Update VM registers based on the instruction.
24 void decode_address(const vm_exec_op_t &inst, vm_registers_t &reg)26 void decode_address(const vm_exec_op_t &inst, vm_registers_t &reg)
25 {27 {
26 switch (inst.source.mode)28 decode_table[inst.addr_code](inst, reg);
27 {
28 case address_mode_t::offset_indirect_fp:
29 reg.src = reinterpret_cast<pointer_t>(reinterpret_cast<uint8_t *>(reg.stack.peek_frame()->base()) + inst.source.register1);
30 break;
31 case address_mode_t::offset_indirect_mp:
32 reg.src = reinterpret_cast<pointer_t>(reinterpret_cast<uint8_t *>(reg.mp_base->get_allocation()) + inst.source.register1);
33 break;
34 case address_mode_t::offset_double_indirect_fp:
35 {
36 const auto frame_offset = *reinterpret_cast<std::size_t *>(reinterpret_cast<uint8_t *>(reg.stack.peek_frame()->base()) + inst.source.register1);
37 reg.src = reinterpret_cast<pointer_t>(frame_offset + inst.source.register2);
38 break;
39 }
40 case address_mode_t::offset_double_indirect_mp:
41 {
42 const auto mp_offset = *reinterpret_cast<std::size_t *>(reinterpret_cast<uint8_t *>(reg.mp_base->get_allocation()) + inst.source.register1);
43 reg.src = reinterpret_cast<pointer_t>(mp_offset + inst.source.register2);
44 break;
45 }
46 case address_mode_t::immediate:
47 reg.src = reinterpret_cast<pointer_t>(const_cast<word_t *>(&inst.source.register1));
48 break;
49 case address_mode_t::none:
50 reg.src = nullptr;
51 break;
52 default:
53 assert(false && "Unknown source addressing");
54 }
55
56 switch (inst.destination.mode)
57 {
58 case address_mode_t::offset_indirect_fp:
59 reg.dest = reinterpret_cast<pointer_t>(reinterpret_cast<uint8_t *>(reg.stack.peek_frame()->base()) + inst.destination.register1);
60 break;
61 case address_mode_t::offset_indirect_mp:
62 reg.dest = reinterpret_cast<pointer_t>(reinterpret_cast<uint8_t *>(reg.mp_base->get_allocation()) + inst.destination.register1);
63 break;
64 case address_mode_t::offset_double_indirect_fp:
65 {
66 const auto frame_offset = *reinterpret_cast<std::size_t *>(reinterpret_cast<uint8_t *>(reg.stack.peek_frame()->base()) + inst.destination.register1);
67 reg.dest = reinterpret_cast<pointer_t>(frame_offset + inst.destination.register2);
68 break;
69 }
70 case address_mode_t::offset_double_indirect_mp:
71 {
72 const auto mp_offset = *reinterpret_cast<std::size_t *>(reinterpret_cast<uint8_t *>(reg.mp_base->get_allocation()) + inst.destination.register1);
73 reg.dest = reinterpret_cast<pointer_t>(mp_offset + inst.destination.register2);
74 break;
75 }
76 case address_mode_t::immediate:
77 reg.dest = reinterpret_cast<pointer_t>(const_cast<word_t *>(&inst.destination.register1));
78 break;
79 case address_mode_t::none:
80 reg.dest = nullptr;
81 break;
82 default:
83 assert(false && "Unknown destination addressing");
84 }
85
86 switch (inst.middle.mode)
87 {
88 case address_mode_middle_t::small_offset_indirect_fp:
89 reg.mid = reinterpret_cast<pointer_t>(reinterpret_cast<uint8_t *>(reg.stack.peek_frame()->base()) + inst.middle.register1);
90 break;
91 case address_mode_middle_t::small_offset_indirect_mp:
92 reg.mid = reinterpret_cast<pointer_t>(reinterpret_cast<uint8_t *>(reg.mp_base->get_allocation()) + inst.middle.register1);
93 break;
94 case address_mode_middle_t::small_immediate:
95 reg.mid = reinterpret_cast<pointer_t>(const_cast<word_t *>(&inst.middle.register1));
96 break;
97 case address_mode_middle_t::none:
98 // [SPEC] This is an undocumented expectation but required in many operations (e.g. i++).
99 reg.mid = reg.dest;
100 break;
101 default:
102 assert(false && "Unknown middle addressing");
103 }
104 29
105#ifndef NDEBUG30#ifndef NDEBUG
106 // This is a perf critical function so logging is only available in debug builds31 // This is a perf critical function so logging is only available in debug builds