decoder.isa revision 13653:079472978bca
1// -*- mode:c++ -*-
2
3// Copyright (c) 2015 RISC-V Foundation
4// Copyright (c) 2017 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 QUADRANT default Unknown::unknown() {
38    0x0: decode COPCODE {
39        0x0: CIOp::c_addi4spn({{
40            imm = CIMM8<1:1> << 2 |
41                  CIMM8<0:0> << 3 |
42                  CIMM8<7:6> << 4 |
43                  CIMM8<5:2> << 6;
44        }}, {{
45            if (machInst == 0)
46                fault = make_shared<IllegalInstFault>("zero instruction",
47                                                      machInst);
48            Rp2 = sp + imm;
49        }}, uint64_t);
50        format CompressedLoad {
51            0x1: c_fld({{
52                offset = CIMM3 << 3 | CIMM2 << 6;
53            }}, {{
54                Fp2_bits = Mem;
55            }}, {{
56                EA = Rp1 + offset;
57            }});
58            0x2: c_lw({{
59                offset = CIMM2<1:1> << 2 |
60                         CIMM3 << 3 |
61                         CIMM2<0:0> << 6;
62            }}, {{
63                Rp2_sd = Mem_sw;
64            }}, {{
65                EA = Rp1 + offset;
66            }});
67            0x3: c_ld({{
68                offset = CIMM3 << 3 | CIMM2 << 6;
69            }}, {{
70                Rp2_sd = Mem_sd;
71            }}, {{
72                EA = Rp1 + offset;
73            }});
74        }
75        format CompressedStore {
76            0x5: c_fsd({{
77                offset = CIMM3 << 3 | CIMM2 << 6;
78            }}, {{
79                Mem = Fp2_bits;
80            }}, {{
81                EA = Rp1 + offset;
82            }});
83            0x6: c_sw({{
84                offset = CIMM2<1:1> << 2 |
85                         CIMM3 << 3 |
86                         CIMM2<0:0> << 6;
87            }}, {{
88                Mem_uw = Rp2_uw;
89            }}, ea_code={{
90                EA = Rp1 + offset;
91            }});
92            0x7: c_sd({{
93                offset = CIMM3 << 3 | CIMM2 << 6;
94            }}, {{
95                    Mem_ud = Rp2_ud;
96            }}, {{
97                EA = Rp1 + offset;
98            }});
99        }
100    }
101    0x1: decode COPCODE {
102        format CIOp {
103            0x0: c_addi({{
104                imm = CIMM5;
105                if (CIMM1 > 0)
106                    imm |= ~((uint64_t)0x1F);
107            }}, {{
108                if ((RC1 == 0) != (imm == 0)) {
109                    if (RC1 == 0) {
110                        fault = make_shared<IllegalInstFault>("source reg x0",
111                                                              machInst);
112                    } else // imm == 0
113                        fault = make_shared<IllegalInstFault>("immediate = 0",
114                                                              machInst);
115                }
116                Rc1_sd = Rc1_sd + imm;
117            }});
118            0x1: c_addiw({{
119                imm = CIMM5;
120                if (CIMM1 > 0)
121                    imm |= ~((uint64_t)0x1F);
122            }}, {{
123                if (RC1 == 0) {
124                    fault = make_shared<IllegalInstFault>("source reg x0",
125                                                          machInst);
126                }
127                Rc1_sd = (int32_t)Rc1_sd + imm;
128            }});
129            0x2: c_li({{
130                imm = CIMM5;
131                if (CIMM1 > 0)
132                    imm |= ~((uint64_t)0x1F);
133            }}, {{
134                if (RC1 == 0) {
135                    fault = make_shared<IllegalInstFault>("source reg x0",
136                                                          machInst);
137                }
138                Rc1_sd = imm;
139            }});
140            0x3: decode RC1 {
141                0x2: c_addi16sp({{
142                    imm = CIMM5<4:4> << 4 |
143                          CIMM5<0:0> << 5 |
144                          CIMM5<3:3> << 6 |
145                          CIMM5<2:1> << 7;
146                    if (CIMM1 > 0)
147                        imm |= ~((int64_t)0x1FF);
148                }}, {{
149                    if (imm == 0) {
150                        fault = make_shared<IllegalInstFault>("immediate = 0",
151                                                              machInst);
152                    }
153                    sp_sd = sp_sd + imm;
154                }});
155                default: c_lui({{
156                    imm = CIMM5 << 12;
157                    if (CIMM1 > 0)
158                        imm |= ~((uint64_t)0x1FFFF);
159                }}, {{
160                    if (RC1 == 0 || RC1 == 2) {
161                        fault = make_shared<IllegalInstFault>("source reg x0",
162                                                              machInst);
163                    }
164                    if (imm == 0) {
165                        fault = make_shared<IllegalInstFault>("immediate = 0",
166                                                              machInst);
167                    }
168                    Rc1_sd = imm;
169                }});
170            }
171        }
172        0x4: decode CFUNCT2HIGH {
173            format CIOp {
174                0x0: c_srli({{
175                    imm = CIMM5 | (CIMM1 << 5);
176                }}, {{
177                    if (imm == 0) {
178                        fault = make_shared<IllegalInstFault>("immediate = 0",
179                                                              machInst);
180                    }
181                    Rp1 = Rp1 >> imm;
182                }}, uint64_t);
183                0x1: c_srai({{
184                    imm = CIMM5 | (CIMM1 << 5);
185                }}, {{
186                    if (imm == 0) {
187                        fault = make_shared<IllegalInstFault>("immediate = 0",
188                                                              machInst);
189                    }
190                    Rp1_sd = Rp1_sd >> imm;
191                }}, uint64_t);
192                0x2: c_andi({{
193                    imm = CIMM5;
194                    if (CIMM1 > 0)
195                        imm |= ~((uint64_t)0x1F);
196                }}, {{
197                    Rp1 = Rp1 & imm;
198                }}, uint64_t);
199            }
200            format ROp {
201                0x3: decode CFUNCT1 {
202                    0x0: decode CFUNCT2LOW {
203                        0x0: c_sub({{
204                            Rp1 = Rp1 - Rp2;
205                        }});
206                        0x1: c_xor({{
207                            Rp1 = Rp1 ^ Rp2;
208                        }});
209                        0x2: c_or({{
210                            Rp1 = Rp1 | Rp2;
211                        }});
212                        0x3: c_and({{
213                            Rp1 = Rp1 & Rp2;
214                        }});
215                    }
216                    0x1: decode CFUNCT2LOW {
217                        0x0: c_subw({{
218                            Rp1_sd = (int32_t)Rp1_sd - Rp2_sw;
219                        }});
220                        0x1: c_addw({{
221                            Rp1_sd = (int32_t)Rp1_sd + Rp2_sw;
222                        }});
223                    }
224                }
225            }
226        }
227        0x5: JOp::c_j({{
228            int64_t offset = CJUMPIMM<3:1> << 1 |
229                             CJUMPIMM<9:9> << 4 |
230                             CJUMPIMM<0:0> << 5 |
231                             CJUMPIMM<5:5> << 6 |
232                             CJUMPIMM<4:4> << 7 |
233                             CJUMPIMM<8:7> << 8 |
234                             CJUMPIMM<6:6> << 10;
235            if (CJUMPIMM<10:10> > 0)
236                offset |= ~((int64_t)0x7FF);
237            NPC = PC + offset;
238        }}, IsIndirectControl, IsUncondControl, IsCall);
239        format CBOp {
240            0x6: c_beqz({{
241                if (Rp1 == 0)
242                    NPC = PC + imm;
243                else
244                    NPC = NPC;
245            }}, IsDirectControl, IsCondControl);
246            0x7: c_bnez({{
247                if (Rp1 != 0)
248                    NPC = PC + imm;
249                else
250                    NPC = NPC;
251            }}, IsDirectControl, IsCondControl);
252        }
253    }
254    0x2: decode COPCODE {
255        0x0: CIOp::c_slli({{
256            imm = CIMM5 | (CIMM1 << 5);
257        }}, {{
258            if (imm == 0) {
259                fault = make_shared<IllegalInstFault>("immediate = 0",
260                                                      machInst);
261            }
262            if (RC1 == 0) {
263                fault = make_shared<IllegalInstFault>("source reg x0",
264                                                      machInst);
265            }
266            Rc1 = Rc1 << imm;
267        }}, uint64_t);
268        format CompressedLoad {
269            0x1: c_fldsp({{
270                offset = CIMM5<4:3> << 3 |
271                         CIMM1 << 5 |
272                         CIMM5<2:0> << 6;
273            }}, {{
274                Fc1_bits = Mem;
275            }}, {{
276                EA = sp + offset;
277            }});
278            0x2: c_lwsp({{
279                offset = CIMM5<4:2> << 2 |
280                         CIMM1 << 5 |
281                         CIMM5<1:0> << 6;
282            }}, {{
283                if (RC1 == 0) {
284                    fault = make_shared<IllegalInstFault>("source reg x0",
285                                                          machInst);
286                }
287                Rc1_sd = Mem_sw;
288            }}, {{
289                EA = sp + offset;
290            }});
291            0x3: c_ldsp({{
292                offset = CIMM5<4:3> << 3 |
293                         CIMM1 << 5 |
294                         CIMM5<2:0> << 6;
295            }}, {{
296                if (RC1 == 0) {
297                    fault = make_shared<IllegalInstFault>("source reg x0",
298                                                          machInst);
299                }
300                Rc1_sd = Mem_sd;
301            }}, {{
302                EA = sp + offset;
303            }});
304        }
305        0x4: decode CFUNCT1 {
306            0x0: decode RC2 {
307                0x0: Jump::c_jr({{
308                    if (RC1 == 0) {
309                        fault = make_shared<IllegalInstFault>("source reg x0",
310                                                              machInst);
311                    }
312                    NPC = Rc1;
313                }}, IsIndirectControl, IsUncondControl, IsCall);
314                default: CROp::c_mv({{
315                    if (RC1 == 0) {
316                        fault = make_shared<IllegalInstFault>("source reg x0",
317                                                              machInst);
318                    }
319                    Rc1 = Rc2;
320                }});
321            }
322            0x1: decode RC1 {
323                0x0: SystemOp::c_ebreak({{
324                    if (RC2 != 0) {
325                        fault = make_shared<IllegalInstFault>("source reg x1",
326                                                              machInst);
327                    }
328                    fault = make_shared<BreakpointFault>(xc->pcState());
329                }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
330                default: decode RC2 {
331                    0x0: Jump::c_jalr({{
332                        if (RC1 == 0) {
333                            fault = make_shared<IllegalInstFault>
334                                                        ("source reg x0",
335                                                         machInst);
336                        }
337                        ra = NPC;
338                        NPC = Rc1;
339                    }}, IsIndirectControl, IsUncondControl, IsCall);
340                    default: ROp::c_add({{
341                        Rc1_sd = Rc1_sd + Rc2_sd;
342                    }});
343                }
344            }
345        }
346        format CompressedStore {
347            0x5: c_fsdsp({{
348                offset = CIMM6<5:3> << 3 |
349                         CIMM6<2:0> << 6;
350            }}, {{
351                Mem_ud = Fc2_bits;
352            }}, {{
353                EA = sp + offset;
354            }});
355            0x6: c_swsp({{
356                offset = CIMM6<5:2> << 2 |
357                         CIMM6<1:0> << 6;
358            }}, {{
359                Mem_uw = Rc2_uw;
360            }}, {{
361                EA = sp + offset;
362            }});
363            0x7: c_sdsp({{
364                offset = CIMM6<5:3> << 3 |
365                         CIMM6<2:0> << 6;
366            }}, {{
367                Mem = Rc2;
368            }}, {{
369                EA = sp + offset;
370            }});
371        }
372    }
373    0x3: decode OPCODE {
374        0x00: decode FUNCT3 {
375            format Load {
376                0x0: lb({{
377                    Rd_sd = Mem_sb;
378                }});
379                0x1: lh({{
380                    Rd_sd = Mem_sh;
381                }});
382                0x2: lw({{
383                    Rd_sd = Mem_sw;
384                }});
385                0x3: ld({{
386                    Rd_sd = Mem_sd;
387                }});
388                0x4: lbu({{
389                    Rd = Mem_ub;
390                }});
391                0x5: lhu({{
392                    Rd = Mem_uh;
393                }});
394                0x6: lwu({{
395                    Rd = Mem_uw;
396                }});
397            }
398        }
399
400        0x01: decode FUNCT3 {
401            format Load {
402                0x2: flw({{
403                    Fd_bits = (uint64_t)Mem_uw;
404                }}, inst_flags=FloatMemReadOp);
405                0x3: fld({{
406                    Fd_bits = Mem;
407                }}, inst_flags=FloatMemReadOp);
408            }
409        }
410
411        0x03: decode FUNCT3 {
412            format IOp {
413                0x0: fence({{
414                }}, uint64_t, IsMemBarrier, No_OpClass);
415                0x1: fence_i({{
416                }}, uint64_t, IsNonSpeculative, IsSerializeAfter, No_OpClass);
417            }
418        }
419
420        0x04: decode FUNCT3 {
421            format IOp {
422                0x0: addi({{
423                    Rd_sd = Rs1_sd + imm;
424                }});
425                0x1: slli({{
426                    Rd = Rs1 << SHAMT6;
427                }});
428                0x2: slti({{
429                    Rd = (Rs1_sd < imm) ? 1 : 0;
430                }});
431                0x3: sltiu({{
432                    Rd = (Rs1 < imm) ? 1 : 0;
433                }}, uint64_t);
434                0x4: xori({{
435                    Rd = Rs1 ^ imm;
436                }}, uint64_t);
437                0x5: decode SRTYPE {
438                    0x0: srli({{
439                        Rd = Rs1 >> SHAMT6;
440                    }});
441                    0x1: srai({{
442                        Rd_sd = Rs1_sd >> SHAMT6;
443                    }});
444                }
445                0x6: ori({{
446                    Rd = Rs1 | imm;
447                }}, uint64_t);
448                0x7: andi({{
449                    Rd = Rs1 & imm;
450                }}, uint64_t);
451            }
452        }
453
454        0x05: UOp::auipc({{
455            Rd = PC + imm;
456        }});
457
458        0x06: decode FUNCT3 {
459            format IOp {
460                0x0: addiw({{
461                    Rd_sd = Rs1_sw + imm;
462                }}, int32_t);
463                0x1: slliw({{
464                    Rd_sd = Rs1_sw << SHAMT5;
465                }});
466                0x5: decode SRTYPE {
467                    0x0: srliw({{
468                        Rd_sd = (int32_t)(Rs1_uw >> SHAMT5);
469                    }});
470                    0x1: sraiw({{
471                        Rd_sd = Rs1_sw >> SHAMT5;
472                    }});
473                }
474            }
475        }
476
477        0x08: decode FUNCT3 {
478            format Store {
479                0x0: sb({{
480                    Mem_ub = Rs2_ub;
481                }});
482                0x1: sh({{
483                    Mem_uh = Rs2_uh;
484                }});
485                0x2: sw({{
486                    Mem_uw = Rs2_uw;
487                }});
488                0x3: sd({{
489                    Mem_ud = Rs2_ud;
490                }});
491            }
492        }
493
494        0x09: decode FUNCT3 {
495            format Store {
496                0x2: fsw({{
497                    Mem_uw = (uint32_t)Fs2_bits;
498                }}, inst_flags=FloatMemWriteOp);
499                0x3: fsd({{
500                    Mem_ud = Fs2_bits;
501                }}, inst_flags=FloatMemWriteOp);
502            }
503        }
504
505        0x0b: decode FUNCT3 {
506            0x2: decode AMOFUNCT {
507                0x2: LoadReserved::lr_w({{
508                    Rd_sd = Mem_sw;
509                }}, mem_flags=LLSC);
510                0x3: StoreCond::sc_w({{
511                    Mem_uw = Rs2_uw;
512                }}, {{
513                    Rd = result;
514                }}, inst_flags=IsStoreConditional, mem_flags=LLSC);
515                0x0: AtomicMemOp::amoadd_w({{
516                    Rd_sd = Mem_sw;
517                }}, {{
518                    TypedAtomicOpFunctor<int32_t> *amo_op =
519                          new AtomicGenericOp<int32_t>(Rs2_sw,
520                                  [](int32_t* b, int32_t a){ *b += a; });
521                }}, mem_flags=ATOMIC_RETURN_OP);
522                0x1: AtomicMemOp::amoswap_w({{
523                    Rd_sd = Mem_sw;
524                }}, {{
525                    TypedAtomicOpFunctor<uint32_t> *amo_op =
526                          new AtomicGenericOp<uint32_t>(Rs2_uw,
527                                  [](uint32_t* b, uint32_t a){ *b = a; });
528                }}, mem_flags=ATOMIC_RETURN_OP);
529                0x4: AtomicMemOp::amoxor_w({{
530                    Rd_sd = Mem_sw;
531                }}, {{
532                    TypedAtomicOpFunctor<uint32_t> *amo_op =
533                          new AtomicGenericOp<uint32_t>(Rs2_uw,
534                                  [](uint32_t* b, uint32_t a){ *b ^= a; });
535                }}, mem_flags=ATOMIC_RETURN_OP);
536                0x8: AtomicMemOp::amoor_w({{
537                    Rd_sd = Mem_sw;
538                }}, {{
539                    TypedAtomicOpFunctor<uint32_t> *amo_op =
540                          new AtomicGenericOp<uint32_t>(Rs2_uw,
541                                  [](uint32_t* b, uint32_t a){ *b |= a; });
542                }}, mem_flags=ATOMIC_RETURN_OP);
543                0xc: AtomicMemOp::amoand_w({{
544                    Rd_sd = Mem_sw;
545                }}, {{
546                    TypedAtomicOpFunctor<uint32_t> *amo_op =
547                          new AtomicGenericOp<uint32_t>(Rs2_uw,
548                                  [](uint32_t* b, uint32_t a){ *b &= a; });
549                }}, mem_flags=ATOMIC_RETURN_OP);
550                0x10: AtomicMemOp::amomin_w({{
551                    Rd_sd = Mem_sw;
552                }}, {{
553                    TypedAtomicOpFunctor<int32_t> *amo_op =
554                      new AtomicGenericOp<int32_t>(Rs2_sw,
555                        [](int32_t* b, int32_t a){ if (a < *b) *b = a; });
556                }}, mem_flags=ATOMIC_RETURN_OP);
557                0x14: AtomicMemOp::amomax_w({{
558                    Rd_sd = Mem_sw;
559                }}, {{
560                    TypedAtomicOpFunctor<int32_t> *amo_op =
561                      new AtomicGenericOp<int32_t>(Rs2_sw,
562                        [](int32_t* b, int32_t a){ if (a > *b) *b = a; });
563                }}, mem_flags=ATOMIC_RETURN_OP);
564                0x18: AtomicMemOp::amominu_w({{
565                    Rd_sd = Mem_sw;
566                }}, {{
567                    TypedAtomicOpFunctor<uint32_t> *amo_op =
568                      new AtomicGenericOp<uint32_t>(Rs2_uw,
569                        [](uint32_t* b, uint32_t a){ if (a < *b) *b = a; });
570                }}, mem_flags=ATOMIC_RETURN_OP);
571                0x1c: AtomicMemOp::amomaxu_w({{
572                    Rd_sd = Mem_sw;
573                }}, {{
574                    TypedAtomicOpFunctor<uint32_t> *amo_op =
575                      new AtomicGenericOp<uint32_t>(Rs2_uw,
576                        [](uint32_t* b, uint32_t a){ if (a > *b) *b = a; });
577                }}, mem_flags=ATOMIC_RETURN_OP);
578            }
579            0x3: decode AMOFUNCT {
580                0x2: LoadReserved::lr_d({{
581                    Rd_sd = Mem_sd;
582                }}, mem_flags=LLSC);
583                0x3: StoreCond::sc_d({{
584                    Mem = Rs2;
585                }}, {{
586                    Rd = result;
587                }}, mem_flags=LLSC, inst_flags=IsStoreConditional);
588                0x0: AtomicMemOp::amoadd_d({{
589                    Rd_sd = Mem_sd;
590                }}, {{
591                    TypedAtomicOpFunctor<int64_t> *amo_op =
592                          new AtomicGenericOp<int64_t>(Rs2_sd,
593                                  [](int64_t* b, int64_t a){ *b += a; });
594                }}, mem_flags=ATOMIC_RETURN_OP);
595                0x1: AtomicMemOp::amoswap_d({{
596                    Rd_sd = Mem_sd;
597                }}, {{
598                    TypedAtomicOpFunctor<uint64_t> *amo_op =
599                          new AtomicGenericOp<uint64_t>(Rs2_ud,
600                                  [](uint64_t* b, uint64_t a){ *b = a; });
601                }}, mem_flags=ATOMIC_RETURN_OP);
602                0x4: AtomicMemOp::amoxor_d({{
603                    Rd_sd = Mem_sd;
604                }}, {{
605                    TypedAtomicOpFunctor<uint64_t> *amo_op =
606                          new AtomicGenericOp<uint64_t>(Rs2_ud,
607                                 [](uint64_t* b, uint64_t a){ *b ^= a; });
608                }}, mem_flags=ATOMIC_RETURN_OP);
609                0x8: AtomicMemOp::amoor_d({{
610                    Rd_sd = Mem_sd;
611                }}, {{
612                    TypedAtomicOpFunctor<uint64_t> *amo_op =
613                          new AtomicGenericOp<uint64_t>(Rs2_ud,
614                                 [](uint64_t* b, uint64_t a){ *b |= a; });
615                }}, mem_flags=ATOMIC_RETURN_OP);
616                0xc: AtomicMemOp::amoand_d({{
617                    Rd_sd = Mem_sd;
618                }}, {{
619                    TypedAtomicOpFunctor<uint64_t> *amo_op =
620                          new AtomicGenericOp<uint64_t>(Rs2_ud,
621                                 [](uint64_t* b, uint64_t a){ *b &= a; });
622                }}, mem_flags=ATOMIC_RETURN_OP);
623                0x10: AtomicMemOp::amomin_d({{
624                    Rd_sd = Mem_sd;
625                }}, {{
626                    TypedAtomicOpFunctor<int64_t> *amo_op =
627                      new AtomicGenericOp<int64_t>(Rs2_sd,
628                        [](int64_t* b, int64_t a){ if (a < *b) *b = a; });
629                }}, mem_flags=ATOMIC_RETURN_OP);
630                0x14: AtomicMemOp::amomax_d({{
631                    Rd_sd = Mem_sd;
632                }}, {{
633                    TypedAtomicOpFunctor<int64_t> *amo_op =
634                      new AtomicGenericOp<int64_t>(Rs2_sd,
635                        [](int64_t* b, int64_t a){ if (a > *b) *b = a; });
636                }}, mem_flags=ATOMIC_RETURN_OP);
637                0x18: AtomicMemOp::amominu_d({{
638                    Rd_sd = Mem_sd;
639                }}, {{
640                    TypedAtomicOpFunctor<uint64_t> *amo_op =
641                      new AtomicGenericOp<uint64_t>(Rs2_ud,
642                        [](uint64_t* b, uint64_t a){ if (a < *b) *b = a; });
643                }}, mem_flags=ATOMIC_RETURN_OP);
644                0x1c: AtomicMemOp::amomaxu_d({{
645                    Rd_sd = Mem_sd;
646                }}, {{
647                    TypedAtomicOpFunctor<uint64_t> *amo_op =
648                      new AtomicGenericOp<uint64_t>(Rs2_ud,
649                        [](uint64_t* b, uint64_t a){ if (a > *b) *b = a; });
650                }}, mem_flags=ATOMIC_RETURN_OP);
651            }
652        }
653        0x0c: decode FUNCT3 {
654            format ROp {
655                0x0: decode FUNCT7 {
656                    0x0: add({{
657                        Rd = Rs1_sd + Rs2_sd;
658                    }});
659                    0x1: mul({{
660                        Rd = Rs1_sd*Rs2_sd;
661                    }}, IntMultOp);
662                    0x20: sub({{
663                        Rd = Rs1_sd - Rs2_sd;
664                    }});
665                }
666                0x1: decode FUNCT7 {
667                    0x0: sll({{
668                        Rd = Rs1 << Rs2<5:0>;
669                    }});
670                    0x1: mulh({{
671                        bool negate = (Rs1_sd < 0) != (Rs2_sd < 0);
672
673                        uint64_t Rs1_lo = (uint32_t)abs(Rs1_sd);
674                        uint64_t Rs1_hi = (uint64_t)abs(Rs1_sd) >> 32;
675                        uint64_t Rs2_lo = (uint32_t)abs(Rs2_sd);
676                        uint64_t Rs2_hi = (uint64_t)abs(Rs2_sd) >> 32;
677
678                        uint64_t hi = Rs1_hi*Rs2_hi;
679                        uint64_t mid1 = Rs1_hi*Rs2_lo;
680                        uint64_t mid2 = Rs1_lo*Rs2_hi;
681                        uint64_t lo = Rs2_lo*Rs1_lo;
682                        uint64_t carry = ((uint64_t)(uint32_t)mid1
683                                + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
684
685                        uint64_t res = hi +
686                                       (mid1 >> 32) +
687                                       (mid2 >> 32) +
688                                       carry;
689                        Rd = negate ? ~res + (Rs1_sd*Rs2_sd == 0 ? 1 : 0)
690                                    : res;
691                    }}, IntMultOp);
692                }
693                0x2: decode FUNCT7 {
694                    0x0: slt({{
695                        Rd = (Rs1_sd < Rs2_sd) ? 1 : 0;
696                    }});
697                    0x1: mulhsu({{
698                        bool negate = Rs1_sd < 0;
699                        uint64_t Rs1_lo = (uint32_t)abs(Rs1_sd);
700                        uint64_t Rs1_hi = (uint64_t)abs(Rs1_sd) >> 32;
701                        uint64_t Rs2_lo = (uint32_t)Rs2;
702                        uint64_t Rs2_hi = Rs2 >> 32;
703
704                        uint64_t hi = Rs1_hi*Rs2_hi;
705                        uint64_t mid1 = Rs1_hi*Rs2_lo;
706                        uint64_t mid2 = Rs1_lo*Rs2_hi;
707                        uint64_t lo = Rs1_lo*Rs2_lo;
708                        uint64_t carry = ((uint64_t)(uint32_t)mid1
709                                + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
710
711                        uint64_t res = hi +
712                                       (mid1 >> 32) +
713                                       (mid2 >> 32) +
714                                       carry;
715                        Rd = negate ? ~res + (Rs1_sd*Rs2 == 0 ? 1 : 0) : res;
716                    }}, IntMultOp);
717                }
718                0x3: decode FUNCT7 {
719                    0x0: sltu({{
720                        Rd = (Rs1 < Rs2) ? 1 : 0;
721                    }});
722                    0x1: mulhu({{
723                        uint64_t Rs1_lo = (uint32_t)Rs1;
724                        uint64_t Rs1_hi = Rs1 >> 32;
725                        uint64_t Rs2_lo = (uint32_t)Rs2;
726                        uint64_t Rs2_hi = Rs2 >> 32;
727
728                        uint64_t hi = Rs1_hi*Rs2_hi;
729                        uint64_t mid1 = Rs1_hi*Rs2_lo;
730                        uint64_t mid2 = Rs1_lo*Rs2_hi;
731                        uint64_t lo = Rs1_lo*Rs2_lo;
732                        uint64_t carry = ((uint64_t)(uint32_t)mid1
733                                + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32;
734
735                        Rd = hi + (mid1 >> 32) + (mid2 >> 32) + carry;
736                    }}, IntMultOp);
737                }
738                0x4: decode FUNCT7 {
739                    0x0: xor({{
740                        Rd = Rs1 ^ Rs2;
741                    }});
742                    0x1: div({{
743                        if (Rs2_sd == 0) {
744                            Rd_sd = -1;
745                        } else if (Rs1_sd == numeric_limits<int64_t>::min()
746                                && Rs2_sd == -1) {
747                            Rd_sd = numeric_limits<int64_t>::min();
748                        } else {
749                            Rd_sd = Rs1_sd/Rs2_sd;
750                        }
751                    }}, IntDivOp);
752                }
753                0x5: decode FUNCT7 {
754                    0x0: srl({{
755                        Rd = Rs1 >> Rs2<5:0>;
756                    }});
757                    0x1: divu({{
758                        if (Rs2 == 0) {
759                            Rd = numeric_limits<uint64_t>::max();
760                        } else {
761                            Rd = Rs1/Rs2;
762                        }
763                    }}, IntDivOp);
764                    0x20: sra({{
765                        Rd_sd = Rs1_sd >> Rs2<5:0>;
766                    }});
767                }
768                0x6: decode FUNCT7 {
769                    0x0: or({{
770                        Rd = Rs1 | Rs2;
771                    }});
772                    0x1: rem({{
773                        if (Rs2_sd == 0) {
774                            Rd = Rs1_sd;
775                        } else if (Rs1_sd == numeric_limits<int64_t>::min()
776                                && Rs2_sd == -1) {
777                            Rd = 0;
778                        } else {
779                            Rd = Rs1_sd%Rs2_sd;
780                        }
781                    }}, IntDivOp);
782                }
783                0x7: decode FUNCT7 {
784                    0x0: and({{
785                        Rd = Rs1 & Rs2;
786                    }});
787                    0x1: remu({{
788                        if (Rs2 == 0) {
789                            Rd = Rs1;
790                        } else {
791                            Rd = Rs1%Rs2;
792                        }
793                    }}, IntDivOp);
794                }
795            }
796        }
797
798        0x0d: UOp::lui({{
799            Rd = (uint64_t)imm;
800        }});
801
802        0x0e: decode FUNCT3 {
803            format ROp {
804                0x0: decode FUNCT7 {
805                    0x0: addw({{
806                        Rd_sd = Rs1_sw + Rs2_sw;
807                    }});
808                    0x1: mulw({{
809                        Rd_sd = (int32_t)(Rs1_sw*Rs2_sw);
810                    }}, IntMultOp);
811                    0x20: subw({{
812                        Rd_sd = Rs1_sw - Rs2_sw;
813                    }});
814                }
815                0x1: sllw({{
816                    Rd_sd = Rs1_sw << Rs2<4:0>;
817                }});
818                0x4: divw({{
819                    if (Rs2_sw == 0) {
820                        Rd_sd = -1;
821                    } else if (Rs1_sw == numeric_limits<int32_t>::min()
822                            && Rs2_sw == -1) {
823                        Rd_sd = numeric_limits<int32_t>::min();
824                    } else {
825                        Rd_sd = Rs1_sw/Rs2_sw;
826                    }
827                }}, IntDivOp);
828                0x5: decode FUNCT7 {
829                    0x0: srlw({{
830                        Rd_sd = (int32_t)(Rs1_uw >> Rs2<4:0>);
831                    }});
832                    0x1: divuw({{
833                        if (Rs2_uw == 0) {
834                            Rd_sd = numeric_limits<uint64_t>::max();
835                        } else {
836                            Rd_sd = (int32_t)(Rs1_uw/Rs2_uw);
837                        }
838                    }}, IntDivOp);
839                    0x20: sraw({{
840                        Rd_sd = Rs1_sw >> Rs2<4:0>;
841                    }});
842                }
843                0x6: remw({{
844                    if (Rs2_sw == 0) {
845                        Rd_sd = Rs1_sw;
846                    } else if (Rs1_sw == numeric_limits<int32_t>::min()
847                            && Rs2_sw == -1) {
848                        Rd_sd = 0;
849                    } else {
850                        Rd_sd = Rs1_sw%Rs2_sw;
851                    }
852                }}, IntDivOp);
853                0x7: remuw({{
854                    if (Rs2_uw == 0) {
855                        Rd_sd = (int32_t)Rs1_uw;
856                    } else {
857                        Rd_sd = (int32_t)(Rs1_uw%Rs2_uw);
858                    }
859                }}, IntDivOp);
860            }
861        }
862
863        format FPROp {
864            0x10: decode FUNCT2 {
865                0x0: fmadd_s({{
866                    uint32_t temp;
867                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
868                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
869                    float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
870                    float fd;
871
872                    if (std::isnan(fs1) || std::isnan(fs2) ||
873                            std::isnan(fs3)) {
874                        if (issignalingnan(fs1) || issignalingnan(fs2)
875                                || issignalingnan(fs3)) {
876                            FFLAGS |= FloatInvalid;
877                        }
878                        fd = numeric_limits<float>::quiet_NaN();
879                    } else if (std::isinf(fs1) || std::isinf(fs2) ||
880                            std::isinf(fs3)) {
881                        if (signbit(fs1) == signbit(fs2)
882                                && !std::isinf(fs3)) {
883                            fd = numeric_limits<float>::infinity();
884                        } else if (signbit(fs1) != signbit(fs2)
885                                && !std::isinf(fs3)) {
886                            fd = -numeric_limits<float>::infinity();
887                        } else { // Fs3_sf is infinity
888                            fd = fs3;
889                        }
890                    } else {
891                        fd = fs1*fs2 + fs3;
892                    }
893                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
894                }}, FloatMultAccOp);
895                0x1: fmadd_d({{
896                    if (std::isnan(Fs1) || std::isnan(Fs2) ||
897                            std::isnan(Fs3)) {
898                        if (issignalingnan(Fs1) || issignalingnan(Fs2)
899                                || issignalingnan(Fs3)) {
900                            FFLAGS |= FloatInvalid;
901                        }
902                        Fd = numeric_limits<double>::quiet_NaN();
903                    } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
904                            std::isinf(Fs3)) {
905                        if (signbit(Fs1) == signbit(Fs2)
906                                && !std::isinf(Fs3)) {
907                            Fd = numeric_limits<double>::infinity();
908                        } else if (signbit(Fs1) != signbit(Fs2)
909                                && !std::isinf(Fs3)) {
910                            Fd = -numeric_limits<double>::infinity();
911                        } else {
912                            Fd = Fs3;
913                        }
914                    } else {
915                        Fd = Fs1*Fs2 + Fs3;
916                    }
917                }}, FloatMultAccOp);
918            }
919            0x11: decode FUNCT2 {
920                0x0: fmsub_s({{
921                    uint32_t temp;
922                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
923                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
924                    float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
925                    float fd;
926
927                    if (std::isnan(fs1) || std::isnan(fs2) ||
928                            std::isnan(fs3)) {
929                        if (issignalingnan(fs1) || issignalingnan(fs2)
930                                || issignalingnan(fs3)) {
931                            FFLAGS |= FloatInvalid;
932                        }
933                        fd = numeric_limits<float>::quiet_NaN();
934                    } else if (std::isinf(fs1) || std::isinf(fs2) ||
935                            std::isinf(fs3)) {
936                        if (signbit(fs1) == signbit(fs2)
937                                && !std::isinf(fs3)) {
938                            fd = numeric_limits<float>::infinity();
939                        } else if (signbit(fs1) != signbit(fs2)
940                                && !std::isinf(fs3)) {
941                            fd = -numeric_limits<float>::infinity();
942                        } else { // Fs3_sf is infinity
943                            fd = -fs3;
944                        }
945                    } else {
946                        fd = fs1*fs2 - fs3;
947                    }
948                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
949                }}, FloatMultAccOp);
950                0x1: fmsub_d({{
951                    if (std::isnan(Fs1) || std::isnan(Fs2) ||
952                            std::isnan(Fs3)) {
953                        if (issignalingnan(Fs1) || issignalingnan(Fs2)
954                                || issignalingnan(Fs3)) {
955                            FFLAGS |= FloatInvalid;
956                        }
957                        Fd = numeric_limits<double>::quiet_NaN();
958                    } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
959                            std::isinf(Fs3)) {
960                        if (signbit(Fs1) == signbit(Fs2)
961                                && !std::isinf(Fs3)) {
962                            Fd = numeric_limits<double>::infinity();
963                        } else if (signbit(Fs1) != signbit(Fs2)
964                                && !std::isinf(Fs3)) {
965                            Fd = -numeric_limits<double>::infinity();
966                        } else {
967                            Fd = -Fs3;
968                        }
969                    } else {
970                        Fd = Fs1*Fs2 - Fs3;
971                    }
972                }}, FloatMultAccOp);
973            }
974            0x12: decode FUNCT2 {
975                0x0: fnmsub_s({{
976                    uint32_t temp;
977                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
978                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
979                    float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
980                    float fd;
981
982                    if (std::isnan(fs1) || std::isnan(fs2) ||
983                            std::isnan(fs3)) {
984                        if (issignalingnan(fs1) || issignalingnan(fs2)
985                                || issignalingnan(fs3)) {
986                            FFLAGS |= FloatInvalid;
987                        }
988                        fd = numeric_limits<float>::quiet_NaN();
989                    } else if (std::isinf(fs1) || std::isinf(fs2) ||
990                            std::isinf(fs3)) {
991                        if (signbit(fs1) == signbit(fs2)
992                                && !std::isinf(fs3)) {
993                            fd = -numeric_limits<float>::infinity();
994                        } else if (signbit(fs1) != signbit(fs2)
995                                && !std::isinf(fs3)) {
996                            fd = numeric_limits<float>::infinity();
997                        } else { // Fs3_sf is infinity
998                            fd = fs3;
999                        }
1000                    } else {
1001                        fd = -(fs1*fs2 - fs3);
1002                    }
1003                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1004                }}, FloatMultAccOp);
1005                0x1: fnmsub_d({{
1006                    if (std::isnan(Fs1) || std::isnan(Fs2) ||
1007                            std::isnan(Fs3)) {
1008                        if (issignalingnan(Fs1) || issignalingnan(Fs2)
1009                                || issignalingnan(Fs3)) {
1010                            FFLAGS |= FloatInvalid;
1011                        }
1012                        Fd = numeric_limits<double>::quiet_NaN();
1013                    } else if (std::isinf(Fs1) || std::isinf(Fs2)
1014                            || std::isinf(Fs3)) {
1015                        if (signbit(Fs1) == signbit(Fs2)
1016                                && !std::isinf(Fs3)) {
1017                            Fd = -numeric_limits<double>::infinity();
1018                        } else if (signbit(Fs1) != signbit(Fs2)
1019                                && !std::isinf(Fs3)) {
1020                            Fd = numeric_limits<double>::infinity();
1021                        } else {
1022                            Fd = Fs3;
1023                        }
1024                    } else {
1025                        Fd = -(Fs1*Fs2 - Fs3);
1026                    }
1027                }}, FloatMultAccOp);
1028            }
1029            0x13: decode FUNCT2 {
1030                0x0: fnmadd_s({{
1031                    uint32_t temp;
1032                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1033                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1034                    float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
1035                    float fd;
1036
1037                    if (std::isnan(fs1) || std::isnan(fs2) ||
1038                            std::isnan(fs3)) {
1039                        if (issignalingnan(fs1) || issignalingnan(fs2)
1040                                || issignalingnan(fs3)) {
1041                            FFLAGS |= FloatInvalid;
1042                        }
1043                        fd = numeric_limits<float>::quiet_NaN();
1044                    } else if (std::isinf(fs1) || std::isinf(fs2) ||
1045                            std::isinf(fs3)) {
1046                        if (signbit(fs1) == signbit(fs2)
1047                                && !std::isinf(fs3)) {
1048                            fd = -numeric_limits<float>::infinity();
1049                        } else if (signbit(fs1) != signbit(fs2)
1050                                && !std::isinf(fs3)) {
1051                            fd = numeric_limits<float>::infinity();
1052                        } else { // Fs3_sf is infinity
1053                            fd = -fs3;
1054                        }
1055                    } else {
1056                        fd = -(fs1*fs2 + fs3);
1057                    }
1058                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1059                }}, FloatMultAccOp);
1060                0x1: fnmadd_d({{
1061                    if (std::isnan(Fs1) || std::isnan(Fs2) ||
1062                            std::isnan(Fs3)) {
1063                        if (issignalingnan(Fs1) || issignalingnan(Fs2)
1064                                || issignalingnan(Fs3)) {
1065                            FFLAGS |= FloatInvalid;
1066                        }
1067                        Fd = numeric_limits<double>::quiet_NaN();
1068                    } else if (std::isinf(Fs1) || std::isinf(Fs2) ||
1069                            std::isinf(Fs3)) {
1070                        if (signbit(Fs1) == signbit(Fs2)
1071                                && !std::isinf(Fs3)) {
1072                            Fd = -numeric_limits<double>::infinity();
1073                        } else if (signbit(Fs1) != signbit(Fs2)
1074                                && !std::isinf(Fs3)) {
1075                            Fd = numeric_limits<double>::infinity();
1076                        } else {
1077                            Fd = -Fs3;
1078                        }
1079                    } else {
1080                        Fd = -(Fs1*Fs2 + Fs3);
1081                    }
1082                }}, FloatMultAccOp);
1083            }
1084            0x14: decode FUNCT7 {
1085                0x0: fadd_s({{
1086                    uint32_t temp;
1087                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1088                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1089                    float fd;
1090
1091                    if (std::isnan(fs1) || std::isnan(fs2)) {
1092                        if (issignalingnan(fs1) || issignalingnan(fs2)) {
1093                            FFLAGS |= FloatInvalid;
1094                        }
1095                        fd = numeric_limits<float>::quiet_NaN();
1096                    } else {
1097                        fd = fs1 + fs2;
1098                    }
1099                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1100                }}, FloatAddOp);
1101                0x1: fadd_d({{
1102                    if (std::isnan(Fs1) || std::isnan(Fs2)) {
1103                        if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1104                            FFLAGS |= FloatInvalid;
1105                        }
1106                        Fd = numeric_limits<double>::quiet_NaN();
1107                    } else {
1108                        Fd = Fs1 + Fs2;
1109                    }
1110                }}, FloatAddOp);
1111                0x4: fsub_s({{
1112                    uint32_t temp;
1113                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1114                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1115                    float fd;
1116
1117                    if (std::isnan(fs1) || std::isnan(fs2)) {
1118                        if (issignalingnan(fs1) || issignalingnan(fs2)) {
1119                            FFLAGS |= FloatInvalid;
1120                        }
1121                        fd = numeric_limits<float>::quiet_NaN();
1122                    } else {
1123                        fd = fs1 - fs2;
1124                    }
1125                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1126                }}, FloatAddOp);
1127                0x5: fsub_d({{
1128                    if (std::isnan(Fs1) || std::isnan(Fs2)) {
1129                        if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1130                            FFLAGS |= FloatInvalid;
1131                        }
1132                        Fd = numeric_limits<double>::quiet_NaN();
1133                    } else {
1134                        Fd = Fs1 - Fs2;
1135                    }
1136                }}, FloatAddOp);
1137                0x8: fmul_s({{
1138                    uint32_t temp;
1139                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1140                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1141                    float fd;
1142
1143                    if (std::isnan(fs1) || std::isnan(fs2)) {
1144                        if (issignalingnan(fs1) || issignalingnan(fs2)) {
1145                            FFLAGS |= FloatInvalid;
1146                        }
1147                        fd = numeric_limits<float>::quiet_NaN();
1148                    } else {
1149                        fd = fs1*fs2;
1150                    }
1151                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1152                }}, FloatMultOp);
1153                0x9: fmul_d({{
1154                    if (std::isnan(Fs1) || std::isnan(Fs2)) {
1155                        if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1156                            FFLAGS |= FloatInvalid;
1157                        }
1158                        Fd = numeric_limits<double>::quiet_NaN();
1159                    } else {
1160                        Fd = Fs1*Fs2;
1161                    }
1162                }}, FloatMultOp);
1163                0xc: fdiv_s({{
1164                    uint32_t temp;
1165                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1166                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1167                    float fd;
1168
1169                    if (std::isnan(fs1) || std::isnan(fs2)) {
1170                        if (issignalingnan(fs1) || issignalingnan(fs2)) {
1171                            FFLAGS |= FloatInvalid;
1172                        }
1173                        fd = numeric_limits<float>::quiet_NaN();
1174                    } else {
1175                        fd = fs1/fs2;
1176                    }
1177                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1178                }}, FloatDivOp);
1179                0xd: fdiv_d({{
1180                    if (std::isnan(Fs1) || std::isnan(Fs2)) {
1181                        if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1182                            FFLAGS |= FloatInvalid;
1183                        }
1184                        Fd = numeric_limits<double>::quiet_NaN();
1185                    } else {
1186                        Fd = Fs1/Fs2;
1187                    }
1188                }}, FloatDivOp);
1189                0x10: decode ROUND_MODE {
1190                    0x0: fsgnj_s({{
1191                        uint32_t temp;
1192                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1193                        float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1194                        float fd;
1195
1196                        if (issignalingnan(fs1)) {
1197                            fd = numeric_limits<float>::signaling_NaN();
1198                            feclearexcept(FE_INVALID);
1199                        } else {
1200                            fd = copysign(fs1, fs2);
1201                        }
1202                        Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1203                    }}, FloatMiscOp);
1204                    0x1: fsgnjn_s({{
1205                        uint32_t temp;
1206                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1207                        float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1208                        float fd;
1209
1210                        if (issignalingnan(fs1)) {
1211                            fd = numeric_limits<float>::signaling_NaN();
1212                            feclearexcept(FE_INVALID);
1213                        } else {
1214                            fd = copysign(fs1, -fs2);
1215                        }
1216                        Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1217                    }}, FloatMiscOp);
1218                    0x2: fsgnjx_s({{
1219                        uint32_t temp;
1220                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1221                        float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1222                        float fd;
1223
1224                        if (issignalingnan(fs1)) {
1225                            fd = numeric_limits<float>::signaling_NaN();
1226                            feclearexcept(FE_INVALID);
1227                        } else {
1228                            fd = fs1*(signbit(fs2) ? -1.0 : 1.0);
1229                        }
1230                        Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1231                    }}, FloatMiscOp);
1232                }
1233                0x11: decode ROUND_MODE {
1234                    0x0: fsgnj_d({{
1235                        if (issignalingnan(Fs1)) {
1236                            Fd = numeric_limits<double>::signaling_NaN();
1237                            feclearexcept(FE_INVALID);
1238                        } else {
1239                            Fd = copysign(Fs1, Fs2);
1240                        }
1241                    }}, FloatMiscOp);
1242                    0x1: fsgnjn_d({{
1243                        if (issignalingnan(Fs1)) {
1244                            Fd = numeric_limits<double>::signaling_NaN();
1245                            feclearexcept(FE_INVALID);
1246                        } else {
1247                            Fd = copysign(Fs1, -Fs2);
1248                        }
1249                    }}, FloatMiscOp);
1250                    0x2: fsgnjx_d({{
1251                        if (issignalingnan(Fs1)) {
1252                            Fd = numeric_limits<double>::signaling_NaN();
1253                            feclearexcept(FE_INVALID);
1254                        } else {
1255                            Fd = Fs1*(signbit(Fs2) ? -1.0 : 1.0);
1256                        }
1257                    }}, FloatMiscOp);
1258                }
1259                0x14: decode ROUND_MODE {
1260                    0x0: fmin_s({{
1261                        uint32_t temp;
1262                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1263                        float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1264                        float fd;
1265
1266                        if (issignalingnan(fs2)) {
1267                            fd = fs1;
1268                            FFLAGS |= FloatInvalid;
1269                        } else if (issignalingnan(fs1)) {
1270                            fd = fs2;
1271                            FFLAGS |= FloatInvalid;
1272                        } else {
1273                            fd = fmin(fs1, fs2);
1274                        }
1275                        Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1276                    }}, FloatCmpOp);
1277                    0x1: fmax_s({{
1278                        uint32_t temp;
1279                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1280                        float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1281                        float fd;
1282
1283                        if (issignalingnan(fs2)) {
1284                            fd = fs1;
1285                            FFLAGS |= FloatInvalid;
1286                        } else if (issignalingnan(fs1)) {
1287                            fd = fs2;
1288                            FFLAGS |= FloatInvalid;
1289                        } else {
1290                            fd = fmax(fs1, fs2);
1291                        }
1292                        Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1293                    }}, FloatCmpOp);
1294                }
1295                0x15: decode ROUND_MODE {
1296                    0x0: fmin_d({{
1297                        if (issignalingnan(Fs2)) {
1298                            Fd = Fs1;
1299                            FFLAGS |= FloatInvalid;
1300                        } else if (issignalingnan(Fs1)) {
1301                            Fd = Fs2;
1302                            FFLAGS |= FloatInvalid;
1303                        } else {
1304                            Fd = fmin(Fs1, Fs2);
1305                        }
1306                    }}, FloatCmpOp);
1307                    0x1: fmax_d({{
1308                        if (issignalingnan(Fs2)) {
1309                            Fd = Fs1;
1310                            FFLAGS |= FloatInvalid;
1311                        } else if (issignalingnan(Fs1)) {
1312                            Fd = Fs2;
1313                            FFLAGS |= FloatInvalid;
1314                        } else {
1315                            Fd = fmax(Fs1, Fs2);
1316                        }
1317                    }}, FloatCmpOp);
1318                }
1319                0x20: fcvt_s_d({{
1320                    if (CONV_SGN != 1) {
1321                        fault = make_shared<IllegalInstFault>("CONV_SGN != 1",
1322                                                              machInst);
1323                    }
1324                    float fd;
1325                    if (issignalingnan(Fs1)) {
1326                        fd = numeric_limits<float>::quiet_NaN();
1327                        FFLAGS |= FloatInvalid;
1328                    } else {
1329                        fd = (float)Fs1;
1330                    }
1331                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1332                }}, FloatCvtOp);
1333                0x21: fcvt_d_s({{
1334                    if (CONV_SGN != 0) {
1335                        fault = make_shared<IllegalInstFault>("CONV_SGN != 0",
1336                                                              machInst);
1337                    }
1338                    uint32_t temp;
1339                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1340
1341                    if (issignalingnan(fs1)) {
1342                        Fd = numeric_limits<double>::quiet_NaN();
1343                        FFLAGS |= FloatInvalid;
1344                    } else {
1345                        Fd = (double)fs1;
1346                    }
1347                }}, FloatCvtOp);
1348                0x2c: fsqrt_s({{
1349                    if (RS2 != 0) {
1350                        fault = make_shared<IllegalInstFault>("source reg x1",
1351                                                              machInst);
1352                    }
1353                    uint32_t temp;
1354                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1355                    float fd;
1356
1357                    if (issignalingnan(Fs1_sf)) {
1358                        FFLAGS |= FloatInvalid;
1359                    }
1360                    fd = sqrt(fs1);
1361                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1362                }}, FloatSqrtOp);
1363                0x2d: fsqrt_d({{
1364                    if (RS2 != 0) {
1365                        fault = make_shared<IllegalInstFault>("source reg x1",
1366                                                              machInst);
1367                    }
1368                    Fd = sqrt(Fs1);
1369                }}, FloatSqrtOp);
1370                0x50: decode ROUND_MODE {
1371                    0x0: fle_s({{
1372                        uint32_t temp;
1373                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1374                        float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1375
1376                        if (std::isnan(fs1) || std::isnan(fs2)) {
1377                            FFLAGS |= FloatInvalid;
1378                            Rd = 0;
1379                        } else {
1380                            Rd = fs1 <= fs2 ? 1 : 0;
1381                        }
1382                    }}, FloatCmpOp);
1383                    0x1: flt_s({{
1384                        uint32_t temp;
1385                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1386                        float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1387
1388                        if (std::isnan(fs1) || std::isnan(fs2)) {
1389                            FFLAGS |= FloatInvalid;
1390                            Rd = 0;
1391                        } else {
1392                            Rd = fs1 < fs2 ? 1 : 0;
1393                        }
1394                    }}, FloatCmpOp);
1395                    0x2: feq_s({{
1396                        uint32_t temp;
1397                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1398                        float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1399
1400                        if (issignalingnan(fs1) || issignalingnan(fs2)) {
1401                            FFLAGS |= FloatInvalid;
1402                        }
1403                        Rd = fs1 == fs2 ? 1 : 0;
1404                    }}, FloatCmpOp);
1405                }
1406                0x51: decode ROUND_MODE {
1407                    0x0: fle_d({{
1408                        if (std::isnan(Fs1) || std::isnan(Fs2)) {
1409                            FFLAGS |= FloatInvalid;
1410                            Rd = 0;
1411                        } else {
1412                            Rd = Fs1 <= Fs2 ? 1 : 0;
1413                        }
1414                    }}, FloatCmpOp);
1415                    0x1: flt_d({{
1416                        if (std::isnan(Fs1) || std::isnan(Fs2)) {
1417                            FFLAGS |= FloatInvalid;
1418                            Rd = 0;
1419                        } else {
1420                            Rd = Fs1 < Fs2 ? 1 : 0;
1421                        }
1422                    }}, FloatCmpOp);
1423                    0x2: feq_d({{
1424                        if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1425                            FFLAGS |= FloatInvalid;
1426                        }
1427                        Rd = Fs1 == Fs2 ? 1 : 0;
1428                    }}, FloatCmpOp);
1429                }
1430                0x60: decode CONV_SGN {
1431                    0x0: fcvt_w_s({{
1432                        uint32_t temp;
1433                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1434
1435                        if (std::isnan(fs1)) {
1436                            Rd_sd = numeric_limits<int32_t>::max();
1437                            FFLAGS |= FloatInvalid;
1438                        } else if (fs1 >= numeric_limits<int32_t>::max()) {
1439                            Rd_sd = numeric_limits<int32_t>::max();
1440                            FFLAGS |= FloatInvalid;
1441                        } else if (fs1 <= numeric_limits<int32_t>::min()) {
1442                            Rd_sd = numeric_limits<int32_t>::min();
1443                            FFLAGS |= FloatInvalid;
1444                        } else {
1445                            Rd_sd = (int32_t)fs1;
1446                        }
1447                    }}, FloatCvtOp);
1448                    0x1: fcvt_wu_s({{
1449                        uint32_t temp;
1450                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1451
1452                        if (std::isnan(fs1)) {
1453                            Rd = numeric_limits<uint64_t>::max();
1454                            FFLAGS |= FloatInvalid;
1455                        } else if (fs1 < 0.0) {
1456                            Rd = 0;
1457                            FFLAGS |= FloatInvalid;
1458                        } else if (fs1 > numeric_limits<uint32_t>::max()) {
1459                            Rd = numeric_limits<uint64_t>::max();
1460                            FFLAGS |= FloatInvalid;
1461                        } else {
1462                            Rd = (uint32_t)fs1;
1463                        }
1464                    }}, FloatCvtOp);
1465                    0x2: fcvt_l_s({{
1466                        uint32_t temp;
1467                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1468
1469                        if (std::isnan(fs1)) {
1470                            Rd_sd = numeric_limits<int64_t>::max();
1471                            FFLAGS |= FloatInvalid;
1472                        } else if (fs1 > numeric_limits<int64_t>::max()) {
1473                            Rd_sd = numeric_limits<int64_t>::max();
1474                            FFLAGS |= FloatInvalid;
1475                        } else if (fs1 < numeric_limits<int64_t>::min()) {
1476                            Rd_sd = numeric_limits<int64_t>::min();
1477                            FFLAGS |= FloatInvalid;
1478                        } else {
1479                            Rd_sd = (int64_t)fs1;
1480                        }
1481                    }}, FloatCvtOp);
1482                    0x3: fcvt_lu_s({{
1483                        uint32_t temp;
1484                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1485
1486                        if (std::isnan(fs1)) {
1487                            Rd = numeric_limits<uint64_t>::max();
1488                            FFLAGS |= FloatInvalid;
1489                        } else if (fs1 < 0.0) {
1490                            Rd = 0;
1491                            FFLAGS |= FloatInvalid;
1492                        } else if (fs1 > numeric_limits<uint64_t>::max()) {
1493                            Rd = numeric_limits<uint64_t>::max();
1494                            FFLAGS |= FloatInvalid;
1495                        } else {
1496                            Rd = (uint64_t)fs1;
1497                        }
1498                    }}, FloatCvtOp);
1499                }
1500                0x61: decode CONV_SGN {
1501                    0x0: fcvt_w_d({{
1502                        if (std::isnan(Fs1)) {
1503                            Rd_sd = numeric_limits<int32_t>::max();
1504                            FFLAGS |= FloatInvalid;
1505                        } else if (Fs1 > numeric_limits<int32_t>::max()) {
1506                            Rd_sd = numeric_limits<int32_t>::max();
1507                            FFLAGS |= FloatInvalid;
1508                        } else if (Fs1 < numeric_limits<int32_t>::min()) {
1509                            Rd_sd = numeric_limits<int32_t>::min();
1510                            FFLAGS |= FloatInvalid;
1511                        } else {
1512                            Rd_sd = (int32_t)Fs1;
1513                        }
1514                    }}, FloatCvtOp);
1515                    0x1: fcvt_wu_d({{
1516                        if (std::isnan(Fs1)) {
1517                            Rd = numeric_limits<uint64_t>::max();
1518                            FFLAGS |= FloatInvalid;
1519                        } else if (Fs1 < 0) {
1520                            Rd = 0;
1521                            FFLAGS |= FloatInvalid;
1522                        } else if (Fs1 > numeric_limits<uint32_t>::max()) {
1523                            Rd = numeric_limits<uint64_t>::max();
1524                            FFLAGS |= FloatInvalid;
1525                        } else {
1526                            Rd = (uint32_t)Fs1;
1527                        }
1528                    }}, FloatCvtOp);
1529                    0x2: fcvt_l_d({{
1530                        if (std::isnan(Fs1)) {
1531                            Rd_sd = numeric_limits<int64_t>::max();
1532                            FFLAGS |= FloatInvalid;
1533                        } else if (Fs1 > numeric_limits<int64_t>::max()) {
1534                            Rd_sd = numeric_limits<int64_t>::max();
1535                            FFLAGS |= FloatInvalid;
1536                        } else if (Fs1 < numeric_limits<int64_t>::min()) {
1537                            Rd_sd = numeric_limits<int64_t>::min();
1538                            FFLAGS |= FloatInvalid;
1539                        } else {
1540                            Rd_sd = Fs1;
1541                        }
1542                    }}, FloatCvtOp);
1543                    0x3: fcvt_lu_d({{
1544                        if (std::isnan(Fs1)) {
1545                            Rd = numeric_limits<uint64_t>::max();
1546                            FFLAGS |= FloatInvalid;
1547                        } else if (Fs1 < 0) {
1548                            Rd = 0;
1549                            FFLAGS |= FloatInvalid;
1550                        } else if (Fs1 > numeric_limits<uint64_t>::max()) {
1551                            Rd = numeric_limits<uint64_t>::max();
1552                            FFLAGS |= FloatInvalid;
1553                        } else {
1554                            Rd = Fs1;
1555                        }
1556                    }}, FloatCvtOp);
1557                }
1558                0x68: decode CONV_SGN {
1559                    0x0: fcvt_s_w({{
1560                        float temp = (float)Rs1_sw;
1561                        Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1562                    }}, FloatCvtOp);
1563                    0x1: fcvt_s_wu({{
1564                        float temp = (float)Rs1_uw;
1565                        Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1566                    }}, FloatCvtOp);
1567                    0x2: fcvt_s_l({{
1568                        float temp = (float)Rs1_sd;
1569                        Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1570                    }}, FloatCvtOp);
1571                    0x3: fcvt_s_lu({{
1572                        float temp = (float)Rs1;
1573                        Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1574                    }}, FloatCvtOp);
1575                }
1576                0x69: decode CONV_SGN {
1577                    0x0: fcvt_d_w({{
1578                        Fd = (double)Rs1_sw;
1579                    }}, FloatCvtOp);
1580                    0x1: fcvt_d_wu({{
1581                        Fd = (double)Rs1_uw;
1582                    }}, FloatCvtOp);
1583                    0x2: fcvt_d_l({{
1584                        Fd = (double)Rs1_sd;
1585                    }}, FloatCvtOp);
1586                    0x3: fcvt_d_lu({{
1587                        Fd = (double)Rs1;
1588                    }}, FloatCvtOp);
1589                }
1590                0x70: decode ROUND_MODE {
1591                    0x0: fmv_x_s({{
1592                        Rd = (uint32_t)Fs1_bits;
1593                        if ((Rd&0x80000000) != 0) {
1594                            Rd |= (0xFFFFFFFFULL << 32);
1595                        }
1596                    }}, FloatCvtOp);
1597                    0x1: fclass_s({{
1598                        uint32_t temp;
1599                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1600                        switch (fpclassify(fs1)) {
1601                          case FP_INFINITE:
1602                            if (signbit(fs1)) {
1603                                Rd = 1 << 0;
1604                            } else {
1605                                Rd = 1 << 7;
1606                            }
1607                            break;
1608                          case FP_NAN:
1609                            if (issignalingnan(fs1)) {
1610                                Rd = 1 << 8;
1611                            } else {
1612                                Rd = 1 << 9;
1613                            }
1614                            break;
1615                          case FP_ZERO:
1616                            if (signbit(fs1)) {
1617                                Rd = 1 << 3;
1618                            } else {
1619                                Rd = 1 << 4;
1620                            }
1621                            break;
1622                          case FP_SUBNORMAL:
1623                            if (signbit(fs1)) {
1624                                Rd = 1 << 2;
1625                            } else {
1626                                Rd = 1 << 5;
1627                            }
1628                            break;
1629                          case FP_NORMAL:
1630                            if (signbit(fs1)) {
1631                                Rd = 1 << 1;
1632                            } else {
1633                                Rd = 1 << 6;
1634                            }
1635                            break;
1636                          default:
1637                            panic("Unknown classification for operand.");
1638                            break;
1639                        }
1640                    }}, FloatMiscOp);
1641                }
1642                0x71: decode ROUND_MODE {
1643                    0x0: fmv_x_d({{
1644                        Rd = Fs1_bits;
1645                    }}, FloatCvtOp);
1646                    0x1: fclass_d({{
1647                        switch (fpclassify(Fs1)) {
1648                          case FP_INFINITE:
1649                            if (signbit(Fs1)) {
1650                                Rd = 1 << 0;
1651                            } else {
1652                                Rd = 1 << 7;
1653                            }
1654                            break;
1655                          case FP_NAN:
1656                            if (issignalingnan(Fs1)) {
1657                                Rd = 1 << 8;
1658                            } else {
1659                                Rd = 1 << 9;
1660                            }
1661                            break;
1662                          case FP_ZERO:
1663                            if (signbit(Fs1)) {
1664                                Rd = 1 << 3;
1665                            } else {
1666                                Rd = 1 << 4;
1667                            }
1668                            break;
1669                          case FP_SUBNORMAL:
1670                            if (signbit(Fs1)) {
1671                                Rd = 1 << 2;
1672                            } else {
1673                                Rd = 1 << 5;
1674                            }
1675                            break;
1676                          case FP_NORMAL:
1677                            if (signbit(Fs1)) {
1678                                Rd = 1 << 1;
1679                            } else {
1680                                Rd = 1 << 6;
1681                            }
1682                            break;
1683                          default:
1684                            panic("Unknown classification for operand.");
1685                            break;
1686                        }
1687                    }}, FloatMiscOp);
1688                }
1689                0x78: fmv_s_x({{
1690                    Fd_bits = (uint64_t)Rs1_uw;
1691                }}, FloatCvtOp);
1692                0x79: fmv_d_x({{
1693                    Fd_bits = Rs1;
1694                }}, FloatCvtOp);
1695            }
1696        }
1697
1698        0x18: decode FUNCT3 {
1699            format BOp {
1700                0x0: beq({{
1701                    if (Rs1 == Rs2) {
1702                        NPC = PC + imm;
1703                    } else {
1704                        NPC = NPC;
1705                    }
1706                }}, IsDirectControl, IsCondControl);
1707                0x1: bne({{
1708                    if (Rs1 != Rs2) {
1709                        NPC = PC + imm;
1710                    } else {
1711                        NPC = NPC;
1712                    }
1713                }}, IsDirectControl, IsCondControl);
1714                0x4: blt({{
1715                    if (Rs1_sd < Rs2_sd) {
1716                        NPC = PC + imm;
1717                    } else {
1718                        NPC = NPC;
1719                    }
1720                }}, IsDirectControl, IsCondControl);
1721                0x5: bge({{
1722                    if (Rs1_sd >= Rs2_sd) {
1723                        NPC = PC + imm;
1724                    } else {
1725                        NPC = NPC;
1726                    }
1727                }}, IsDirectControl, IsCondControl);
1728                0x6: bltu({{
1729                    if (Rs1 < Rs2) {
1730                        NPC = PC + imm;
1731                    } else {
1732                        NPC = NPC;
1733                    }
1734                }}, IsDirectControl, IsCondControl);
1735                0x7: bgeu({{
1736                    if (Rs1 >= Rs2) {
1737                        NPC = PC + imm;
1738                    } else {
1739                        NPC = NPC;
1740                    }
1741                }}, IsDirectControl, IsCondControl);
1742            }
1743        }
1744
1745        0x19: decode FUNCT3 {
1746            0x0: Jump::jalr({{
1747                Rd = NPC;
1748                NPC = (imm + Rs1) & (~0x1);
1749            }}, IsIndirectControl, IsUncondControl, IsCall);
1750        }
1751
1752        0x1b: JOp::jal({{
1753            Rd = NPC;
1754            NPC = PC + imm;
1755        }}, IsDirectControl, IsUncondControl, IsCall);
1756
1757        0x1c: decode FUNCT3 {
1758            format SystemOp {
1759                0x0: decode FUNCT12 {
1760                    0x0: ecall({{
1761                        fault = make_shared<SyscallFault>(
1762                                (PrivilegeMode)xc->readMiscReg(MISCREG_PRV));
1763                    }}, IsSerializeAfter, IsNonSpeculative, IsSyscall,
1764                        No_OpClass);
1765                    0x1: ebreak({{
1766                        fault = make_shared<BreakpointFault>(xc->pcState());
1767                    }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1768                    0x2: uret({{
1769                        STATUS status = xc->readMiscReg(MISCREG_STATUS);
1770                        status.uie = status.upie;
1771                        status.upie = 1;
1772                        xc->setMiscReg(MISCREG_STATUS, status);
1773                        NPC = xc->readMiscReg(MISCREG_UEPC);
1774                    }}, IsReturn);
1775                    0x102: sret({{
1776                        if (xc->readMiscReg(MISCREG_PRV) == PRV_U) {
1777                            fault = make_shared<IllegalInstFault>(
1778                                        "sret in user mode", machInst);
1779                            NPC = NPC;
1780                        } else {
1781                            STATUS status = xc->readMiscReg(MISCREG_STATUS);
1782                            xc->setMiscReg(MISCREG_PRV, status.spp);
1783                            status.sie = status.spie;
1784                            status.spie = 1;
1785                            status.spp = PRV_U;
1786                            xc->setMiscReg(MISCREG_STATUS, status);
1787                            NPC = xc->readMiscReg(MISCREG_SEPC);
1788                        }
1789                    }}, IsReturn);
1790                    0x302: mret({{
1791                        if (xc->readMiscReg(MISCREG_PRV) != PRV_M) {
1792                            fault = make_shared<IllegalInstFault>(
1793                                        "mret at lower privilege", machInst);
1794                            NPC = NPC;
1795                        } else {
1796                            STATUS status = xc->readMiscReg(MISCREG_STATUS);
1797                            xc->setMiscReg(MISCREG_PRV, status.mpp);
1798                            status.mie = status.mpie;
1799                            status.mpie = 1;
1800                            status.mpp = PRV_U;
1801                            xc->setMiscReg(MISCREG_STATUS, status);
1802                            NPC = xc->readMiscReg(MISCREG_MEPC);
1803                        }
1804                    }}, IsReturn);
1805                }
1806            }
1807            format CSROp {
1808                0x1: csrrw({{
1809                    Rd = data;
1810                    data = Rs1;
1811                }}, IsNonSpeculative, No_OpClass);
1812                0x2: csrrs({{
1813                    Rd = data;
1814                    data |= Rs1;
1815                }}, IsNonSpeculative, No_OpClass);
1816                0x3: csrrc({{
1817                    Rd = data;
1818                    data &= ~Rs1;
1819                }}, IsNonSpeculative, No_OpClass);
1820                0x5: csrrwi({{
1821                    Rd = data;
1822                    data = uimm;
1823                }}, IsNonSpeculative, No_OpClass);
1824                0x6: csrrsi({{
1825                    Rd = data;
1826                    data |= uimm;
1827                }}, IsNonSpeculative, No_OpClass);
1828                0x7: csrrci({{
1829                    Rd = data;
1830                    data &= ~uimm;
1831                }}, IsNonSpeculative, No_OpClass);
1832            }
1833        }
1834    }
1835}
1836