decoder.isa revision 11729:f37b5fcd66fe
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, aq=AQ, rl=RL);
174            0x3: StoreCond::sc_w({{
175                Mem_uw = Rs2_uw;
176            }}, {{
177                Rd = result;
178            }}, inst_flags=IsStoreConditional, mem_flags=LLSC, aq=AQ, rl=RL);
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, aq=AQ, rl=RL);
222            0x3: StoreCond::sc_d({{
223                Mem = Rs2;
224            }}, {{
225                Rd = result;
226            }}, mem_flags=LLSC, inst_flags=IsStoreConditional, aq=AQ, rl=RL);
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 FPR4Op {
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
685    0x53: decode FUNCT7 {
686        format FPROp {
687            0x0: fadd_s({{
688                uint32_t temp;
689                float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
690                float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
691                float fd;
692
693                if (std::isnan(fs1) || std::isnan(fs2)) {
694                    if (issignalingnan(fs1) || issignalingnan(fs2)) {
695                        FFLAGS |= FloatInvalid;
696                    }
697                    fd = std::numeric_limits<float>::quiet_NaN();
698                } else {
699                    fd = fs1 + fs2;
700                }
701                Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
702            }}, FloatAddOp);
703            0x1: fadd_d({{
704                if (std::isnan(Fs1) || std::isnan(Fs2)) {
705                    if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
706                        FFLAGS |= FloatInvalid;
707                    }
708                    Fd = std::numeric_limits<double>::quiet_NaN();
709                } else {
710                    Fd = Fs1 + Fs2;
711                }
712            }}, FloatAddOp);
713            0x4: fsub_s({{
714                uint32_t temp;
715                float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
716                float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
717                float fd;
718
719                if (std::isnan(fs1) || std::isnan(fs2)) {
720                    if (issignalingnan(fs1) || issignalingnan(fs2)) {
721                        FFLAGS |= FloatInvalid;
722                    }
723                    fd = std::numeric_limits<float>::quiet_NaN();
724                } else {
725                    fd = fs1 - fs2;
726                }
727                Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
728            }}, FloatAddOp);
729            0x5: fsub_d({{
730                if (std::isnan(Fs1) || std::isnan(Fs2)) {
731                    if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
732                        FFLAGS |= FloatInvalid;
733                    }
734                    Fd = std::numeric_limits<double>::quiet_NaN();
735                } else {
736                    Fd = Fs1 - Fs2;
737                }
738            }}, FloatAddOp);
739            0x8: fmul_s({{
740                uint32_t temp;
741                float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
742                float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
743                float fd;
744
745                if (std::isnan(fs1) || std::isnan(fs2)) {
746                    if (issignalingnan(fs1) || issignalingnan(fs2)) {
747                        FFLAGS |= FloatInvalid;
748                    }
749                    fd = std::numeric_limits<float>::quiet_NaN();
750                } else {
751                    fd = fs1*fs2;
752                }
753                Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
754            }}, FloatMultOp);
755            0x9: fmul_d({{
756                if (std::isnan(Fs1) || std::isnan(Fs2)) {
757                    if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
758                        FFLAGS |= FloatInvalid;
759                    }
760                    Fd = std::numeric_limits<double>::quiet_NaN();
761                } else {
762                    Fd = Fs1*Fs2;
763                }
764            }}, FloatMultOp);
765            0xc: fdiv_s({{
766                uint32_t temp;
767                float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
768                float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
769                float fd;
770
771                if (std::isnan(fs1) || std::isnan(fs2)) {
772                    if (issignalingnan(fs1) || issignalingnan(fs2)) {
773                        FFLAGS |= FloatInvalid;
774                    }
775                    fd = std::numeric_limits<float>::quiet_NaN();
776                } else {
777                    fd = fs1/fs2;
778                }
779                Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
780            }}, FloatDivOp);
781            0xd: fdiv_d({{
782                if (std::isnan(Fs1) || std::isnan(Fs2)) {
783                    if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
784                        FFLAGS |= FloatInvalid;
785                    }
786                    Fd = std::numeric_limits<double>::quiet_NaN();
787                } else {
788                    Fd = Fs1/Fs2;
789                }
790            }}, FloatDivOp);
791            0x10: decode ROUND_MODE {
792                0x0: fsgnj_s({{
793                    uint32_t temp;
794                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
795                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
796                    float fd;
797
798                    if (issignalingnan(fs1)) {
799                        fd = std::numeric_limits<float>::signaling_NaN();
800                        std::feclearexcept(FE_INVALID);
801                    } else {
802                        fd = std::copysign(fs1, fs2);
803                    }
804                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
805                }});
806                0x1: fsgnjn_s({{
807                    uint32_t temp;
808                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
809                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
810                    float fd;
811
812                    if (issignalingnan(fs1)) {
813                        fd = std::numeric_limits<float>::signaling_NaN();
814                        std::feclearexcept(FE_INVALID);
815                    } else {
816                        fd = std::copysign(fs1, -fs2);
817                    }
818                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
819                }});
820                0x2: fsgnjx_s({{
821                    uint32_t temp;
822                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
823                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
824                    float fd;
825
826                    if (issignalingnan(fs1)) {
827                        fd = std::numeric_limits<float>::signaling_NaN();
828                        std::feclearexcept(FE_INVALID);
829                    } else {
830                        fd = fs1*(std::signbit(fs2) ? -1.0 : 1.0);
831                    }
832                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
833                }});
834            }
835            0x11: decode ROUND_MODE {
836                0x0: fsgnj_d({{
837                    if (issignalingnan(Fs1)) {
838                        Fd = std::numeric_limits<double>::signaling_NaN();
839                        std::feclearexcept(FE_INVALID);
840                    } else {
841                        Fd = std::copysign(Fs1, Fs2);
842                    }
843                }});
844                0x1: fsgnjn_d({{
845                    if (issignalingnan(Fs1)) {
846                        Fd = std::numeric_limits<double>::signaling_NaN();
847                        std::feclearexcept(FE_INVALID);
848                    } else {
849                        Fd = std::copysign(Fs1, -Fs2);
850                    }
851                }});
852                0x2: fsgnjx_d({{
853                    if (issignalingnan(Fs1)) {
854                        Fd = std::numeric_limits<double>::signaling_NaN();
855                        std::feclearexcept(FE_INVALID);
856                    } else {
857                        Fd = Fs1*(std::signbit(Fs2) ? -1.0 : 1.0);
858                    }
859                }});
860            }
861            0x14: decode ROUND_MODE {
862                0x0: fmin_s({{
863                    uint32_t temp;
864                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
865                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
866                    float fd;
867
868                    if (issignalingnan(fs2)) {
869                        fd = fs1;
870                        FFLAGS |= FloatInvalid;
871                    } else if (issignalingnan(fs1)) {
872                        fd = fs2;
873                        FFLAGS |= FloatInvalid;
874                    } else {
875                        fd = std::fmin(fs1, fs2);
876                    }
877                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
878                }}, FloatCmpOp);
879                0x1: fmax_s({{
880                    uint32_t temp;
881                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
882                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
883                    float fd;
884
885                    if (issignalingnan(fs2)) {
886                        fd = fs1;
887                        FFLAGS |= FloatInvalid;
888                    } else if (issignalingnan(fs1)) {
889                        fd = fs2;
890                        FFLAGS |= FloatInvalid;
891                    } else {
892                        fd = std::fmax(fs1, fs2);
893                    }
894                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
895                }}, FloatCmpOp);
896            }
897            0x15: decode ROUND_MODE {
898                0x0: fmin_d({{
899                    if (issignalingnan(Fs2)) {
900                        Fd = Fs1;
901                        FFLAGS |= FloatInvalid;
902                    } else if (issignalingnan(Fs1)) {
903                        Fd = Fs2;
904                        FFLAGS |= FloatInvalid;
905                    } else {
906                        Fd = std::fmin(Fs1, Fs2);
907                    }
908                }}, FloatCmpOp);
909                0x1: fmax_d({{
910                    if (issignalingnan(Fs2)) {
911                        Fd = Fs1;
912                        FFLAGS |= FloatInvalid;
913                    } else if (issignalingnan(Fs1)) {
914                        Fd = Fs2;
915                        FFLAGS |= FloatInvalid;
916                    } else {
917                        Fd = std::fmax(Fs1, Fs2);
918                    }
919                }}, FloatCmpOp);
920            }
921            0x20: fcvt_s_d({{
922                assert(CONV_SGN == 1);
923                float fd;
924                if (issignalingnan(Fs1)) {
925                    fd = std::numeric_limits<float>::quiet_NaN();
926                    FFLAGS |= FloatInvalid;
927                } else {
928                    fd = (float)Fs1;
929                }
930                Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
931            }}, FloatCvtOp);
932            0x21: fcvt_d_s({{
933                assert(CONV_SGN == 0);
934                uint32_t temp;
935                float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
936
937                if (issignalingnan(fs1)) {
938                    Fd = std::numeric_limits<double>::quiet_NaN();
939                    FFLAGS |= FloatInvalid;
940                } else {
941                    Fd = (double)fs1;
942                }
943            }}, FloatCvtOp);
944            0x2c: fsqrt_s({{
945                assert(RS2 == 0);
946                uint32_t temp;
947                float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
948                float fd;
949
950                if (issignalingnan(Fs1_sf)) {
951                    FFLAGS |= FloatInvalid;
952                }
953                fd = std::sqrt(fs1);
954                Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
955            }}, FloatSqrtOp);
956            0x2d: fsqrt_d({{
957                assert(RS2 == 0);
958                Fd = std::sqrt(Fs1);
959            }}, FloatSqrtOp);
960            0x50: decode ROUND_MODE {
961                0x0: fle_s({{
962                    uint32_t temp;
963                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
964                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
965
966                    if (std::isnan(fs1) || std::isnan(fs2)) {
967                        FFLAGS |= FloatInvalid;
968                        Rd = 0;
969                    } else {
970                        Rd = fs1 <= fs2 ? 1 : 0;
971                    }
972                }}, FloatCmpOp);
973                0x1: flt_s({{
974                    uint32_t temp;
975                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
976                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
977
978                    if (std::isnan(fs1) || std::isnan(fs2)) {
979                        FFLAGS |= FloatInvalid;
980                        Rd = 0;
981                    } else {
982                        Rd = fs1 < fs2 ? 1 : 0;
983                    }
984                }}, FloatCmpOp);
985                0x2: feq_s({{
986                    uint32_t temp;
987                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
988                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
989
990                    if (issignalingnan(fs1) || issignalingnan(fs2)) {
991                        FFLAGS |= FloatInvalid;
992                    }
993                    Rd = fs1 == fs2 ? 1 : 0;
994                }}, FloatCmpOp);
995            }
996            0x51: decode ROUND_MODE {
997                0x0: fle_d({{
998                    if (std::isnan(Fs1) || std::isnan(Fs2)) {
999                        FFLAGS |= FloatInvalid;
1000                        Rd = 0;
1001                    } else {
1002                        Rd = Fs1 <= Fs2 ? 1 : 0;
1003                    }
1004                }}, FloatCmpOp);
1005                0x1: flt_d({{
1006                    if (std::isnan(Fs1) || std::isnan(Fs2)) {
1007                        FFLAGS |= FloatInvalid;
1008                        Rd = 0;
1009                    } else {
1010                        Rd = Fs1 < Fs2 ? 1 : 0;
1011                    }
1012                }}, FloatCmpOp);
1013                0x2: feq_d({{
1014                    if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1015                        FFLAGS |= FloatInvalid;
1016                    }
1017                    Rd = Fs1 == Fs2 ? 1 : 0;
1018                }}, FloatCmpOp);
1019            }
1020            0x60: decode CONV_SGN {
1021                0x0: fcvt_w_s({{
1022                    uint32_t temp;
1023                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1024
1025                    if (std::isnan(fs1)) {
1026                        Rd_sd = std::numeric_limits<int32_t>::max();
1027                        FFLAGS |= FloatInvalid;
1028                    } else {
1029                        Rd_sd = (int32_t)fs1;
1030                        if (std::fetestexcept(FE_INVALID)) {
1031                            if (std::signbit(fs1)) {
1032                                Rd_sd = std::numeric_limits<int32_t>::min();
1033                            } else {
1034                                Rd_sd = std::numeric_limits<int32_t>::max();
1035                            }
1036                            std::feclearexcept(FE_INEXACT);
1037                        }
1038                    }
1039                }}, FloatCvtOp);
1040                0x1: fcvt_wu_s({{
1041                    uint32_t temp;
1042                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1043
1044                    if (fs1 < 0.0) {
1045                        Rd = 0;
1046                        FFLAGS |= FloatInvalid;
1047                    } else {
1048                        Rd = (uint32_t)fs1;
1049                        if (std::fetestexcept(FE_INVALID)) {
1050                            Rd = std::numeric_limits<uint64_t>::max();
1051                            std::feclearexcept(FE_INEXACT);
1052                        }
1053                    }
1054                }}, FloatCvtOp);
1055                0x2: fcvt_l_s({{
1056                    uint32_t temp;
1057                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1058
1059                    if (std::isnan(fs1)) {
1060                        Rd_sd = std::numeric_limits<int64_t>::max();
1061                        FFLAGS |= FloatInvalid;
1062                    } else {
1063                        Rd_sd = (int64_t)fs1;
1064                        if (std::fetestexcept(FE_INVALID)) {
1065                            if (std::signbit(fs1)) {
1066                                Rd_sd = std::numeric_limits<int64_t>::min();
1067                            } else {
1068                                Rd_sd = std::numeric_limits<int64_t>::max();
1069                            }
1070                            std::feclearexcept(FE_INEXACT);
1071                        }
1072                    }
1073                }}, FloatCvtOp);
1074                0x3: fcvt_lu_s({{
1075                    uint32_t temp;
1076                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1077
1078                    if (fs1 < 0.0) {
1079                        Rd = 0;
1080                        FFLAGS |= FloatInvalid;
1081                    } else {
1082                        Rd = (uint64_t)fs1;
1083                        if (std::fetestexcept(FE_INVALID)) {
1084                            Rd = std::numeric_limits<uint64_t>::max();
1085                            std::feclearexcept(FE_INEXACT);
1086                        }
1087                    }
1088                }}, FloatCvtOp);
1089            }
1090            0x61: decode CONV_SGN {
1091                0x0: fcvt_w_d({{
1092                    Rd_sd = (int32_t)Fs1;
1093                    if (std::fetestexcept(FE_INVALID)) {
1094                        if (Fs1 < 0.0) {
1095                            Rd_sd = std::numeric_limits<int32_t>::min();
1096                        } else {
1097                            Rd_sd = std::numeric_limits<int32_t>::max();
1098                        }
1099                        std::feclearexcept(FE_INEXACT);
1100                    }
1101                }}, FloatCvtOp);
1102                0x1: fcvt_wu_d({{
1103                    if (Fs1 < 0.0) {
1104                        Rd = 0;
1105                        FFLAGS |= FloatInvalid;
1106                    } else {
1107                        Rd = (uint32_t)Fs1;
1108                        if (std::fetestexcept(FE_INVALID)) {
1109                            Rd = std::numeric_limits<uint64_t>::max();
1110                            std::feclearexcept(FE_INEXACT);
1111                        }
1112                    }
1113                }}, FloatCvtOp);
1114                0x2: fcvt_l_d({{
1115                    Rd_sd = Fs1;
1116                    if (std::fetestexcept(FE_INVALID)) {
1117                        if (Fs1 < 0.0) {
1118                            Rd_sd = std::numeric_limits<int64_t>::min();
1119                        } else {
1120                            Rd_sd = std::numeric_limits<int64_t>::max();
1121                        }
1122                        std::feclearexcept(FE_INEXACT);
1123                    }
1124                }}, FloatCvtOp);
1125                0x3: fcvt_lu_d({{
1126                    if (Fs1 < 0.0) {
1127                        Rd = 0;
1128                        FFLAGS |= FloatInvalid;
1129                    } else {
1130                        Rd = (uint64_t)Fs1;
1131                        if (std::fetestexcept(FE_INVALID)) {
1132                            Rd = std::numeric_limits<uint64_t>::max();
1133                            std::feclearexcept(FE_INEXACT);
1134                        }
1135                    }
1136                }}, FloatCvtOp);
1137            }
1138            0x68: decode CONV_SGN {
1139                0x0: fcvt_s_w({{
1140                    float temp = (float)Rs1_sw;
1141                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1142                }}, FloatCvtOp);
1143                0x1: fcvt_s_wu({{
1144                    float temp = (float)Rs1_uw;
1145                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1146                }}, FloatCvtOp);
1147                0x2: fcvt_s_l({{
1148                    float temp = (float)Rs1_sd;
1149                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1150                }}, FloatCvtOp);
1151                0x3: fcvt_s_lu({{
1152                    float temp = (float)Rs1;
1153                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1154                }}, FloatCvtOp);
1155            }
1156            0x69: decode CONV_SGN {
1157                0x0: fcvt_d_w({{
1158                    Fd = (double)Rs1_sw;
1159                }}, FloatCvtOp);
1160                0x1: fcvt_d_wu({{
1161                    Fd = (double)Rs1_uw;
1162                }}, FloatCvtOp);
1163                0x2: fcvt_d_l({{
1164                    Fd = (double)Rs1_sd;
1165                }}, FloatCvtOp);
1166                0x3: fcvt_d_lu({{
1167                    Fd = (double)Rs1;
1168                }}, FloatCvtOp);
1169            }
1170            0x70: decode ROUND_MODE {
1171                0x0: fmv_x_s({{
1172                    Rd = (uint32_t)Fs1_bits;
1173                    if ((Rd&0x80000000) != 0) {
1174                        Rd |= (0xFFFFFFFFULL << 32);
1175                    }
1176                }}, FloatCvtOp);
1177                0x1: fclass_s({{
1178                    uint32_t temp;
1179                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1180                    switch (std::fpclassify(fs1)) {
1181                    case FP_INFINITE:
1182                        if (std::signbit(fs1)) {
1183                            Rd = 1 << 0;
1184                        } else {
1185                            Rd = 1 << 7;
1186                        }
1187                        break;
1188                    case FP_NAN:
1189                        if (issignalingnan(fs1)) {
1190                            Rd = 1 << 8;
1191                        } else {
1192                            Rd = 1 << 9;
1193                        }
1194                        break;
1195                    case FP_ZERO:
1196                        if (std::signbit(fs1)) {
1197                            Rd = 1 << 3;
1198                        } else {
1199                            Rd = 1 << 4;
1200                        }
1201                        break;
1202                    case FP_SUBNORMAL:
1203                        if (std::signbit(fs1)) {
1204                            Rd = 1 << 2;
1205                        } else {
1206                            Rd = 1 << 5;
1207                        }
1208                        break;
1209                    case FP_NORMAL:
1210                        if (std::signbit(fs1)) {
1211                            Rd = 1 << 1;
1212                        } else {
1213                            Rd = 1 << 6;
1214                        }
1215                        break;
1216                    default:
1217                        panic("Unknown classification for operand.");
1218                        break;
1219                    }
1220                }});
1221            }
1222            0x71: decode ROUND_MODE {
1223                0x0: fmv_x_d({{
1224                    Rd = Fs1_bits;
1225                }}, FloatCvtOp);
1226                0x1: fclass_d({{
1227                    switch (std::fpclassify(Fs1)) {
1228                    case FP_INFINITE:
1229                        if (std::signbit(Fs1)) {
1230                            Rd = 1 << 0;
1231                        } else {
1232                            Rd = 1 << 7;
1233                        }
1234                        break;
1235                    case FP_NAN:
1236                        if (issignalingnan(Fs1)) {
1237                            Rd = 1 << 8;
1238                        } else {
1239                            Rd = 1 << 9;
1240                        }
1241                        break;
1242                    case FP_ZERO:
1243                        if (std::signbit(Fs1)) {
1244                            Rd = 1 << 3;
1245                        } else {
1246                            Rd = 1 << 4;
1247                        }
1248                        break;
1249                    case FP_SUBNORMAL:
1250                        if (std::signbit(Fs1)) {
1251                            Rd = 1 << 2;
1252                        } else {
1253                            Rd = 1 << 5;
1254                        }
1255                        break;
1256                    case FP_NORMAL:
1257                        if (std::signbit(Fs1)) {
1258                            Rd = 1 << 1;
1259                        } else {
1260                            Rd = 1 << 6;
1261                        }
1262                        break;
1263                    default:
1264                        panic("Unknown classification for operand.");
1265                        break;
1266                    }
1267                }});
1268            }
1269            0x78: fmv_s_x({{
1270                Fd_bits = (uint64_t)Rs1_uw;
1271            }}, FloatCvtOp);
1272            0x79: fmv_d_x({{
1273                Fd_bits = Rs1;
1274            }}, FloatCvtOp);
1275        }
1276    }
1277    0x63: decode FUNCT3 {
1278        format SBOp {
1279            0x0: beq({{
1280                if (Rs1 == Rs2) {
1281                    NPC = PC + imm;
1282                } else {
1283                    NPC = NPC;
1284                }
1285            }}, IsDirectControl, IsCondControl);
1286            0x1: bne({{
1287                if (Rs1 != Rs2) {
1288                    NPC = PC + imm;
1289                } else {
1290                    NPC = NPC;
1291                }
1292            }}, IsDirectControl, IsCondControl);
1293            0x4: blt({{
1294                if (Rs1_sd < Rs2_sd) {
1295                    NPC = PC + imm;
1296                } else {
1297                    NPC = NPC;
1298                }
1299            }}, IsDirectControl, IsCondControl);
1300            0x5: bge({{
1301                if (Rs1_sd >= Rs2_sd) {
1302                    NPC = PC + imm;
1303                } else {
1304                    NPC = NPC;
1305                }
1306            }}, IsDirectControl, IsCondControl);
1307            0x6: bltu({{
1308                if (Rs1 < Rs2) {
1309                    NPC = PC + imm;
1310                } else {
1311                    NPC = NPC;
1312                }
1313            }}, IsDirectControl, IsCondControl);
1314            0x7: bgeu({{
1315                if (Rs1 >= Rs2) {
1316                    NPC = PC + imm;
1317                } else {
1318                    NPC = NPC;
1319                }
1320            }}, IsDirectControl, IsCondControl);
1321        }
1322    }
1323
1324    0x67: decode FUNCT3 {
1325        0x0: Jump::jalr({{
1326            Rd = NPC;
1327            NPC = (imm + Rs1) & (~0x1);
1328        }}, IsIndirectControl, IsUncondControl, IsCall);
1329    }
1330
1331    0x6f: UJOp::jal({{
1332        Rd = NPC;
1333        NPC = PC + imm;
1334    }}, IsDirectControl, IsUncondControl, IsCall);
1335
1336    0x73: decode FUNCT3 {
1337        format IOp {
1338            0x0: decode FUNCT12 {
1339                0x0: ecall({{
1340                    fault = std::make_shared<SyscallFault>();
1341                }}, IsSerializeAfter, IsNonSpeculative, IsSyscall, No_OpClass);
1342                0x1: ebreak({{
1343                    fault = std::make_shared<BreakpointFault>();
1344                }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1345                0x100: eret({{
1346                    fault = std::make_shared<UnimplementedFault>("eret");
1347                }}, No_OpClass);
1348            }
1349            0x1: csrrw({{
1350                Rd = xc->readMiscReg(FUNCT12);
1351                xc->setMiscReg(FUNCT12, Rs1);
1352            }}, IsNonSpeculative, No_OpClass);
1353            0x2: csrrs({{
1354                Rd = xc->readMiscReg(FUNCT12);
1355                if (Rs1 != 0) {
1356                    xc->setMiscReg(FUNCT12, Rd | Rs1);
1357                }
1358            }}, IsNonSpeculative, No_OpClass);
1359            0x3: csrrc({{
1360                Rd = xc->readMiscReg(FUNCT12);
1361                if (Rs1 != 0) {
1362                    xc->setMiscReg(FUNCT12, Rd & ~Rs1);
1363                }
1364            }}, IsNonSpeculative, No_OpClass);
1365            0x5: csrrwi({{
1366                Rd = xc->readMiscReg(FUNCT12);
1367                xc->setMiscReg(FUNCT12, ZIMM);
1368            }}, IsNonSpeculative, No_OpClass);
1369            0x6: csrrsi({{
1370                Rd = xc->readMiscReg(FUNCT12);
1371                if (ZIMM != 0) {
1372                    xc->setMiscReg(FUNCT12, Rd | ZIMM);
1373                }
1374            }}, IsNonSpeculative, No_OpClass);
1375            0x7: csrrci({{
1376                Rd = xc->readMiscReg(FUNCT12);
1377                if (ZIMM != 0) {
1378                    xc->setMiscReg(FUNCT12, Rd & ~ZIMM);
1379                }
1380            }}, IsNonSpeculative, No_OpClass);
1381        }
1382    }
1383}
1384