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
|
#include "ex.h"
#include "accessor.h"
#include "definitions.h"
#include "instrDTO.h"
#include "response.h"
#include "stage.h"
#include <unordered_map>
// clang-format off
#define INIT_INSTRUCTION(mnemonic, body) \
{mnemonic, [this](signed int &s1, signed int &s2) { \
body; \
}}
// clang-format on
EX::EX(Stage *stage) : Stage(stage)
{
this->id = EXEC;
instr_map = {
/* R type instructions */
INIT_INSTRUCTION(
ADD,
{
this->overflow_guard(s1, s2);
s1 = s1 + s2;
}),
INIT_INSTRUCTION(
SUB,
{
this->overflow_guard(s1, -s2);
s1 = s1 - s2;
}),
INIT_INSTRUCTION(MUL, {}),
INIT_INSTRUCTION(QUOT, {}),
INIT_INSTRUCTION(REM, {}),
INIT_INSTRUCTION(SFTR, {}),
INIT_INSTRUCTION(SFTL, {}),
INIT_INSTRUCTION(AND, {}),
INIT_INSTRUCTION(OR, {}),
INIT_INSTRUCTION(NOT, {}),
INIT_INSTRUCTION(XOR, {}),
INIT_INSTRUCTION(ADDV, {}),
INIT_INSTRUCTION(SUBV, {}),
INIT_INSTRUCTION(MULV, {}),
INIT_INSTRUCTION(DIVV, {}),
INIT_INSTRUCTION(CMP, {}),
INIT_INSTRUCTION(CEV, {}),
/* I type instructions */
INIT_INSTRUCTION(LOAD, {}),
INIT_INSTRUCTION(LOADV, {}),
INIT_INSTRUCTION(ADDI, {}),
INIT_INSTRUCTION(SUBI, {}),
INIT_INSTRUCTION(SFTRI, {}),
INIT_INSTRUCTION(SFTL, {}),
INIT_INSTRUCTION(ANDI, {}),
INIT_INSTRUCTION(ORI, {}),
INIT_INSTRUCTION(XORI, {}),
INIT_INSTRUCTION(STORE, {}),
INIT_INSTRUCTION(STOREV, {}),
/* J type instructions */
INIT_INSTRUCTION(JMP, {}),
INIT_INSTRUCTION(JRL, {}),
INIT_INSTRUCTION(JAL, {}),
INIT_INSTRUCTION(BEQ, {}),
INIT_INSTRUCTION(BGT, {}),
INIT_INSTRUCTION(BUF, {}),
INIT_INSTRUCTION(BOF, {}),
INIT_INSTRUCTION(PUSH, {}),
INIT_INSTRUCTION(POP, {}),
/* NOP */
INIT_INSTRUCTION(NOP, (void)s2; (void)s1;),
};
}
InstrDTO *EX::advance(Response p) { return nullptr; }
void EX::overflow_guard(signed int a, signed int b)
{
if (a >= 0 && b >= 0 && (a > MAX_INT - b)) {
this->set_condition(OF, true);
this->set_condition(UF, false);
} else if (a < 0 && b < 0 && (a < (-MAX_INT) - 1 - b)) {
this->set_condition(OF, false);
this->set_condition(UF, true);
} else {
this->set_condition(OF, false);
this->set_condition(UF, false);
}
}
|