-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathOP_AL_32I.cpp
118 lines (98 loc) · 3 KB
/
OP_AL_32I.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
#include "parameters.hpp"
r_e_type OP_AL_32I(inst_type opcode, func7_type func7, func3_type func3, r_type op1, r_type op2)
{
r_type rd_val;
bit_type error=0;
switch(opcode) {
case OP_AL_R:
switch(func7){ //func7
case FUNC7_0:
switch(func3){
case ADD: rd_val = ALU_SUM(op1,op2); break;
case SLL: rd_val = ALU_SLL(op1, op2.range(4,0));break;
case SLT: rd_val = ALU_SLT(op1,op2); break;
case SLTU:rd_val = ALU_SLTU((uns)op1, (uns)op2); break;
case XOR: rd_val = ALU_XOR(op1,op2);break;
case SRL: rd_val = ALU_SRL((uns) op1,op2.range(4,0));break;
case OR: rd_val = ALU_OR(op1,op2);break;
case AND: rd_val = ALU_AND(op1,op2);break;
default: error = 1;break;//... //illegal opcode
}
break;
case FUNC7_32:
switch(func3){ //func3
case SUB: rd_val = ALU_SUM(op1, ALU_NEG(op2)); break;
case SRA: rd_val = ALU_SRA(op1, op2.range(4,0));break;
default: error = 1;break;//... //illegal opcode
}
break;
default: error = 1;break; //... //illegal opcode
}
break;
case OP_AL_I:
switch(func3){
case ADD: rd_val = ALU_SUM(op1,op2); break;
case SLL: rd_val = ALU_SLL(op1, op2.range(4,0));break;
case SLT: rd_val = ALU_SLT(op1,op2); break;
case SLTU:rd_val = ALU_SLTU((uns)op1, (uns)op2); break;
case XOR: rd_val = ALU_XOR(op1,op2);break;
case SRL:
switch (func7) {
case FUNC7_0: rd_val = ALU_SRL((uns) op1,op2.range(4,0));break;
case FUNC7_32: rd_val = ALU_SRA(op1, op2.range(4,0));break;
default: error = 1; break;
}
break;
case OR: rd_val = ALU_OR(op1,op2);break;
case AND: rd_val = ALU_AND(op1,op2);break;
default: error = 1;break; //... //illegal opcode
}
break;
default: error = 1; break;
}
return (rd_val<<1) | error; //caution: you also have to return illegal opcode info!!
}
// For branching
imm_type OP_AL_32B(imm_type offset, func3_type func3, r_type op1, r_type op2) {
imm_type returnval;
switch(func3) {
case BEQ: (op1==op2) ? returnval = offset : returnval = 4; break;
case BNE: (op1!=op2) ? returnval = offset : returnval = 4; break;
case BLT: (op1<op2) ? returnval = offset : returnval = 4; break;
case BGE: (op1>=op2) ? returnval = offset : returnval = 4; break;
case BLTU: ((uns)op1<(uns)op2) ? returnval = offset : returnval = 4; break;
case BGEU: ((uns)op1>=(uns)op2) ? returnval = offset : returnval = 4; break;
default: returnval = 1; break;
}
return returnval;
}
imm_type ALU_SUM(imm_type op1, imm_type op2) {
return op1 + op2;
}
imm_type ALU_NEG(imm_type op1) {
return -op1;
}
imm_type ALU_SLL(imm_type op1, rf_pntr_type op2) {
return op1 << op2;
}
imm_type ALU_SLT(imm_type op1, imm_type op2) {
return (op1<op2);
}
imm_type ALU_SLTU(uns op1, uns op2) {
return (op1<op2);
}
imm_type ALU_XOR(imm_type op1, imm_type op2) {
return op1 ^ op2;
}
imm_type ALU_SRL(uns op1, rf_pntr_type op2) {
return op1 >> op2;
}
imm_type ALU_SRA(imm_type op1, rf_pntr_type op2) {
return op1 >> op2;
}
imm_type ALU_OR(imm_type op1, imm_type op2) {
return op1 | op2;
}
imm_type ALU_AND(imm_type op1, imm_type op2) {
return op1 & op2;
}