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