decoder.isa revision 11724
12086SN/A// -*- mode:c++ -*-
22086SN/A
32086SN/A// Copyright (c) 2015 RISC-V Foundation
42086SN/A// Copyright (c) 2016 The University of Virginia
52086SN/A// All rights reserved.
62086SN/A//
72086SN/A// Redistribution and use in source and binary forms, with or without
82086SN/A// modification, are permitted provided that the following conditions are
92086SN/A// met: redistributions of source code must retain the above copyright
102086SN/A// notice, this list of conditions and the following disclaimer;
112086SN/A// redistributions in binary form must reproduce the above copyright
122086SN/A// notice, this list of conditions and the following disclaimer in the
132086SN/A// documentation and/or other materials provided with the distribution;
142086SN/A// neither the name of the copyright holders nor the names of its
152086SN/A// contributors may be used to endorse or promote products derived from
162086SN/A// this software without specific prior written permission.
172086SN/A//
182086SN/A// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
192086SN/A// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
202086SN/A// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
212086SN/A// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
222086SN/A// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
232086SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
242086SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
252086SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
262086SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
272086SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
282665Ssaidi@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
292665Ssaidi@eecs.umich.edu//
302665Ssaidi@eecs.umich.edu// Authors: Alec Roelke
312086SN/A
324202Sbinkertn@umich.edu////////////////////////////////////////////////////////////////////
332086SN/A//
344202Sbinkertn@umich.edu// The RISC-V ISA decoder
354202Sbinkertn@umich.edu//
369022Sgblack@eecs.umich.edu
374202Sbinkertn@umich.edudecode OPCODE default Unknown::unknown() {
388745Sgblack@eecs.umich.edu    0x03: decode FUNCT3 {
396313Sgblack@eecs.umich.edu        format Load {
408778Sgblack@eecs.umich.edu            0x0: lb({{
418778Sgblack@eecs.umich.edu                Rd_sd = Mem_sb;
428778Sgblack@eecs.umich.edu            }});
436365Sgblack@eecs.umich.edu            0x1: lh({{
444997Sgblack@eecs.umich.edu                Rd_sd = Mem_sh;
458778Sgblack@eecs.umich.edu            }});
464202Sbinkertn@umich.edu            0x2: lw({{
478778Sgblack@eecs.umich.edu                Rd_sd = Mem_sw;
488778Sgblack@eecs.umich.edu            }});
498778Sgblack@eecs.umich.edu            0x3: ld({{
504997Sgblack@eecs.umich.edu                Rd_sd = Mem_sd;
518747Sgblack@eecs.umich.edu            }});
524826Ssaidi@eecs.umich.edu            0x4: lbu({{
538760Sgblack@eecs.umich.edu                Rd = Mem_ub;
542086SN/A            }});
558745Sgblack@eecs.umich.edu            0x5: lhu({{
569384SAndreas.Sandberg@arm.com                Rd = Mem_uh;
576365Sgblack@eecs.umich.edu            }});
588778Sgblack@eecs.umich.edu            0x6: lwu({{
598745Sgblack@eecs.umich.edu                Rd = Mem_uw;
606365Sgblack@eecs.umich.edu            }});
618335Snate@binkert.org        }
628335Snate@binkert.org    }
634997Sgblack@eecs.umich.edu
6410196SCurtis.Dunham@arm.com    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                0x1: mul({{
154                    Rd = Rs1_sd*Rs2_sd;
155                }}, IntMultOp);
156                0x20: sub({{
157                    Rd = Rs1_sd - Rs2_sd;
158                }});
159            }
160            0x1: decode FUNCT7 {
161                0x0: sll({{
162                    Rd = Rs1 << Rs2<5:0>;
163                }});
164                0x1: mulh({{
165                    bool negate = (Rs1_sd < 0) != (Rs2_sd < 0);
166
167                    uint64_t Rs1_lo = (uint32_t)std::abs(Rs1_sd);
168                    uint64_t Rs1_hi = (uint64_t)std::abs(Rs1_sd) >> 32;
169                    uint64_t Rs2_lo = (uint32_t)std::abs(Rs2_sd);
170                    uint64_t Rs2_hi = (uint64_t)std::abs(Rs2_sd) >> 32;
171
172                    uint64_t hi = Rs1_hi*Rs2_hi;
173                    uint64_t mid1 = Rs1_hi*Rs2_lo;
174                    uint64_t mid2 = Rs1_lo*Rs2_hi;
175                    uint64_t lo = Rs2_lo*Rs1_lo;
176                    uint64_t carry = ((uint64_t)(uint32_t)mid1
177                            + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
178
179                    uint64_t res = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
180                    Rd = negate ? ~res + (Rs1_sd*Rs2_sd == 0 ? 1 : 0) : res;
181                }}, IntMultOp);
182            }
183            0x2: decode FUNCT7 {
184                0x0: slt({{
185                    Rd = (Rs1_sd < Rs2_sd) ? 1 : 0;
186                }});
187                0x1: mulhsu({{
188                    bool negate = Rs1_sd < 0;
189                    uint64_t Rs1_lo = (uint32_t)std::abs(Rs1_sd);
190                    uint64_t Rs1_hi = (uint64_t)std::abs(Rs1_sd) >> 32;
191                    uint64_t Rs2_lo = (uint32_t)Rs2;
192                    uint64_t Rs2_hi = Rs2 >> 32;
193
194                    uint64_t hi = Rs1_hi*Rs2_hi;
195                    uint64_t mid1 = Rs1_hi*Rs2_lo;
196                    uint64_t mid2 = Rs1_lo*Rs2_hi;
197                    uint64_t lo = Rs1_lo*Rs2_lo;
198                    uint64_t carry = ((uint64_t)(uint32_t)mid1
199                            + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
200
201                    uint64_t res = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
202                    Rd = negate ? ~res + (Rs1_sd*Rs2 == 0 ? 1 : 0) : res;
203                }}, IntMultOp);
204            }
205            0x3: decode FUNCT7 {
206                0x0: sltu({{
207                    Rd = (Rs1 < Rs2) ? 1 : 0;
208                }});
209                0x1: mulhu({{
210                    uint64_t Rs1_lo = (uint32_t)Rs1;
211                    uint64_t Rs1_hi = Rs1 >> 32;
212                    uint64_t Rs2_lo = (uint32_t)Rs2;
213                    uint64_t Rs2_hi = Rs2 >> 32;
214
215                    uint64_t hi = Rs1_hi*Rs2_hi;
216                    uint64_t mid1 = Rs1_hi*Rs2_lo;
217                    uint64_t mid2 = Rs1_lo*Rs2_hi;
218                    uint64_t lo = Rs1_lo*Rs2_lo;
219                    uint64_t carry = ((uint64_t)(uint32_t)mid1
220                            + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
221
222                    Rd = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
223                }}, IntMultOp);
224            }
225            0x4: decode FUNCT7 {
226                0x0: xor({{
227                    Rd = Rs1 ^ Rs2;
228                }});
229                0x1: div({{
230                    if (Rs2_sd == 0) {
231                        Rd_sd = -1;
232                    } else if (Rs1_sd == std::numeric_limits<int64_t>::min()
233                            && Rs2_sd == -1) {
234                        Rd_sd = std::numeric_limits<int64_t>::min();
235                    } else {
236                        Rd_sd = Rs1_sd/Rs2_sd;
237                    }
238                }}, IntDivOp);
239            }
240            0x5: decode FUNCT7 {
241                0x0: srl({{
242                    Rd = Rs1 >> Rs2<5:0>;
243                }});
244                0x1: divu({{
245                    if (Rs2 == 0) {
246                        Rd = std::numeric_limits<uint64_t>::max();
247                    } else {
248                        Rd = Rs1/Rs2;
249                    }
250                }}, IntDivOp);
251                0x20: sra({{
252                    Rd_sd = Rs1_sd >> Rs2<5:0>;
253                }});
254            }
255            0x6: decode FUNCT7 {
256                0x0: or({{
257                    Rd = Rs1 | Rs2;
258                }});
259                0x1: rem({{
260                    if (Rs2_sd == 0) {
261                        Rd = Rs1_sd;
262                    } else if (Rs1_sd == std::numeric_limits<int64_t>::min()
263                            && Rs2_sd == -1) {
264                        Rd = 0;
265                    } else {
266                        Rd = Rs1_sd%Rs2_sd;
267                    }
268                }}, IntDivOp);
269            }
270            0x7: decode FUNCT7 {
271                0x0: and({{
272                    Rd = Rs1 & Rs2;
273                }});
274                0x1: remu({{
275                    if (Rs2 == 0) {
276                        Rd = Rs1;
277                    } else {
278                        Rd = Rs1%Rs2;
279                    }
280                }}, IntDivOp);
281            }
282        }
283    }
284
285    0x37: UOp::lui({{
286        Rd = (uint64_t)imm;
287    }});
288
289    0x3b: decode FUNCT3 {
290        format ROp {
291            0x0: decode FUNCT7 {
292                0x0: addw({{
293                    Rd_sd = Rs1_sw + Rs2_sw;
294                }});
295                0x1: mulw({{
296                    Rd_sd = (int32_t)(Rs1_sw*Rs2_sw);
297                }}, IntMultOp);
298                0x20: subw({{
299                    Rd_sd = Rs1_sw - Rs2_sw;
300                }});
301            }
302            0x1: sllw({{
303                Rd_sd = Rs1_sw << Rs2<4:0>;
304            }});
305            0x4: divw({{
306                if (Rs2_sw == 0) {
307                    Rd_sd = -1;
308                } else if (Rs1_sw == std::numeric_limits<int32_t>::min()
309                        && Rs2_sw == -1) {
310                    Rd_sd = std::numeric_limits<int32_t>::min();
311                } else {
312                    Rd_sd = Rs1_sw/Rs2_sw;
313                }
314            }}, IntDivOp);
315            0x5: decode FUNCT7 {
316                0x0: srlw({{
317                    Rd_uw = Rs1_uw >> Rs2<4:0>;
318                }});
319                0x1: divuw({{
320                    if (Rs2_uw == 0) {
321                        Rd_sd = std::numeric_limits<IntReg>::max();
322                    } else {
323                        Rd_sd = (int32_t)(Rs1_uw/Rs2_uw);
324                    }
325                }}, IntDivOp);
326                0x20: sraw({{
327                    Rd_sd = Rs1_sw >> Rs2<4:0>;
328                }});
329            }
330            0x6: remw({{
331                if (Rs2_sw == 0) {
332                    Rd_sd = Rs1_sw;
333                } else if (Rs1_sw == std::numeric_limits<int32_t>::min()
334                        && Rs2_sw == -1) {
335                    Rd_sd = 0;
336                } else {
337                    Rd_sd = Rs1_sw%Rs2_sw;
338                }
339            }}, IntDivOp);
340            0x7: remuw({{
341                if (Rs2_uw == 0) {
342                    Rd_sd = (int32_t)Rs1_uw;
343                } else {
344                    Rd_sd = (int32_t)(Rs1_uw%Rs2_uw);
345                }
346            }}, IntDivOp);
347        }
348    }
349
350    0x63: decode FUNCT3 {
351        format SBOp {
352            0x0: beq({{
353                if (Rs1 == Rs2) {
354                    NPC = PC + imm;
355                } else {
356                    NPC = NPC;
357                }
358            }}, IsDirectControl, IsCondControl);
359            0x1: bne({{
360                if (Rs1 != Rs2) {
361                    NPC = PC + imm;
362                } else {
363                    NPC = NPC;
364                }
365            }}, IsDirectControl, IsCondControl);
366            0x4: blt({{
367                if (Rs1_sd < Rs2_sd) {
368                    NPC = PC + imm;
369                } else {
370                    NPC = NPC;
371                }
372            }}, IsDirectControl, IsCondControl);
373            0x5: bge({{
374                if (Rs1_sd >= Rs2_sd) {
375                    NPC = PC + imm;
376                } else {
377                    NPC = NPC;
378                }
379            }}, IsDirectControl, IsCondControl);
380            0x6: bltu({{
381                if (Rs1 < Rs2) {
382                    NPC = PC + imm;
383                } else {
384                    NPC = NPC;
385                }
386            }}, IsDirectControl, IsCondControl);
387            0x7: bgeu({{
388                if (Rs1 >= Rs2) {
389                    NPC = PC + imm;
390                } else {
391                    NPC = NPC;
392                }
393            }}, IsDirectControl, IsCondControl);
394        }
395    }
396
397    0x67: decode FUNCT3 {
398        0x0: Jump::jalr({{
399            Rd = NPC;
400            NPC = (imm + Rs1) & (~0x1);
401        }}, IsIndirectControl, IsUncondControl, IsCall);
402    }
403
404    0x6f: UJOp::jal({{
405        Rd = NPC;
406        NPC = PC + imm;
407    }}, IsDirectControl, IsUncondControl, IsCall);
408
409    0x73: decode FUNCT3 {
410        format IOp {
411            0x0: decode FUNCT12 {
412                0x0: ecall({{
413                    fault = std::make_shared<SyscallFault>();
414                }}, IsSerializeAfter, IsNonSpeculative, IsSyscall, No_OpClass);
415                0x1: ebreak({{
416                    fault = std::make_shared<BreakpointFault>();
417                }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
418                0x100: eret({{
419                    fault = std::make_shared<UnimplementedFault>("eret");
420                }}, No_OpClass);
421            }
422            0x1: csrrw({{
423                Rd = xc->readMiscReg(FUNCT12);
424                xc->setMiscReg(FUNCT12, Rs1);
425            }}, IsNonSpeculative, No_OpClass);
426            0x2: csrrs({{
427                Rd = xc->readMiscReg(FUNCT12);
428                if (Rs1 != 0) {
429                    xc->setMiscReg(FUNCT12, Rd | Rs1);
430                }
431            }}, IsNonSpeculative, No_OpClass);
432            0x3: csrrc({{
433                Rd = xc->readMiscReg(FUNCT12);
434                if (Rs1 != 0) {
435                    xc->setMiscReg(FUNCT12, Rd & ~Rs1);
436                }
437            }}, IsNonSpeculative, No_OpClass);
438            0x5: csrrwi({{
439                Rd = xc->readMiscReg(FUNCT12);
440                xc->setMiscReg(FUNCT12, ZIMM);
441            }}, IsNonSpeculative, No_OpClass);
442            0x6: csrrsi({{
443                Rd = xc->readMiscReg(FUNCT12);
444                if (ZIMM != 0) {
445                    xc->setMiscReg(FUNCT12, Rd | ZIMM);
446                }
447            }}, IsNonSpeculative, No_OpClass);
448            0x7: csrrci({{
449                Rd = xc->readMiscReg(FUNCT12);
450                if (ZIMM != 0) {
451                    xc->setMiscReg(FUNCT12, Rd & ~ZIMM);
452                }
453            }}, IsNonSpeculative, No_OpClass);
454        }
455    }
456}
457