-
Notifications
You must be signed in to change notification settings - Fork 6
/
util.hpp
105 lines (93 loc) · 2.55 KB
/
util.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/**
* @file util.hpp
* @author paul
* @date 25.05.20
* Definition of utility functions for printing the results of program execution.
*/
#ifndef TEMPLATE_CPU_UTIL_HPP
#define TEMPLATE_CPU_UTIL_HPP
#include <iostream>
#include <iomanip>
#include "config.hpp"
/**
* Macro for generating a case statement which returns the string representation of the enum value
*/
#define ADD_CASE(a) case Register::a: return #a;
/**
* Get the string representation of a register.
* @param reg the register
* @return a string, with the exact name as the enum value
*/
auto getRegisterName(Register reg) -> std::string {
switch (reg) {
ADD_CASE(ZERO)
ADD_CASE(A)
ADD_CASE(B)
ADD_CASE(C)
ADD_CASE(D)
ADD_CASE(E)
ADD_CASE(F)
ADD_CASE(G)
ADD_CASE(H)
ADD_CASE(STACK_PTR)
ADD_CASE(RET)
default: return "ERROR";
}
}
/**
* Implementation of a compile time loop for printing the registers.
* @tparam registers the register map
* @tparam c the index at which to print
*/
template<Registers registers, std::size_t c>
struct registerPrinterImpl {
static void print() {
std::cout << getRegisterName(static_cast<Register>(c)) << " (" << c << "):\t" << GetVal<registers, 0>::val << std::endl;
registerPrinterImpl<typename registers::next, c+1>::print();
}
};
template<std::size_t c>
struct registerPrinterImpl<ListEnd, c> {
static void print() {}
};
/**
* Implementation of a compile time loop for printing the memory
* @tparam memory the memory
* @tparam c the index at which to print
*/
template<Memory memory, std::size_t c>
struct memoryPrinterImpl {
static void print() {
constexpr auto WORDS_PER_LINE = 16;
std::cout << std::setw(10) << GetVal<memory, 0>::val;
if (c % WORDS_PER_LINE == (WORDS_PER_LINE - 1)) {
std::cout << std::endl;
}
memoryPrinterImpl<typename memory::next, c+1>::print();
}
};
template<std::size_t c>
struct memoryPrinterImpl<ListEnd, c> {
static void print() {}
};
/**
* Struct used for printing registers and memory from a program result
* @tparam registers the registers
* @tparam memory the memory
*/
template<Registers registers, Memory memory>
struct printer {
/**
* Runtime function to printing the registers
*/
static void reg() {
registerPrinterImpl<registers, 0>::print();
}
/**
* Runtime function for printing the memory
*/
static void mem() {
memoryPrinterImpl<memory, 0>::print();
}
};
#endif //TEMPLATE_CPU_UTIL_HPP