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