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