arch: [Patch 1/5] Added RISC-V base instruction set RV64I
[gem5.git] / src / arch / riscv / isa / decoder.isa
1 // -*- mode:c++ -*-
2
3 // Copyright (c) 2015 RISC-V Foundation
4 // Copyright (c) 2016 The University of Virginia
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are
9 // met: redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer;
11 // redistributions in binary form must reproduce the above copyright
12 // notice, this list of conditions and the following disclaimer in the
13 // documentation and/or other materials provided with the distribution;
14 // neither the name of the copyright holders nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // Authors: Alec Roelke
31
32 ////////////////////////////////////////////////////////////////////
33 //
34 // The RISC-V ISA decoder
35 //
36
37 decode OPCODE default Unknown::unknown() {
38 0x03: decode FUNCT3 {
39 format Load {
40 0x0: lb({{
41 Rd_sd = Mem_sb;
42 }});
43 0x1: lh({{
44 Rd_sd = Mem_sh;
45 }});
46 0x2: lw({{
47 Rd_sd = Mem_sw;
48 }});
49 0x3: ld({{
50 Rd_sd = Mem_sd;
51 }});
52 0x4: lbu({{
53 Rd = Mem_ub;
54 }});
55 0x5: lhu({{
56 Rd = Mem_uh;
57 }});
58 0x6: lwu({{
59 Rd = Mem_uw;
60 }});
61 }
62 }
63
64 0x0f: decode FUNCT3 {
65 format IOp {
66 0x0: fence({{
67 }}, IsNonSpeculative, IsMemBarrier, No_OpClass);
68 0x1: fence_i({{
69 }}, IsNonSpeculative, IsSerializeAfter, No_OpClass);
70 }
71 }
72
73 0x13: decode FUNCT3 {
74 format IOp {
75 0x0: addi({{
76 Rd_sd = Rs1_sd + imm;
77 }});
78 0x1: slli({{
79 Rd = Rs1 << SHAMT6;
80 }});
81 0x2: slti({{
82 Rd = (Rs1_sd < imm) ? 1 : 0;
83 }});
84 0x3: sltiu({{
85 Rd = (Rs1 < (uint64_t)imm) ? 1 : 0;
86 }});
87 0x4: xori({{
88 Rd = Rs1 ^ (uint64_t)imm;
89 }});
90 0x5: decode SRTYPE {
91 0x0: srli({{
92 Rd = Rs1 >> SHAMT6;
93 }});
94 0x1: srai({{
95 Rd_sd = Rs1_sd >> SHAMT6;
96 }});
97 }
98 0x6: ori({{
99 Rd = Rs1 | (uint64_t)imm;
100 }});
101 0x7: andi({{
102 Rd = Rs1 & (uint64_t)imm;
103 }});
104 }
105 }
106
107 0x17: UOp::auipc({{
108 Rd = PC + imm;
109 }});
110
111 0x1b: decode FUNCT3 {
112 format IOp {
113 0x0: addiw({{
114 Rd_sd = (int32_t)Rs1 + (int32_t)imm;
115 }});
116 0x1: slliw({{
117 Rd_sd = Rs1_sw << SHAMT5;
118 }});
119 0x5: decode SRTYPE {
120 0x0: srliw({{
121 Rd = Rs1_uw >> SHAMT5;
122 }});
123 0x1: sraiw({{
124 Rd_sd = Rs1_sw >> SHAMT5;
125 }});
126 }
127 }
128 }
129
130 0x23: decode FUNCT3 {
131 format Store {
132 0x0: sb({{
133 Mem_ub = Rs2_ub;
134 }});
135 0x1: sh({{
136 Mem_uh = Rs2_uh;
137 }});
138 0x2: sw({{
139 Mem_uw = Rs2_uw;
140 }});
141 0x3: sd({{
142 Mem_ud = Rs2_ud;
143 }});
144 }
145 }
146
147 0x33: decode FUNCT3 {
148 format ROp {
149 0x0: decode FUNCT7 {
150 0x0: add({{
151 Rd = Rs1_sd + Rs2_sd;
152 }});
153 0x20: sub({{
154 Rd = Rs1_sd - Rs2_sd;
155 }});
156 }
157 0x1: decode FUNCT7 {
158 0x0: sll({{
159 Rd = Rs1 << Rs2<5:0>;
160 }});
161 }
162 0x2: decode FUNCT7 {
163 0x0: slt({{
164 Rd = (Rs1_sd < Rs2_sd) ? 1 : 0;
165 }});
166 }
167 0x3: decode FUNCT7 {
168 0x0: sltu({{
169 Rd = (Rs1 < Rs2) ? 1 : 0;
170 }});
171 }
172 0x4: decode FUNCT7 {
173 0x0: xor({{
174 Rd = Rs1 ^ Rs2;
175 }});
176 }
177 0x5: decode FUNCT7 {
178 0x0: srl({{
179 Rd = Rs1 >> Rs2<5:0>;
180 }});
181 0x20: sra({{
182 Rd_sd = Rs1_sd >> Rs2<5:0>;
183 }});
184 }
185 0x6: decode FUNCT7 {
186 0x0: or({{
187 Rd = Rs1 | Rs2;
188 }});
189 }
190 0x7: decode FUNCT7 {
191 0x0: and({{
192 Rd = Rs1 & Rs2;
193 }});
194 }
195 }
196 }
197
198 0x37: UOp::lui({{
199 Rd = (uint64_t)imm;
200 }});
201
202 0x3b: decode FUNCT3 {
203 format ROp {
204 0x0: decode FUNCT7 {
205 0x0: addw({{
206 Rd_sd = Rs1_sw + Rs2_sw;
207 }});
208 0x20: subw({{
209 Rd_sd = Rs1_sw - Rs2_sw;
210 }});
211 }
212 0x1: sllw({{
213 Rd_sd = Rs1_sw << Rs2<4:0>;
214 }});
215 0x5: decode FUNCT7 {
216 0x0: srlw({{
217 Rd_uw = Rs1_uw >> Rs2<4:0>;
218 }});
219 0x20: sraw({{
220 Rd_sd = Rs1_sw >> Rs2<4:0>;
221 }});
222 }
223 }
224 }
225
226 0x63: decode FUNCT3 {
227 format SBOp {
228 0x0: beq({{
229 if (Rs1 == Rs2) {
230 NPC = PC + imm;
231 } else {
232 NPC = NPC;
233 }
234 }}, IsDirectControl, IsCondControl);
235 0x1: bne({{
236 if (Rs1 != Rs2) {
237 NPC = PC + imm;
238 } else {
239 NPC = NPC;
240 }
241 }}, IsDirectControl, IsCondControl);
242 0x4: blt({{
243 if (Rs1_sd < Rs2_sd) {
244 NPC = PC + imm;
245 } else {
246 NPC = NPC;
247 }
248 }}, IsDirectControl, IsCondControl);
249 0x5: bge({{
250 if (Rs1_sd >= Rs2_sd) {
251 NPC = PC + imm;
252 } else {
253 NPC = NPC;
254 }
255 }}, IsDirectControl, IsCondControl);
256 0x6: bltu({{
257 if (Rs1 < Rs2) {
258 NPC = PC + imm;
259 } else {
260 NPC = NPC;
261 }
262 }}, IsDirectControl, IsCondControl);
263 0x7: bgeu({{
264 if (Rs1 >= Rs2) {
265 NPC = PC + imm;
266 } else {
267 NPC = NPC;
268 }
269 }}, IsDirectControl, IsCondControl);
270 }
271 }
272
273 0x67: decode FUNCT3 {
274 0x0: Jump::jalr({{
275 Rd = NPC;
276 NPC = (imm + Rs1) & (~0x1);
277 }}, IsIndirectControl, IsUncondControl, IsCall);
278 }
279
280 0x6f: UJOp::jal({{
281 Rd = NPC;
282 NPC = PC + imm;
283 }}, IsDirectControl, IsUncondControl, IsCall);
284
285 0x73: decode FUNCT3 {
286 format IOp {
287 0x0: decode FUNCT12 {
288 0x0: ecall({{
289 fault = std::make_shared<SyscallFault>();
290 }}, IsSerializeAfter, IsNonSpeculative, IsSyscall, No_OpClass);
291 0x1: ebreak({{
292 fault = std::make_shared<BreakpointFault>();
293 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
294 0x100: eret({{
295 fault = std::make_shared<UnimplementedFault>("eret");
296 }}, No_OpClass);
297 }
298 0x1: csrrw({{
299 Rd = xc->readMiscReg(FUNCT12);
300 xc->setMiscReg(FUNCT12, Rs1);
301 }}, IsNonSpeculative, No_OpClass);
302 0x2: csrrs({{
303 Rd = xc->readMiscReg(FUNCT12);
304 if (Rs1 != 0) {
305 xc->setMiscReg(FUNCT12, Rd | Rs1);
306 }
307 }}, IsNonSpeculative, No_OpClass);
308 0x3: csrrc({{
309 Rd = xc->readMiscReg(FUNCT12);
310 if (Rs1 != 0) {
311 xc->setMiscReg(FUNCT12, Rd & ~Rs1);
312 }
313 }}, IsNonSpeculative, No_OpClass);
314 0x5: csrrwi({{
315 Rd = xc->readMiscReg(FUNCT12);
316 xc->setMiscReg(FUNCT12, ZIMM);
317 }}, IsNonSpeculative, No_OpClass);
318 0x6: csrrsi({{
319 Rd = xc->readMiscReg(FUNCT12);
320 if (ZIMM != 0) {
321 xc->setMiscReg(FUNCT12, Rd | ZIMM);
322 }
323 }}, IsNonSpeculative, No_OpClass);
324 0x7: csrrci({{
325 Rd = xc->readMiscReg(FUNCT12);
326 if (ZIMM != 0) {
327 xc->setMiscReg(FUNCT12, Rd & ~ZIMM);
328 }
329 }}, IsNonSpeculative, No_OpClass);
330 }
331 }
332 }