decoder.isa revision 11723
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
37decode 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}
333