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