-
Notifications
You must be signed in to change notification settings - Fork 0
/
alu.cpp
140 lines (135 loc) · 4.72 KB
/
alu.cpp
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
140
#include "alu.h"
Alu::Alu(
unordered_map<string, double> & cdb,
unordered_map<string, double> & physicalRegs,
unordered_map<int, double> & memories,
const bool debugMode
) :
cdb(cdb),
physicalRegs(physicalRegs),
memories(memories),
debugMode(debugMode)
{
this->moduleType = ModuleType::ALU;
};
// perform operation based on InstructionType
double Alu::performOperation(ROBStatus inpEntry, RSStatus inpRs) {
double newVj;
if (cdb.count(inpRs.vj)) newVj = cdb[inpRs.vj];
else newVj = physicalRegs[inpRs.vj];
double newVk;
if (cdb.count(inpRs.vk)) newVk = cdb[inpRs.vk];
else if (
inpEntry.instruction.opcode != InstructionType::ADDI &&
inpEntry.instruction.opcode != InstructionType::FLD
) {
if (inpEntry.instruction.rt == ZERO_REGISTER_NAME)
newVk = 0;
else if (inpEntry.instruction.opcode == InstructionType::BNE)
newVk = physicalRegs[inpEntry.instruction.rd];
else
newVk = physicalRegs[inpEntry.instruction.rt];
}
if (debugMode) {
cout << "PERFORMING ALU FOR=\n";
printROBStatus(inpEntry);
printRSStatus(inpRs);
}
switch (inpEntry.instruction.opcode) {
case InstructionType::FLD: {
if (debugMode) cout << "\nFLD alu hit (memories key = Vj + imm)= " <<
newVj <<
" + " <<
inpEntry.instruction.immediate <<
" = " << memories[newVj + inpEntry.instruction.immediate] <<
"(key= " << newVj + inpEntry.instruction.immediate << ")" <<
"\n";
return memories[newVj + inpEntry.instruction.immediate];
}
case InstructionType::FSD: {
if (debugMode) cout << "\nFSD alu hit (val = Vk + imm)= " <<
newVk <<
" + " <<
inpEntry.instruction.immediate <<
" = " << newVk + inpEntry.instruction.immediate <<
"\n";
return newVk + inpEntry.instruction.immediate;
}
case InstructionType::ADD: {
if (debugMode) cout << "\nADD alu hit (val = Vj + Vk)= " <<
newVj <<
" + " <<
newVk <<
" = " << (int)(newVj + newVk) <<
"\n";
return (int)(newVj + newVk);
}
case InstructionType::ADDI: {
if (debugMode) cout << "\nADDI alu hit (val = Vj + imm)= " <<
newVj <<
" + " <<
inpEntry.instruction.immediate <<
" = " << newVj + inpEntry.instruction.immediate <<
"\n";
return newVj + inpEntry.instruction.immediate;
}
case InstructionType::SLT: {
if (debugMode) cout << "\nSLT alu hit (val = Vj < Vk)= " <<
newVj <<
" < " <<
newVk <<
" = " << (newVj < newVk) <<
"\n";
return newVj < newVk; // double val returned as 0(false) or 1(true)
}
case InstructionType::FADD: {
if (debugMode) cout << "\nFADD alu hit (val = Vj + Vk)= " <<
newVj <<
" + " <<
newVk <<
" = " << newVj + newVk <<
"\n";
return newVj + newVk;
}
case InstructionType::FSUB: {
if (debugMode) cout << "\nFSUB alu hit (val = Vj - Vk)= " <<
newVj <<
" - " <<
newVk <<
" = " << newVj - newVk <<
"\n";
return newVj - newVk;
}
case InstructionType::FMUL: {
if (debugMode) cout << "\nFMUL alu hit (val = Vj * Vk)= " <<
newVj <<
" * " <<
newVk <<
" = " << newVj * newVk <<
"\n";
return newVj * newVk;
}
case InstructionType::FDIV: {
if (debugMode) cout << "\nFDIV alu hit (val = Vj / Vk)= " <<
newVj <<
" / " <<
newVk <<
" = " << newVj / newVk <<
"\n";
return newVj / newVk;
}
case InstructionType::BNE: {
if (debugMode) cout << "\nBNE alu hit (val = Vj != Vk)= " <<
newVj <<
" != " <<
newVk <<
" = " << (newVj != newVk) <<
"\n";
return newVj != newVk; // double val returned as 0(false) or 1(true)
}
default: throw invalid_argument(
"e_alu: the provided InstructionType was not recognized. Check to ensure that input parameters are not null or invalid"
);
}
return 0;
}