-
Notifications
You must be signed in to change notification settings - Fork 0
/
ISA.h
336 lines (305 loc) · 13.5 KB
/
ISA.h
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
/* Utilities to decode MIPS ISA
Copyright (c) 2021 Amano laboratory, Keio University.
Author: Takuya Kojima
This file is part of CubeSim, a cycle accurate simulator for 3-D stacked system.
CubeSim is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
CubeSim is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CubeSim. If not, see <https://www.gnu.org/licenses/>.
*/
#include "cpu.h"
#include <map>
using operand_decodepr = uint16 (*)(uint32);
typedef void (CPU::*alu_funcpr)(void);
/* OPCODEs for R3000 */
#define OP_SPECIAL 0
#define OP_BCOND 1
#define OP_J 2
#define OP_JAL 3
#define OP_BEQ 4
#define OP_BNE 5
#define OP_BLEZ 6
#define OP_BGTZ 7
#define OP_ADDI 8
#define OP_ADDIU 9
#define OP_SLTI 10
#define OP_SLTIU 11
#define OP_ANDI 12
#define OP_ORI 13
#define OP_XORI 14
#define OP_LUI 15
#define OP_COP0 16
#define OP_COP1 17
#define OP_COP2 18
#define OP_COP3 19
/* OPCODE 20~31 are reserved */
#define OP_LB 32
#define OP_LH 33
#define OP_LWL 34
#define OP_LW 35
#define OP_LBU 36
#define OP_LHU 37
#define OP_LWR 38
/* OPCODE 39 is reserved */
#define OP_SB 40
#define OP_SH 41
#define OP_SWL 42
#define OP_SW 43
#define OP_SWR 46
#define OP_CACHE 47
/* OPCODE 44,45 are reserved */
#define OP_LWC0 48
#define OP_LWC1 49
#define OP_LWC2 50
#define OP_LWC3 51
/* OPCODE 52~55 are reserved */
#define OP_SWC0 56
#define OP_SWC1 57
#define OP_SWC2 58
#define OP_SWC3 59
/* OPCODE 60~63 are reserved*/
/* Funct Code for SPECIAL */
#define FUNCT_SLL 0
#define FUNCT_SRL 2
#define FUNCT_SRA 3
#define FUNCT_SLLV 4
#define FUNCT_SRLV 6
#define FUNCT_SRAV 7
/* FUNCT 1 and 5 are reserved */
#define FUNCT_JR 8
#define FUNCT_JALR 9
#define FUNCT_SYSCALL 12
#define FUNCT_BREAK 13
/* FUNCT 10,11,14,15 are reserved */
#define FUNCT_MFHI 16
#define FUNCT_MTHI 17
#define FUNCT_MFLO 18
#define FUNCT_MTLO 19
/* FUNCT 20~23 are reserved */
#define FUNCT_MULT 24
#define FUNCT_MULTU 25
#define FUNCT_DIV 26
#define FUNCT_DIVU 27
/* FUNCT 28~31 are reserved */
#define FUNCT_ADD 32
#define FUNCT_ADDU 33
#define FUNCT_SUB 34
#define FUNCT_SUBU 35
#define FUNCT_AND 36
#define FUNCT_OR 37
#define FUNCT_XOR 38
#define FUNCT_NOR 39
#define FUNCT_SLT 42
#define FUNCT_SLTU 43
/* FUNCT 40,41, 44~63 are reserved */
/* FUNCT for CP0 OP (rs > 15) */
#define FUNCT_TLBR 1
#define FUNCT_TLBWI 2
#define FUNCT_TLBWR 6
#define FUNCT_TLBP 8
#define FUNCT_RFE 16
/* BCOND TYPE */
#define BCOND_BLTZ 0
#define BCOND_BGEZ 1
#define BCONDE_BLTZAL 16
#define BCONDE_BGEZAL 17
/* OPCODEs for CP OP (rs) (rs < 16) */
#define COP_OP_MFC 0
#define COP_OP_MTC 4
#define COP_OP_BC 8
/* for CP OP Branch (rt)*/
#define COP_BCF 0
#define COP_BCT 1
static operand_decodepr firstSrcDecSpecialTable[64] = {
CPU::rt, CPU::no_reg, CPU::rt, CPU::rt, CPU::rt, CPU::no_reg, CPU::rt, CPU::rt,
CPU::rs, CPU::rs, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::no_reg, CPU::rd, CPU::no_reg, CPU::rd, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::rs, CPU::rs, CPU::rs, CPU::rs, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::rs, CPU::rs, CPU::rs, CPU::rs, CPU::rs, CPU::rs, CPU::rs, CPU::rs,
CPU::no_reg, CPU::no_reg, CPU::rs, CPU::rs, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg
};
static operand_decodepr firstSrcDecBcondTable[32] = {
CPU::rs, CPU::rs, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::rs, CPU::rs, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg
};
static operand_decodepr firstSrcDecTable[64] = {
NULL, NULL, CPU::no_reg, CPU::no_reg, CPU::rs, CPU::rs, CPU::rs, CPU::rs,
CPU::rs, CPU::rs, CPU::rs, CPU::rs, CPU::rs, CPU::rs, CPU::rs, CPU::no_reg,
NULL, NULL, NULL, NULL, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::rs, CPU::rs, CPU::rs, CPU::rs, CPU::rs, CPU::rs, CPU::rs,CPU::no_reg,
CPU::rs, CPU::rs, CPU::rs, CPU::rs,CPU::no_reg,CPU::no_reg, CPU::rs, CPU::rs,
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg
};
static operand_decodepr secondSrcDecSpecialTable[64] = {
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::rs, CPU::no_reg, CPU::rs, CPU::rs,
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::rt, CPU::rt, CPU::rt, CPU::rt, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::rt, CPU::rt, CPU::rt, CPU::rt, CPU::rt, CPU::rt, CPU::rt, CPU::rt,
CPU::no_reg, CPU::no_reg, CPU::rt, CPU::rt, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg
};
static operand_decodepr secondSrcDecTable[64] = {
NULL, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::rt, CPU::rt, CPU::no_reg, CPU::no_reg,
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg
};
static operand_decodepr dstDecSpecialTable[64] = {
CPU::rd, CPU::no_reg, CPU::rd, CPU::rd, CPU::rd, CPU::no_reg, CPU::rd, CPU::rd,
CPU::no_reg, CPU::ra_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::rd, CPU::no_reg, CPU::rd, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::rd, CPU::rd, CPU::rd, CPU::rd, CPU::rd, CPU::rd, CPU::rd, CPU::rd,
CPU::no_reg, CPU::no_reg, CPU::rd, CPU::rd, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg
};
static operand_decodepr dstDecTable[64] = {
NULL, CPU::no_reg, CPU::no_reg, CPU::ra_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::rt, CPU::rt, CPU::rt, CPU::rt, CPU::rt, CPU::rt, CPU::rt, CPU::rt,
NULL, NULL, NULL, NULL, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::rt, CPU::rt, CPU::rt, CPU::rt, CPU::rt, CPU::rt, CPU::rt, CPU::no_reg,
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg,
CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg, CPU::no_reg
};
//indexed by funct
//flag of using shamt
static bool shamt_flag[64] = {
true , false, true , true , false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false
};
//indexed by opcode
//flag of signed imm
static bool s_imm_flag[64] = {
false, true , false, false, true , true , true , true ,
true , true , true , true , false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
true , true , true , true , true , true , true , false,
true , true , true , true , false, false, true , false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false
};
//indexed by opcode
//flag of unsigned imm
static bool imm_flag[64] = {
false, false, false, false, false, false, false, false,
false, false, false, false, true , true , true , true ,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false
};
//indexed by opcode
//flag of mem write
static bool mem_write_flag[64] = {
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
true , true , true , true , false, false, true , false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false
};
//indexed by opcode
//flag of mem read
static bool mem_read_flag[64] = {
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
true , true , true , true , true , true , true , false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false
};
//Reserved Instruction Table
//indexed by opcode
static bool RI_flag[64] = {
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, true , true , true , true ,
true , true , true , true , true , true , true , true ,
false, false, false, false, false, false, false, true ,
false, false, false, false, true , true , false, false ,
false, false, false, false, true , true , true , true ,
false, false, false, false, true , true , true , true
};
//indexed by funct
static bool RI_special_flag[64] = {
false, true , false, false, false, true , false, false,
false, false, true , true , false, false, true , true ,
false, false, false, false, true , true , true , true ,
false, false, false, false, true , true , true , true ,
false, false, false, false, false, false, false, false,
true , true , false, false, true , true , true , true ,
true , true , true , true , true , true , true , true ,
true , true , true , true , true , true , true , true
};
//indexed by cache op operand (rt)
static bool RI_cache_op_flag[32] = {
true, false, true, true, false, false, true, true,
true, false, true, true, true, true, true, true,
true, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false
};
//indexed by funct
static bool mul_div_flag[64] = {
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
true , true , true , true , false, false, false, false,
true , true , true , true , false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false
};
std::map<int, int> mul_div_delay = {
{FUNCT_MTLO, 2}, //at WB stage
{FUNCT_MTHI, 2}, //at WB stage
{FUNCT_MULTU, 3},
{FUNCT_MULT, 3},
{FUNCT_DIV, 9},
{FUNCT_DIVU, 9}
};
#define CPZERO_OP_SUSPEND 5
//indexed by opcode
static bool cop_flag[64] = {
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
true , true , true , true , false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false
};