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