This repository has been archived by the owner on Oct 27, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
execution.hpp
84 lines (76 loc) · 3.18 KB
/
execution.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
# include "memoryaccess.hpp"
# include "register.hpp"
# include "tools.hpp"
# include "prediction.hpp"
# ifndef _EXECUTION_
# define _EXECUTION_
class Execution {
friend class RISCV;
private:
Register *reg;
globalPrediction *glb;
public:
Instruction inst;
Execution(Register *_reg, globalPrediction *_glb) {
reg = _reg;
glb = _glb;
}
void go() {
if(inst.type == ERR) return ;
switch(inst.type) {
case LUI: inst.result = inst.imm; break;
case AUIPC: inst.result = inst.src1 - 4 + inst.imm; break;
case JALR: inst.resultpc = inst.src1 + inst.imm; inst.resultpc = setlowzero(inst.resultpc); break;
case BEQ: inst.result = static_cast <uint> (inst.src1 == inst.src2); break;
case BNE: inst.result = static_cast <uint> (inst.src1 != inst.src2); break;
case BLTU: inst.result = static_cast <uint> (inst.src1 < inst.src2); break;
case BGEU: inst.result = static_cast <uint> (inst.src1 >= inst.src2); break;
case BLT: inst.result = static_cast <uint> ((int)inst.src1 < (int)inst.src2); break;
case BGE: inst.result = static_cast <uint> ((int)inst.src1 >= (int)inst.src2); break;
case LB:
case LW:
case LH:
case LHU:
case LBU: inst.src1 = inst.src1 + sgnextend(inst.imm, 11); break;
case SB:
case SW:
case SH: inst.src1 = inst.src1 + sgnextend(inst.imm, 11); break;
case ADDI: inst.result = inst.src1 + inst.imm; break;
case SLTI: inst.result = static_cast <uint> ((int)inst.src1 < (int)inst.imm); break;
case SLTIU: inst.result = static_cast <uint> (inst.src1 < inst.imm); break;
case ANDI: inst.result = (inst.src1 & inst.imm); break;
case ORI: inst.result = (inst.src1 | inst.imm); break;
case XORI: inst.result = (inst.src1 ^ inst.imm); break;
case SLLI: inst.result = (inst.src1 << inst.imm); break;
case SRLI: inst.result = (inst.src1 >> inst.imm); break;
case SRAI: inst.result = ((inst.src1 >> inst.imm) | (inst.src1 >> 31 << 31)); break;
case ADD: inst.result = inst.src1 + inst.src2; break;
case SUB: inst.result = inst.src1 - inst.src2; break;
case SLL: inst.result = (inst.src1 << inst.src2); break;
case SRL: inst.result = (inst.src1 >> inst.src2); break;
case SRA: inst.result = ((inst.src1 >> inst.src2) | (inst.src1 >> 31 << 31)); break;
case SLT: inst.result = static_cast <uint> ((int)inst.src1 < (int)inst.src2); break;
case SLTU: inst.result = static_cast <uint> (inst.src1 < inst.src2); break;
case XOR: inst.result = (inst.src1 ^ inst.src2); break;
case OR: inst.result = (inst.src1 | inst.src2); break;
case AND: inst.result = (inst.src1 & inst.src2); break;
default: break;
}
}
bool check() {
if(inst.type == BEQ || inst.type == BNE || inst.type == BGE || inst.type == BLT || inst.type == BGEU || inst.type == BLTU) {
if(inst.pred != inst.result) {
glb -> addResult(inst.type, inst.result, 0);
if(inst.pred == 0) reg -> setpc(inst.resultpc - 4 + inst.imm);
else reg -> setpc(inst.resultpc);
return false;
} else glb -> addResult(inst.type, inst.result, 1);
return true;
}
return true;
}
void pass(MemoryAccess &nxt) {
nxt.inst = inst;
}
};
# endif