decoder.isa revision 11725:eb58f1bbeac8
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    0x07: decode FUNCT3 {
65        format Load {
66            0x2: flw({{
67                Fd_bits = (uint64_t)Mem_uw;
68            }});
69            0x3: fld({{
70                Fd_bits = Mem;
71            }});
72        }
73    }
74
75    0x0f: decode FUNCT3 {
76        format IOp {
77            0x0: fence({{
78            }}, IsNonSpeculative, IsMemBarrier, No_OpClass);
79            0x1: fence_i({{
80            }}, IsNonSpeculative, IsSerializeAfter, No_OpClass);
81        }
82    }
83
84    0x13: decode FUNCT3 {
85        format IOp {
86            0x0: addi({{
87                Rd_sd = Rs1_sd + imm;
88            }});
89            0x1: slli({{
90                Rd = Rs1 << SHAMT6;
91            }});
92            0x2: slti({{
93                Rd = (Rs1_sd < imm) ? 1 : 0;
94            }});
95            0x3: sltiu({{
96                Rd = (Rs1 < (uint64_t)imm) ? 1 : 0;
97            }});
98            0x4: xori({{
99                Rd = Rs1 ^ (uint64_t)imm;
100            }});
101            0x5: decode SRTYPE {
102                0x0: srli({{
103                    Rd = Rs1 >> SHAMT6;
104                }});
105                0x1: srai({{
106                    Rd_sd = Rs1_sd >> SHAMT6;
107                }});
108            }
109            0x6: ori({{
110                Rd = Rs1 | (uint64_t)imm;
111            }});
112            0x7: andi({{
113                Rd = Rs1 & (uint64_t)imm;
114            }});
115        }
116    }
117
118    0x17: UOp::auipc({{
119        Rd = PC + imm;
120    }});
121
122    0x1b: decode FUNCT3 {
123        format IOp {
124            0x0: addiw({{
125                Rd_sd = (int32_t)Rs1 + (int32_t)imm;
126            }});
127            0x1: slliw({{
128                Rd_sd = Rs1_sw << SHAMT5;
129            }});
130            0x5: decode SRTYPE {
131                0x0: srliw({{
132                    Rd = Rs1_uw >> SHAMT5;
133                }});
134                0x1: sraiw({{
135                    Rd_sd = Rs1_sw >> SHAMT5;
136                }});
137            }
138        }
139    }
140
141    0x23: decode FUNCT3 {
142        format Store {
143            0x0: sb({{
144                Mem_ub = Rs2_ub;
145            }});
146            0x1: sh({{
147                Mem_uh = Rs2_uh;
148            }});
149            0x2: sw({{
150                Mem_uw = Rs2_uw;
151            }});
152            0x3: sd({{
153                Mem_ud = Rs2_ud;
154            }});
155        }
156    }
157
158    0x27: decode FUNCT3 {
159        format Store {
160            0x2: fsw({{
161                Mem_uw = (uint32_t)Fs2_bits;
162            }});
163            0x3: fsd({{
164                Mem_ud = Fs2_bits;
165            }});
166        }
167    }
168
169    0x33: decode FUNCT3 {
170        format ROp {
171            0x0: decode FUNCT7 {
172                0x0: add({{
173                    Rd = Rs1_sd + Rs2_sd;
174                }});
175                0x1: mul({{
176                    Rd = Rs1_sd*Rs2_sd;
177                }}, IntMultOp);
178                0x20: sub({{
179                    Rd = Rs1_sd - Rs2_sd;
180                }});
181            }
182            0x1: decode FUNCT7 {
183                0x0: sll({{
184                    Rd = Rs1 << Rs2<5:0>;
185                }});
186                0x1: mulh({{
187                    bool negate = (Rs1_sd < 0) != (Rs2_sd < 0);
188
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)std::abs(Rs2_sd);
192                    uint64_t Rs2_hi = (uint64_t)std::abs(Rs2_sd) >> 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 = Rs2_lo*Rs1_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_sd == 0 ? 1 : 0) : res;
203                }}, IntMultOp);
204            }
205            0x2: decode FUNCT7 {
206                0x0: slt({{
207                    Rd = (Rs1_sd < Rs2_sd) ? 1 : 0;
208                }});
209                0x1: mulhsu({{
210                    bool negate = Rs1_sd < 0;
211                    uint64_t Rs1_lo = (uint32_t)std::abs(Rs1_sd);
212                    uint64_t Rs1_hi = (uint64_t)std::abs(Rs1_sd) >> 32;
213                    uint64_t Rs2_lo = (uint32_t)Rs2;
214                    uint64_t Rs2_hi = Rs2 >> 32;
215
216                    uint64_t hi = Rs1_hi*Rs2_hi;
217                    uint64_t mid1 = Rs1_hi*Rs2_lo;
218                    uint64_t mid2 = Rs1_lo*Rs2_hi;
219                    uint64_t lo = Rs1_lo*Rs2_lo;
220                    uint64_t carry = ((uint64_t)(uint32_t)mid1
221                            + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
222
223                    uint64_t res = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
224                    Rd = negate ? ~res + (Rs1_sd*Rs2 == 0 ? 1 : 0) : res;
225                }}, IntMultOp);
226            }
227            0x3: decode FUNCT7 {
228                0x0: sltu({{
229                    Rd = (Rs1 < Rs2) ? 1 : 0;
230                }});
231                0x1: mulhu({{
232                    uint64_t Rs1_lo = (uint32_t)Rs1;
233                    uint64_t Rs1_hi = Rs1 >> 32;
234                    uint64_t Rs2_lo = (uint32_t)Rs2;
235                    uint64_t Rs2_hi = Rs2 >> 32;
236
237                    uint64_t hi = Rs1_hi*Rs2_hi;
238                    uint64_t mid1 = Rs1_hi*Rs2_lo;
239                    uint64_t mid2 = Rs1_lo*Rs2_hi;
240                    uint64_t lo = Rs1_lo*Rs2_lo;
241                    uint64_t carry = ((uint64_t)(uint32_t)mid1
242                            + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
243
244                    Rd = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
245                }}, IntMultOp);
246            }
247            0x4: decode FUNCT7 {
248                0x0: xor({{
249                    Rd = Rs1 ^ Rs2;
250                }});
251                0x1: div({{
252                    if (Rs2_sd == 0) {
253                        Rd_sd = -1;
254                    } else if (Rs1_sd == std::numeric_limits<int64_t>::min()
255                            && Rs2_sd == -1) {
256                        Rd_sd = std::numeric_limits<int64_t>::min();
257                    } else {
258                        Rd_sd = Rs1_sd/Rs2_sd;
259                    }
260                }}, IntDivOp);
261            }
262            0x5: decode FUNCT7 {
263                0x0: srl({{
264                    Rd = Rs1 >> Rs2<5:0>;
265                }});
266                0x1: divu({{
267                    if (Rs2 == 0) {
268                        Rd = std::numeric_limits<uint64_t>::max();
269                    } else {
270                        Rd = Rs1/Rs2;
271                    }
272                }}, IntDivOp);
273                0x20: sra({{
274                    Rd_sd = Rs1_sd >> Rs2<5:0>;
275                }});
276            }
277            0x6: decode FUNCT7 {
278                0x0: or({{
279                    Rd = Rs1 | Rs2;
280                }});
281                0x1: rem({{
282                    if (Rs2_sd == 0) {
283                        Rd = Rs1_sd;
284                    } else if (Rs1_sd == std::numeric_limits<int64_t>::min()
285                            && Rs2_sd == -1) {
286                        Rd = 0;
287                    } else {
288                        Rd = Rs1_sd%Rs2_sd;
289                    }
290                }}, IntDivOp);
291            }
292            0x7: decode FUNCT7 {
293                0x0: and({{
294                    Rd = Rs1 & Rs2;
295                }});
296                0x1: remu({{
297                    if (Rs2 == 0) {
298                        Rd = Rs1;
299                    } else {
300                        Rd = Rs1%Rs2;
301                    }
302                }}, IntDivOp);
303            }
304        }
305    }
306
307    0x37: UOp::lui({{
308        Rd = (uint64_t)imm;
309    }});
310
311    0x3b: decode FUNCT3 {
312        format ROp {
313            0x0: decode FUNCT7 {
314                0x0: addw({{
315                    Rd_sd = Rs1_sw + Rs2_sw;
316                }});
317                0x1: mulw({{
318                    Rd_sd = (int32_t)(Rs1_sw*Rs2_sw);
319                }}, IntMultOp);
320                0x20: subw({{
321                    Rd_sd = Rs1_sw - Rs2_sw;
322                }});
323            }
324            0x1: sllw({{
325                Rd_sd = Rs1_sw << Rs2<4:0>;
326            }});
327            0x4: divw({{
328                if (Rs2_sw == 0) {
329                    Rd_sd = -1;
330                } else if (Rs1_sw == std::numeric_limits<int32_t>::min()
331                        && Rs2_sw == -1) {
332                    Rd_sd = std::numeric_limits<int32_t>::min();
333                } else {
334                    Rd_sd = Rs1_sw/Rs2_sw;
335                }
336            }}, IntDivOp);
337            0x5: decode FUNCT7 {
338                0x0: srlw({{
339                    Rd_uw = Rs1_uw >> Rs2<4:0>;
340                }});
341                0x1: divuw({{
342                    if (Rs2_uw == 0) {
343                        Rd_sd = std::numeric_limits<IntReg>::max();
344                    } else {
345                        Rd_sd = (int32_t)(Rs1_uw/Rs2_uw);
346                    }
347                }}, IntDivOp);
348                0x20: sraw({{
349                    Rd_sd = Rs1_sw >> Rs2<4:0>;
350                }});
351            }
352            0x6: remw({{
353                if (Rs2_sw == 0) {
354                    Rd_sd = Rs1_sw;
355                } else if (Rs1_sw == std::numeric_limits<int32_t>::min()
356                        && Rs2_sw == -1) {
357                    Rd_sd = 0;
358                } else {
359                    Rd_sd = Rs1_sw%Rs2_sw;
360                }
361            }}, IntDivOp);
362            0x7: remuw({{
363                if (Rs2_uw == 0) {
364                    Rd_sd = (int32_t)Rs1_uw;
365                } else {
366                    Rd_sd = (int32_t)(Rs1_uw%Rs2_uw);
367                }
368            }}, IntDivOp);
369        }
370    }
371
372    format FPR4Op {
373        0x43: decode FUNCT2 {
374            0x0: fmadd_s({{
375                uint32_t temp;
376                float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
377                float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
378                float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
379                float fd;
380
381                if (std::isnan(fs1) || std::isnan(fs2) || std::isnan(fs3)) {
382                    if (issignalingnan(fs1) || issignalingnan(fs2)
383                            || issignalingnan(fs3)) {
384                        FFLAGS |= FloatInvalid;
385                    }
386                    fd = std::numeric_limits<float>::quiet_NaN();
387                } else if (std::isinf(fs1) || std::isinf(fs2) ||
388                        std::isinf(fs3)) {
389                    if (std::signbit(fs1) == std::signbit(fs2)
390                            && !std::isinf(fs3)) {
391                        fd = std::numeric_limits<float>::infinity();
392                    } else if (std::signbit(fs1) != std::signbit(fs2)
393                            && !std::isinf(fs3)) {
394                        fd = -std::numeric_limits<float>::infinity();
395                    } else { // Fs3_sf is infinity
396                        fd = fs3;
397                    }
398                } else {
399                    fd = fs1*fs2 + fs3;
400                }
401                Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
402            }}, FloatMultOp);
403            0x1: fmadd_d({{
404                if (std::isnan(Fs1) || std::isnan(Fs2) || std::isnan(Fs3)) {
405                    if (issignalingnan(Fs1) || issignalingnan(Fs2)
406                            || issignalingnan(Fs3)) {
407                        FFLAGS |= FloatInvalid;
408                    }
409                    Fd = std::numeric_limits<double>::quiet_NaN();
410                } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
411                        std::isinf(Fs3)) {
412                    if (std::signbit(Fs1) == std::signbit(Fs2)
413                            && !std::isinf(Fs3)) {
414                        Fd = std::numeric_limits<double>::infinity();
415                    } else if (std::signbit(Fs1) != std::signbit(Fs2)
416                            && !std::isinf(Fs3)) {
417                        Fd = -std::numeric_limits<double>::infinity();
418                    } else {
419                        Fd = Fs3;
420                    }
421                } else {
422                    Fd = Fs1*Fs2 + Fs3;
423                }
424            }}, FloatMultOp);
425        }
426        0x47: decode FUNCT2 {
427            0x0: fmsub_s({{
428                uint32_t temp;
429                float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
430                float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
431                float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
432                float fd;
433
434                if (std::isnan(fs1) || std::isnan(fs2) || std::isnan(fs3)) {
435                    if (issignalingnan(fs1) || issignalingnan(fs2)
436                            || issignalingnan(fs3)) {
437                        FFLAGS |= FloatInvalid;
438                    }
439                    fd = std::numeric_limits<float>::quiet_NaN();
440                } else if (std::isinf(fs1) || std::isinf(fs2) ||
441                        std::isinf(fs3)) {
442                    if (std::signbit(fs1) == std::signbit(fs2)
443                            && !std::isinf(fs3)) {
444                        fd = std::numeric_limits<float>::infinity();
445                    } else if (std::signbit(fs1) != std::signbit(fs2)
446                            && !std::isinf(fs3)) {
447                        fd = -std::numeric_limits<float>::infinity();
448                    } else { // Fs3_sf is infinity
449                        fd = -fs3;
450                    }
451                } else {
452                    fd = fs1*fs2 - fs3;
453                }
454                Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
455            }}, FloatMultOp);
456            0x1: fmsub_d({{
457                if (std::isnan(Fs1) || std::isnan(Fs2) || std::isnan(Fs3)) {
458                    if (issignalingnan(Fs1) || issignalingnan(Fs2)
459                            || issignalingnan(Fs3)) {
460                        FFLAGS |= FloatInvalid;
461                    }
462                    Fd = std::numeric_limits<double>::quiet_NaN();
463                } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
464                        std::isinf(Fs3)) {
465                    if (std::signbit(Fs1) == std::signbit(Fs2)
466                            && !std::isinf(Fs3)) {
467                        Fd = std::numeric_limits<double>::infinity();
468                    } else if (std::signbit(Fs1) != std::signbit(Fs2)
469                            && !std::isinf(Fs3)) {
470                        Fd = -std::numeric_limits<double>::infinity();
471                    } else {
472                        Fd = -Fs3;
473                    }
474                } else {
475                    Fd = Fs1*Fs2 - Fs3;
476                }
477            }}, FloatMultOp);
478        }
479        0x4b: decode FUNCT2 {
480            0x0: fnmsub_s({{
481                uint32_t temp;
482                float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
483                float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
484                float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
485                float fd;
486
487                if (std::isnan(fs1) || std::isnan(fs2) || std::isnan(fs3)) {
488                    if (issignalingnan(fs1) || issignalingnan(fs2)
489                            || issignalingnan(fs3)) {
490                        FFLAGS |= FloatInvalid;
491                    }
492                    fd = std::numeric_limits<float>::quiet_NaN();
493                } else if (std::isinf(fs1) || std::isinf(fs2) ||
494                        std::isinf(fs3)) {
495                    if (std::signbit(fs1) == std::signbit(fs2)
496                            && !std::isinf(fs3)) {
497                        fd = -std::numeric_limits<float>::infinity();
498                    } else if (std::signbit(fs1) != std::signbit(fs2)
499                            && !std::isinf(fs3)) {
500                        fd = std::numeric_limits<float>::infinity();
501                    } else { // Fs3_sf is infinity
502                        fd = fs3;
503                    }
504                } else {
505                    fd = -(fs1*fs2 - fs3);
506                }
507                Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
508            }}, FloatMultOp);
509            0x1: fnmsub_d({{
510                if (std::isnan(Fs1) || std::isnan(Fs2) || std::isnan(Fs3)) {
511                    if (issignalingnan(Fs1) || issignalingnan(Fs2)
512                            || issignalingnan(Fs3)) {
513                        FFLAGS |= FloatInvalid;
514                    }
515                    Fd = std::numeric_limits<double>::quiet_NaN();
516                } else if (std::isinf(Fs1) || std::isinf(Fs2)
517                        || std::isinf(Fs3)) {
518                    if (std::signbit(Fs1) == std::signbit(Fs2)
519                            && !std::isinf(Fs3)) {
520                        Fd = -std::numeric_limits<double>::infinity();
521                    } else if (std::signbit(Fs1) != std::signbit(Fs2)
522                            && !std::isinf(Fs3)) {
523                        Fd = std::numeric_limits<double>::infinity();
524                    } else {
525                        Fd = Fs3;
526                    }
527                } else {
528                    Fd = -(Fs1*Fs2 - Fs3);
529                }
530            }}, FloatMultOp);
531        }
532        0x4f: decode FUNCT2 {
533            0x0: fnmadd_s({{
534                uint32_t temp;
535                float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
536                float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
537                float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
538                float fd;
539
540                if (std::isnan(fs1) || std::isnan(fs2) || std::isnan(fs3)) {
541                    if (issignalingnan(fs1) || issignalingnan(fs2)
542                            || issignalingnan(fs3)) {
543                        FFLAGS |= FloatInvalid;
544                    }
545                    fd = std::numeric_limits<float>::quiet_NaN();
546                } else if (std::isinf(fs1) || std::isinf(fs2) ||
547                        std::isinf(fs3)) {
548                    if (std::signbit(fs1) == std::signbit(fs2)
549                            && !std::isinf(fs3)) {
550                        fd = -std::numeric_limits<float>::infinity();
551                    } else if (std::signbit(fs1) != std::signbit(fs2)
552                            && !std::isinf(fs3)) {
553                        fd = std::numeric_limits<float>::infinity();
554                    } else { // Fs3_sf is infinity
555                        fd = -fs3;
556                    }
557                } else {
558                    fd = -(fs1*fs2 + fs3);
559                }
560                Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
561            }}, FloatMultOp);
562            0x1: fnmadd_d({{
563                if (std::isnan(Fs1) || std::isnan(Fs2) || std::isnan(Fs3)) {
564                    if (issignalingnan(Fs1) || issignalingnan(Fs2)
565                            || issignalingnan(Fs3)) {
566                        FFLAGS |= FloatInvalid;
567                    }
568                    Fd = std::numeric_limits<double>::quiet_NaN();
569                } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
570                        std::isinf(Fs3)) {
571                    if (std::signbit(Fs1) == std::signbit(Fs2)
572                            && !std::isinf(Fs3)) {
573                        Fd = -std::numeric_limits<double>::infinity();
574                    } else if (std::signbit(Fs1) != std::signbit(Fs2)
575                            && !std::isinf(Fs3)) {
576                        Fd = std::numeric_limits<double>::infinity();
577                    } else {
578                        Fd = -Fs3;
579                    }
580                } else {
581                    Fd = -(Fs1*Fs2 + Fs3);
582                }
583            }}, FloatMultOp);
584        }
585    }
586
587    0x53: decode FUNCT7 {
588        format FPROp {
589            0x0: fadd_s({{
590                uint32_t temp;
591                float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
592                float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
593                float fd;
594
595                if (std::isnan(fs1) || std::isnan(fs2)) {
596                    if (issignalingnan(fs1) || issignalingnan(fs2)) {
597                        FFLAGS |= FloatInvalid;
598                    }
599                    fd = std::numeric_limits<float>::quiet_NaN();
600                } else {
601                    fd = fs1 + fs2;
602                }
603                Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
604            }}, FloatAddOp);
605            0x1: fadd_d({{
606                if (std::isnan(Fs1) || std::isnan(Fs2)) {
607                    if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
608                        FFLAGS |= FloatInvalid;
609                    }
610                    Fd = std::numeric_limits<double>::quiet_NaN();
611                } else {
612                    Fd = Fs1 + Fs2;
613                }
614            }}, FloatAddOp);
615            0x4: fsub_s({{
616                uint32_t temp;
617                float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
618                float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
619                float fd;
620
621                if (std::isnan(fs1) || std::isnan(fs2)) {
622                    if (issignalingnan(fs1) || issignalingnan(fs2)) {
623                        FFLAGS |= FloatInvalid;
624                    }
625                    fd = std::numeric_limits<float>::quiet_NaN();
626                } else {
627                    fd = fs1 - fs2;
628                }
629                Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
630            }}, FloatAddOp);
631            0x5: fsub_d({{
632                if (std::isnan(Fs1) || std::isnan(Fs2)) {
633                    if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
634                        FFLAGS |= FloatInvalid;
635                    }
636                    Fd = std::numeric_limits<double>::quiet_NaN();
637                } else {
638                    Fd = Fs1 - Fs2;
639                }
640            }}, FloatAddOp);
641            0x8: fmul_s({{
642                uint32_t temp;
643                float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
644                float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
645                float fd;
646
647                if (std::isnan(fs1) || std::isnan(fs2)) {
648                    if (issignalingnan(fs1) || issignalingnan(fs2)) {
649                        FFLAGS |= FloatInvalid;
650                    }
651                    fd = std::numeric_limits<float>::quiet_NaN();
652                } else {
653                    fd = fs1*fs2;
654                }
655                Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
656            }}, FloatMultOp);
657            0x9: fmul_d({{
658                if (std::isnan(Fs1) || std::isnan(Fs2)) {
659                    if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
660                        FFLAGS |= FloatInvalid;
661                    }
662                    Fd = std::numeric_limits<double>::quiet_NaN();
663                } else {
664                    Fd = Fs1*Fs2;
665                }
666            }}, FloatMultOp);
667            0xc: fdiv_s({{
668                uint32_t temp;
669                float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
670                float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
671                float fd;
672
673                if (std::isnan(fs1) || std::isnan(fs2)) {
674                    if (issignalingnan(fs1) || issignalingnan(fs2)) {
675                        FFLAGS |= FloatInvalid;
676                    }
677                    fd = std::numeric_limits<float>::quiet_NaN();
678                } else {
679                    fd = fs1/fs2;
680                }
681                Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
682            }}, FloatDivOp);
683            0xd: fdiv_d({{
684                if (std::isnan(Fs1) || std::isnan(Fs2)) {
685                    if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
686                        FFLAGS |= FloatInvalid;
687                    }
688                    Fd = std::numeric_limits<double>::quiet_NaN();
689                } else {
690                    Fd = Fs1/Fs2;
691                }
692            }}, FloatDivOp);
693            0x10: decode ROUND_MODE {
694                0x0: fsgnj_s({{
695                    uint32_t temp;
696                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
697                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
698                    float fd;
699
700                    if (issignalingnan(fs1)) {
701                        fd = std::numeric_limits<float>::signaling_NaN();
702                        std::feclearexcept(FE_INVALID);
703                    } else {
704                        fd = std::copysign(fs1, fs2);
705                    }
706                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
707                }});
708                0x1: fsgnjn_s({{
709                    uint32_t temp;
710                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
711                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
712                    float fd;
713
714                    if (issignalingnan(fs1)) {
715                        fd = std::numeric_limits<float>::signaling_NaN();
716                        std::feclearexcept(FE_INVALID);
717                    } else {
718                        fd = std::copysign(fs1, -fs2);
719                    }
720                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
721                }});
722                0x2: fsgnjx_s({{
723                    uint32_t temp;
724                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
725                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
726                    float fd;
727
728                    if (issignalingnan(fs1)) {
729                        fd = std::numeric_limits<float>::signaling_NaN();
730                        std::feclearexcept(FE_INVALID);
731                    } else {
732                        fd = fs1*(std::signbit(fs2) ? -1.0 : 1.0);
733                    }
734                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
735                }});
736            }
737            0x11: decode ROUND_MODE {
738                0x0: fsgnj_d({{
739                    if (issignalingnan(Fs1)) {
740                        Fd = std::numeric_limits<double>::signaling_NaN();
741                        std::feclearexcept(FE_INVALID);
742                    } else {
743                        Fd = std::copysign(Fs1, Fs2);
744                    }
745                }});
746                0x1: fsgnjn_d({{
747                    if (issignalingnan(Fs1)) {
748                        Fd = std::numeric_limits<double>::signaling_NaN();
749                        std::feclearexcept(FE_INVALID);
750                    } else {
751                        Fd = std::copysign(Fs1, -Fs2);
752                    }
753                }});
754                0x2: fsgnjx_d({{
755                    if (issignalingnan(Fs1)) {
756                        Fd = std::numeric_limits<double>::signaling_NaN();
757                        std::feclearexcept(FE_INVALID);
758                    } else {
759                        Fd = Fs1*(std::signbit(Fs2) ? -1.0 : 1.0);
760                    }
761                }});
762            }
763            0x14: decode ROUND_MODE {
764                0x0: fmin_s({{
765                    uint32_t temp;
766                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
767                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
768                    float fd;
769
770                    if (issignalingnan(fs2)) {
771                        fd = fs1;
772                        FFLAGS |= FloatInvalid;
773                    } else if (issignalingnan(fs1)) {
774                        fd = fs2;
775                        FFLAGS |= FloatInvalid;
776                    } else {
777                        fd = std::fmin(fs1, fs2);
778                    }
779                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
780                }}, FloatCmpOp);
781                0x1: fmax_s({{
782                    uint32_t temp;
783                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
784                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
785                    float fd;
786
787                    if (issignalingnan(fs2)) {
788                        fd = fs1;
789                        FFLAGS |= FloatInvalid;
790                    } else if (issignalingnan(fs1)) {
791                        fd = fs2;
792                        FFLAGS |= FloatInvalid;
793                    } else {
794                        fd = std::fmax(fs1, fs2);
795                    }
796                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
797                }}, FloatCmpOp);
798            }
799            0x15: decode ROUND_MODE {
800                0x0: fmin_d({{
801                    if (issignalingnan(Fs2)) {
802                        Fd = Fs1;
803                        FFLAGS |= FloatInvalid;
804                    } else if (issignalingnan(Fs1)) {
805                        Fd = Fs2;
806                        FFLAGS |= FloatInvalid;
807                    } else {
808                        Fd = std::fmin(Fs1, Fs2);
809                    }
810                }}, FloatCmpOp);
811                0x1: fmax_d({{
812                    if (issignalingnan(Fs2)) {
813                        Fd = Fs1;
814                        FFLAGS |= FloatInvalid;
815                    } else if (issignalingnan(Fs1)) {
816                        Fd = Fs2;
817                        FFLAGS |= FloatInvalid;
818                    } else {
819                        Fd = std::fmax(Fs1, Fs2);
820                    }
821                }}, FloatCmpOp);
822            }
823            0x20: fcvt_s_d({{
824                assert(CONV_SGN == 1);
825                float fd;
826                if (issignalingnan(Fs1)) {
827                    fd = std::numeric_limits<float>::quiet_NaN();
828                    FFLAGS |= FloatInvalid;
829                } else {
830                    fd = (float)Fs1;
831                }
832                Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
833            }}, FloatCvtOp);
834            0x21: fcvt_d_s({{
835                assert(CONV_SGN == 0);
836                uint32_t temp;
837                float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
838
839                if (issignalingnan(fs1)) {
840                    Fd = std::numeric_limits<double>::quiet_NaN();
841                    FFLAGS |= FloatInvalid;
842                } else {
843                    Fd = (double)fs1;
844                }
845            }}, FloatCvtOp);
846            0x2c: fsqrt_s({{
847                assert(RS2 == 0);
848                uint32_t temp;
849                float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
850                float fd;
851
852                if (issignalingnan(Fs1_sf)) {
853                    FFLAGS |= FloatInvalid;
854                }
855                fd = std::sqrt(fs1);
856                Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
857            }}, FloatSqrtOp);
858            0x2d: fsqrt_d({{
859                assert(RS2 == 0);
860                Fd = std::sqrt(Fs1);
861            }}, FloatSqrtOp);
862            0x50: decode ROUND_MODE {
863                0x0: fle_s({{
864                    uint32_t temp;
865                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
866                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
867
868                    if (std::isnan(fs1) || std::isnan(fs2)) {
869                        FFLAGS |= FloatInvalid;
870                        Rd = 0;
871                    } else {
872                        Rd = fs1 <= fs2 ? 1 : 0;
873                    }
874                }}, FloatCmpOp);
875                0x1: flt_s({{
876                    uint32_t temp;
877                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
878                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
879
880                    if (std::isnan(fs1) || std::isnan(fs2)) {
881                        FFLAGS |= FloatInvalid;
882                        Rd = 0;
883                    } else {
884                        Rd = fs1 < fs2 ? 1 : 0;
885                    }
886                }}, FloatCmpOp);
887                0x2: feq_s({{
888                    uint32_t temp;
889                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
890                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
891
892                    if (issignalingnan(fs1) || issignalingnan(fs2)) {
893                        FFLAGS |= FloatInvalid;
894                    }
895                    Rd = fs1 == fs2 ? 1 : 0;
896                }}, FloatCmpOp);
897            }
898            0x51: decode ROUND_MODE {
899                0x0: fle_d({{
900                    if (std::isnan(Fs1) || std::isnan(Fs2)) {
901                        FFLAGS |= FloatInvalid;
902                        Rd = 0;
903                    } else {
904                        Rd = Fs1 <= Fs2 ? 1 : 0;
905                    }
906                }}, FloatCmpOp);
907                0x1: flt_d({{
908                    if (std::isnan(Fs1) || std::isnan(Fs2)) {
909                        FFLAGS |= FloatInvalid;
910                        Rd = 0;
911                    } else {
912                        Rd = Fs1 < Fs2 ? 1 : 0;
913                    }
914                }}, FloatCmpOp);
915                0x2: feq_d({{
916                    if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
917                        FFLAGS |= FloatInvalid;
918                    }
919                    Rd = Fs1 == Fs2 ? 1 : 0;
920                }}, FloatCmpOp);
921            }
922            0x60: decode CONV_SGN {
923                0x0: fcvt_w_s({{
924                    uint32_t temp;
925                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
926
927                    if (std::isnan(fs1)) {
928                        Rd_sd = std::numeric_limits<int32_t>::max();
929                        FFLAGS |= FloatInvalid;
930                    } else {
931                        Rd_sd = (int32_t)fs1;
932                        if (std::fetestexcept(FE_INVALID)) {
933                            if (std::signbit(fs1)) {
934                                Rd_sd = std::numeric_limits<int32_t>::min();
935                            } else {
936                                Rd_sd = std::numeric_limits<int32_t>::max();
937                            }
938                            std::feclearexcept(FE_INEXACT);
939                        }
940                    }
941                }}, FloatCvtOp);
942                0x1: fcvt_wu_s({{
943                    uint32_t temp;
944                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
945
946                    if (fs1 < 0.0) {
947                        Rd = 0;
948                        FFLAGS |= FloatInvalid;
949                    } else {
950                        Rd = (uint32_t)fs1;
951                        if (std::fetestexcept(FE_INVALID)) {
952                            Rd = std::numeric_limits<uint64_t>::max();
953                            std::feclearexcept(FE_INEXACT);
954                        }
955                    }
956                }}, FloatCvtOp);
957                0x2: fcvt_l_s({{
958                    uint32_t temp;
959                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
960
961                    if (std::isnan(fs1)) {
962                        Rd_sd = std::numeric_limits<int64_t>::max();
963                        FFLAGS |= FloatInvalid;
964                    } else {
965                        Rd_sd = (int64_t)fs1;
966                        if (std::fetestexcept(FE_INVALID)) {
967                            if (std::signbit(fs1)) {
968                                Rd_sd = std::numeric_limits<int64_t>::min();
969                            } else {
970                                Rd_sd = std::numeric_limits<int64_t>::max();
971                            }
972                            std::feclearexcept(FE_INEXACT);
973                        }
974                    }
975                }}, FloatCvtOp);
976                0x3: fcvt_lu_s({{
977                    uint32_t temp;
978                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
979
980                    if (fs1 < 0.0) {
981                        Rd = 0;
982                        FFLAGS |= FloatInvalid;
983                    } else {
984                        Rd = (uint64_t)fs1;
985                        if (std::fetestexcept(FE_INVALID)) {
986                            Rd = std::numeric_limits<uint64_t>::max();
987                            std::feclearexcept(FE_INEXACT);
988                        }
989                    }
990                }}, FloatCvtOp);
991            }
992            0x61: decode CONV_SGN {
993                0x0: fcvt_w_d({{
994                    Rd_sd = (int32_t)Fs1;
995                    if (std::fetestexcept(FE_INVALID)) {
996                        if (Fs1 < 0.0) {
997                            Rd_sd = std::numeric_limits<int32_t>::min();
998                        } else {
999                            Rd_sd = std::numeric_limits<int32_t>::max();
1000                        }
1001                        std::feclearexcept(FE_INEXACT);
1002                    }
1003                }}, FloatCvtOp);
1004                0x1: fcvt_wu_d({{
1005                    if (Fs1 < 0.0) {
1006                        Rd = 0;
1007                        FFLAGS |= FloatInvalid;
1008                    } else {
1009                        Rd = (uint32_t)Fs1;
1010                        if (std::fetestexcept(FE_INVALID)) {
1011                            Rd = std::numeric_limits<uint64_t>::max();
1012                            std::feclearexcept(FE_INEXACT);
1013                        }
1014                    }
1015                }}, FloatCvtOp);
1016                0x2: fcvt_l_d({{
1017                    Rd_sd = Fs1;
1018                    if (std::fetestexcept(FE_INVALID)) {
1019                        if (Fs1 < 0.0) {
1020                            Rd_sd = std::numeric_limits<int64_t>::min();
1021                        } else {
1022                            Rd_sd = std::numeric_limits<int64_t>::max();
1023                        }
1024                        std::feclearexcept(FE_INEXACT);
1025                    }
1026                }}, FloatCvtOp);
1027                0x3: fcvt_lu_d({{
1028                    if (Fs1 < 0.0) {
1029                        Rd = 0;
1030                        FFLAGS |= FloatInvalid;
1031                    } else {
1032                        Rd = (uint64_t)Fs1;
1033                        if (std::fetestexcept(FE_INVALID)) {
1034                            Rd = std::numeric_limits<uint64_t>::max();
1035                            std::feclearexcept(FE_INEXACT);
1036                        }
1037                    }
1038                }}, FloatCvtOp);
1039            }
1040            0x68: decode CONV_SGN {
1041                0x0: fcvt_s_w({{
1042                    float temp = (float)Rs1_sw;
1043                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1044                }}, FloatCvtOp);
1045                0x1: fcvt_s_wu({{
1046                    float temp = (float)Rs1_uw;
1047                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1048                }}, FloatCvtOp);
1049                0x2: fcvt_s_l({{
1050                    float temp = (float)Rs1_sd;
1051                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1052                }}, FloatCvtOp);
1053                0x3: fcvt_s_lu({{
1054                    float temp = (float)Rs1;
1055                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1056                }}, FloatCvtOp);
1057            }
1058            0x69: decode CONV_SGN {
1059                0x0: fcvt_d_w({{
1060                    Fd = (double)Rs1_sw;
1061                }}, FloatCvtOp);
1062                0x1: fcvt_d_wu({{
1063                    Fd = (double)Rs1_uw;
1064                }}, FloatCvtOp);
1065                0x2: fcvt_d_l({{
1066                    Fd = (double)Rs1_sd;
1067                }}, FloatCvtOp);
1068                0x3: fcvt_d_lu({{
1069                    Fd = (double)Rs1;
1070                }}, FloatCvtOp);
1071            }
1072            0x70: decode ROUND_MODE {
1073                0x0: fmv_x_s({{
1074                    Rd = (uint32_t)Fs1_bits;
1075                    if ((Rd&0x80000000) != 0) {
1076                        Rd |= (0xFFFFFFFFULL << 32);
1077                    }
1078                }}, FloatCvtOp);
1079                0x1: fclass_s({{
1080                    uint32_t temp;
1081                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1082                    switch (std::fpclassify(fs1)) {
1083                    case FP_INFINITE:
1084                        if (std::signbit(fs1)) {
1085                            Rd = 1 << 0;
1086                        } else {
1087                            Rd = 1 << 7;
1088                        }
1089                        break;
1090                    case FP_NAN:
1091                        if (issignalingnan(fs1)) {
1092                            Rd = 1 << 8;
1093                        } else {
1094                            Rd = 1 << 9;
1095                        }
1096                        break;
1097                    case FP_ZERO:
1098                        if (std::signbit(fs1)) {
1099                            Rd = 1 << 3;
1100                        } else {
1101                            Rd = 1 << 4;
1102                        }
1103                        break;
1104                    case FP_SUBNORMAL:
1105                        if (std::signbit(fs1)) {
1106                            Rd = 1 << 2;
1107                        } else {
1108                            Rd = 1 << 5;
1109                        }
1110                        break;
1111                    case FP_NORMAL:
1112                        if (std::signbit(fs1)) {
1113                            Rd = 1 << 1;
1114                        } else {
1115                            Rd = 1 << 6;
1116                        }
1117                        break;
1118                    default:
1119                        panic("Unknown classification for operand.");
1120                        break;
1121                    }
1122                }});
1123            }
1124            0x71: decode ROUND_MODE {
1125                0x0: fmv_x_d({{
1126                    Rd = Fs1_bits;
1127                }}, FloatCvtOp);
1128                0x1: fclass_d({{
1129                    switch (std::fpclassify(Fs1)) {
1130                    case FP_INFINITE:
1131                        if (std::signbit(Fs1)) {
1132                            Rd = 1 << 0;
1133                        } else {
1134                            Rd = 1 << 7;
1135                        }
1136                        break;
1137                    case FP_NAN:
1138                        if (issignalingnan(Fs1)) {
1139                            Rd = 1 << 8;
1140                        } else {
1141                            Rd = 1 << 9;
1142                        }
1143                        break;
1144                    case FP_ZERO:
1145                        if (std::signbit(Fs1)) {
1146                            Rd = 1 << 3;
1147                        } else {
1148                            Rd = 1 << 4;
1149                        }
1150                        break;
1151                    case FP_SUBNORMAL:
1152                        if (std::signbit(Fs1)) {
1153                            Rd = 1 << 2;
1154                        } else {
1155                            Rd = 1 << 5;
1156                        }
1157                        break;
1158                    case FP_NORMAL:
1159                        if (std::signbit(Fs1)) {
1160                            Rd = 1 << 1;
1161                        } else {
1162                            Rd = 1 << 6;
1163                        }
1164                        break;
1165                    default:
1166                        panic("Unknown classification for operand.");
1167                        break;
1168                    }
1169                }});
1170            }
1171            0x78: fmv_s_x({{
1172                Fd_bits = (uint64_t)Rs1_uw;
1173            }}, FloatCvtOp);
1174            0x79: fmv_d_x({{
1175                Fd_bits = Rs1;
1176            }}, FloatCvtOp);
1177        }
1178    }
1179    0x63: decode FUNCT3 {
1180        format SBOp {
1181            0x0: beq({{
1182                if (Rs1 == Rs2) {
1183                    NPC = PC + imm;
1184                } else {
1185                    NPC = NPC;
1186                }
1187            }}, IsDirectControl, IsCondControl);
1188            0x1: bne({{
1189                if (Rs1 != Rs2) {
1190                    NPC = PC + imm;
1191                } else {
1192                    NPC = NPC;
1193                }
1194            }}, IsDirectControl, IsCondControl);
1195            0x4: blt({{
1196                if (Rs1_sd < Rs2_sd) {
1197                    NPC = PC + imm;
1198                } else {
1199                    NPC = NPC;
1200                }
1201            }}, IsDirectControl, IsCondControl);
1202            0x5: bge({{
1203                if (Rs1_sd >= Rs2_sd) {
1204                    NPC = PC + imm;
1205                } else {
1206                    NPC = NPC;
1207                }
1208            }}, IsDirectControl, IsCondControl);
1209            0x6: bltu({{
1210                if (Rs1 < Rs2) {
1211                    NPC = PC + imm;
1212                } else {
1213                    NPC = NPC;
1214                }
1215            }}, IsDirectControl, IsCondControl);
1216            0x7: bgeu({{
1217                if (Rs1 >= Rs2) {
1218                    NPC = PC + imm;
1219                } else {
1220                    NPC = NPC;
1221                }
1222            }}, IsDirectControl, IsCondControl);
1223        }
1224    }
1225
1226    0x67: decode FUNCT3 {
1227        0x0: Jump::jalr({{
1228            Rd = NPC;
1229            NPC = (imm + Rs1) & (~0x1);
1230        }}, IsIndirectControl, IsUncondControl, IsCall);
1231    }
1232
1233    0x6f: UJOp::jal({{
1234        Rd = NPC;
1235        NPC = PC + imm;
1236    }}, IsDirectControl, IsUncondControl, IsCall);
1237
1238    0x73: decode FUNCT3 {
1239        format IOp {
1240            0x0: decode FUNCT12 {
1241                0x0: ecall({{
1242                    fault = std::make_shared<SyscallFault>();
1243                }}, IsSerializeAfter, IsNonSpeculative, IsSyscall, No_OpClass);
1244                0x1: ebreak({{
1245                    fault = std::make_shared<BreakpointFault>();
1246                }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1247                0x100: eret({{
1248                    fault = std::make_shared<UnimplementedFault>("eret");
1249                }}, No_OpClass);
1250            }
1251            0x1: csrrw({{
1252                Rd = xc->readMiscReg(FUNCT12);
1253                xc->setMiscReg(FUNCT12, Rs1);
1254            }}, IsNonSpeculative, No_OpClass);
1255            0x2: csrrs({{
1256                Rd = xc->readMiscReg(FUNCT12);
1257                if (Rs1 != 0) {
1258                    xc->setMiscReg(FUNCT12, Rd | Rs1);
1259                }
1260            }}, IsNonSpeculative, No_OpClass);
1261            0x3: csrrc({{
1262                Rd = xc->readMiscReg(FUNCT12);
1263                if (Rs1 != 0) {
1264                    xc->setMiscReg(FUNCT12, Rd & ~Rs1);
1265                }
1266            }}, IsNonSpeculative, No_OpClass);
1267            0x5: csrrwi({{
1268                Rd = xc->readMiscReg(FUNCT12);
1269                xc->setMiscReg(FUNCT12, ZIMM);
1270            }}, IsNonSpeculative, No_OpClass);
1271            0x6: csrrsi({{
1272                Rd = xc->readMiscReg(FUNCT12);
1273                if (ZIMM != 0) {
1274                    xc->setMiscReg(FUNCT12, Rd | ZIMM);
1275                }
1276            }}, IsNonSpeculative, No_OpClass);
1277            0x7: csrrci({{
1278                Rd = xc->readMiscReg(FUNCT12);
1279                if (ZIMM != 0) {
1280                    xc->setMiscReg(FUNCT12, Rd & ~ZIMM);
1281                }
1282            }}, IsNonSpeculative, No_OpClass);
1283        }
1284    }
1285}
1286