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