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