forked from data61/MP-SPDZ
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Program.hpp
139 lines (125 loc) · 2.95 KB
/
Program.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
* Program.cpp
*
*/
#ifndef GC_PROGRAM_HPP_
#define GC_PROGRAM_HPP_
#include <GC/Program.h>
#include "Instruction_inline.h"
#include "instructions.h"
#include "config.h"
#include "Tools/callgrind.h"
#include "Processor/Instruction.hpp"
namespace GC
{
inline
Program::Program()
{
compute_constants();
}
inline
void Program::compute_constants()
{
for (int reg_type = 0; reg_type < MAX_REG_TYPE; reg_type++)
{
max_reg[reg_type] = 0;
max_mem[reg_type] = 0;
}
for (unsigned int i = 0; i < p.size(); i++)
{
for (int reg_type = 0; reg_type < MAX_REG_TYPE; reg_type++)
{
max_reg[reg_type] = max(max_reg[reg_type],
p[i].get_max_reg(RegType(reg_type)));
max_mem[reg_type] = max(max_mem[reg_type],
p[i].get_mem(RegType(reg_type)));
}
}
}
inline
void Program::parse(const string& bytecode_name)
{
string filename = "Programs/Bytecode/" + bytecode_name + ".bc";
parse_file(filename);
}
inline
void Program::parse_file(const string& filename)
{
ifstream s(filename.c_str());
if (s.bad() or s.fail())
throw runtime_error("Cannot open " + filename);
parse(s);
}
inline
void Program::parse(istream& s)
{
p.resize(0);
Instruction instr;
s.peek();
int pos = 0;
CALLGRIND_STOP_INSTRUMENTATION;
while (!s.eof())
{
if (s.bad() or s.fail())
throw runtime_error("error reading program");
instr.parse(s, pos);
p.push_back(instr);
//cerr << "\t" << instr << endl;
s.peek();
pos++;
}
CALLGRIND_START_INSTRUMENTATION;
compute_constants();
}
template <class T, class U>
BreakType Program::execute(Processor<T>& Proc, U& dynamic_memory,
int PC) const
{
if (PC != -1)
Proc.PC = PC;
#ifdef DEBUG_ROUNDS
cout << typeid(T).name() << " starting at PC " << Proc.PC << "/" <<
p.size() << endl;
#endif
unsigned int size = p.size();
size_t time = Proc.time;
Proc.complexity = 0;
auto& Ci = Proc.I;
auto& processor = Proc;
do
{
#ifdef DEBUG_EXE
cout << "execute " << time << "/" << Proc.PC << " " << T::phase_name()
<< endl;
#endif
if (Proc.PC >= size)
{
Proc.time = time;
return DONE_BREAK;
}
#ifdef COUNT_INSTRUCTIONS
Proc.stats[p[Proc.PC].get_opcode()]++;
#endif
auto& instruction = p[Proc.PC++];
switch (instruction.get_opcode())
{
#define X(NAME, CODE) case NAME: CODE; break;
INSTRUCTIONS
#undef X
default:
fallback_code(instruction, processor);
}
time++;
#ifdef DEBUG_COMPLEXITY
cout << "complexity at " << time << ": " << Proc.complexity << endl;
#endif
}
while (Proc.complexity < (1 << 19));
Proc.time = time;
#ifdef DEBUG_ROUNDS
cout << "breaking at time " << Proc.time << endl;
#endif
return TIME_BREAK;
}
} /* namespace GC */
#endif