decoder.isa revision 12136:1070125670e2
14524Sgblack@eecs.umich.edu// -*- mode:c++ -*-
24524Sgblack@eecs.umich.edu
34524Sgblack@eecs.umich.edu// Copyright (c) 2015 RISC-V Foundation
44524Sgblack@eecs.umich.edu// Copyright (c) 2017 The University of Virginia
54524Sgblack@eecs.umich.edu// All rights reserved.
64524Sgblack@eecs.umich.edu//
74524Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
84524Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are
94524Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright
104524Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
114524Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
124524Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
134524Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution;
144524Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its
154524Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from
164524Sgblack@eecs.umich.edu// this software without specific prior written permission.
174524Sgblack@eecs.umich.edu//
184524Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
194524Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
204524Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
214524Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
224524Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
234524Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
244524Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
254524Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
264524Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
274524Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
284524Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
294524Sgblack@eecs.umich.edu//
304524Sgblack@eecs.umich.edu// Authors: Alec Roelke
314524Sgblack@eecs.umich.edu
324524Sgblack@eecs.umich.edu////////////////////////////////////////////////////////////////////
334524Sgblack@eecs.umich.edu//
344524Sgblack@eecs.umich.edu// The RISC-V ISA decoder
354524Sgblack@eecs.umich.edu//
364524Sgblack@eecs.umich.edu
374524Sgblack@eecs.umich.edudecode QUADRANT default Unknown::unknown() {
384524Sgblack@eecs.umich.edu    0x0: decode COPCODE {
394524Sgblack@eecs.umich.edu        0x0: CUIOp::c_addi4spn({{
404524Sgblack@eecs.umich.edu            imm = CIMM8<1:1> << 2 |
414524Sgblack@eecs.umich.edu                  CIMM8<0:0> << 3 |
424524Sgblack@eecs.umich.edu                  CIMM8<7:6> << 4 |
434524Sgblack@eecs.umich.edu                  CIMM8<5:2> << 6;
444524Sgblack@eecs.umich.edu        }}, {{
454524Sgblack@eecs.umich.edu            if (machInst == 0)
464524Sgblack@eecs.umich.edu                fault = make_shared<IllegalInstFault>("zero instruction");
474524Sgblack@eecs.umich.edu            Rp2 = sp + imm;
484524Sgblack@eecs.umich.edu        }});
494524Sgblack@eecs.umich.edu        format CompressedLoad {
504524Sgblack@eecs.umich.edu            0x1: c_fld({{
514524Sgblack@eecs.umich.edu                ldisp = CIMM3 << 3 | CIMM2 << 6;
524524Sgblack@eecs.umich.edu            }}, {{
534524Sgblack@eecs.umich.edu                Fp2_bits = Mem;
544524Sgblack@eecs.umich.edu            }}, {{
554524Sgblack@eecs.umich.edu                EA = Rp1 + ldisp;
564524Sgblack@eecs.umich.edu            }});
574524Sgblack@eecs.umich.edu            0x2: c_lw({{
584524Sgblack@eecs.umich.edu                ldisp = CIMM2<1:1> << 2 |
594524Sgblack@eecs.umich.edu                        CIMM3 << 3 |
604524Sgblack@eecs.umich.edu                        CIMM2<0:0> << 6;
614524Sgblack@eecs.umich.edu            }}, {{
624524Sgblack@eecs.umich.edu                Rp2_sd = Mem_sw;
634524Sgblack@eecs.umich.edu            }}, {{
644524Sgblack@eecs.umich.edu                EA = Rp1 + ldisp;
654524Sgblack@eecs.umich.edu            }});
664524Sgblack@eecs.umich.edu            0x3: c_ld({{
674524Sgblack@eecs.umich.edu                ldisp = CIMM3 << 3 | CIMM2 << 6;
684524Sgblack@eecs.umich.edu            }}, {{
694524Sgblack@eecs.umich.edu                Rp2_sd = Mem_sd;
704524Sgblack@eecs.umich.edu            }}, {{
714524Sgblack@eecs.umich.edu                EA = Rp1 + ldisp;
724524Sgblack@eecs.umich.edu            }});
734524Sgblack@eecs.umich.edu        }
744524Sgblack@eecs.umich.edu        format CompressedStore {
754679Sgblack@eecs.umich.edu            0x5: c_fsd({{
764524Sgblack@eecs.umich.edu                sdisp = CIMM3 << 3 | CIMM2 << 6;
774524Sgblack@eecs.umich.edu            }}, {{
784524Sgblack@eecs.umich.edu                Mem = Fp2_bits;
794524Sgblack@eecs.umich.edu            }}, {{
804693Sgblack@eecs.umich.edu                EA = Rp1 + sdisp;
814524Sgblack@eecs.umich.edu            }});
824524Sgblack@eecs.umich.edu            0x6: c_sw({{
834581Sgblack@eecs.umich.edu                sdisp = CIMM2<1:1> << 2 |
844581Sgblack@eecs.umich.edu                        CIMM3 << 3 |
854581Sgblack@eecs.umich.edu                        CIMM2<0:0> << 6;
864524Sgblack@eecs.umich.edu            }}, {{
874524Sgblack@eecs.umich.edu                Mem_uw = Rp2_uw;
884524Sgblack@eecs.umich.edu            }}, ea_code={{
894524Sgblack@eecs.umich.edu                EA = Rp1 + sdisp;
904693Sgblack@eecs.umich.edu            }});
914524Sgblack@eecs.umich.edu            0x7: c_sd({{
924524Sgblack@eecs.umich.edu                sdisp = CIMM3 << 3 | CIMM2 << 6;
934524Sgblack@eecs.umich.edu            }}, {{
944693Sgblack@eecs.umich.edu                    Mem_ud = Rp2_ud;
954524Sgblack@eecs.umich.edu            }}, {{
964524Sgblack@eecs.umich.edu                EA = Rp1 + sdisp;
974524Sgblack@eecs.umich.edu            }});
984524Sgblack@eecs.umich.edu        }
994524Sgblack@eecs.umich.edu    }
1004581Sgblack@eecs.umich.edu    0x1: decode COPCODE {
1014581Sgblack@eecs.umich.edu        format CIOp {
1024581Sgblack@eecs.umich.edu            0x0: c_addi({{
1034581Sgblack@eecs.umich.edu                imm = CIMM5;
1044581Sgblack@eecs.umich.edu                if (CIMM1 > 0)
1054581Sgblack@eecs.umich.edu                    imm |= ~((uint64_t)0x1F);
1064581Sgblack@eecs.umich.edu            }}, {{
1074693Sgblack@eecs.umich.edu                if ((RC1 == 0) != (imm == 0)) {
1084581Sgblack@eecs.umich.edu                    if (RC1 == 0) {
1094581Sgblack@eecs.umich.edu                        fault = make_shared<IllegalInstFault>("source reg x0");
1104581Sgblack@eecs.umich.edu                    } else // imm == 0
1114581Sgblack@eecs.umich.edu                        fault = make_shared<IllegalInstFault>("immediate = 0");
1124581Sgblack@eecs.umich.edu                }
1134581Sgblack@eecs.umich.edu                Rc1_sd = Rc1_sd + imm;
1144524Sgblack@eecs.umich.edu            }});
1154524Sgblack@eecs.umich.edu            0x1: c_addiw({{
1164524Sgblack@eecs.umich.edu                imm = CIMM5;
1174524Sgblack@eecs.umich.edu                if (CIMM1 > 0)
1184524Sgblack@eecs.umich.edu                    imm |= ~((uint64_t)0x1F);
1194524Sgblack@eecs.umich.edu            }}, {{
1204524Sgblack@eecs.umich.edu                assert(RC1 != 0);
1214524Sgblack@eecs.umich.edu                Rc1_sd = (int32_t)Rc1_sd + imm;
1224524Sgblack@eecs.umich.edu            }});
1234693Sgblack@eecs.umich.edu            0x2: c_li({{
1244524Sgblack@eecs.umich.edu                imm = CIMM5;
1254524Sgblack@eecs.umich.edu                if (CIMM1 > 0)
1264693Sgblack@eecs.umich.edu                    imm |= ~((uint64_t)0x1F);
1274524Sgblack@eecs.umich.edu            }}, {{
1284524Sgblack@eecs.umich.edu                assert(RC1 != 0);
1294524Sgblack@eecs.umich.edu                Rc1_sd = imm;
1304524Sgblack@eecs.umich.edu            }});
1314524Sgblack@eecs.umich.edu            0x3: decode RC1 {
1324524Sgblack@eecs.umich.edu                0x2: c_addi16sp({{
1334524Sgblack@eecs.umich.edu                    imm = CIMM5<4:4> << 4 |
1344693Sgblack@eecs.umich.edu                          CIMM5<0:0> << 5 |
1354524Sgblack@eecs.umich.edu                          CIMM5<3:3> << 6 |
1364524Sgblack@eecs.umich.edu                          CIMM5<2:1> << 7;
1374693Sgblack@eecs.umich.edu                    if (CIMM1 > 0)
1384524Sgblack@eecs.umich.edu                        imm |= ~((int64_t)0x1FF);
1394524Sgblack@eecs.umich.edu                }}, {{
1404524Sgblack@eecs.umich.edu                    assert(imm != 0);
1414524Sgblack@eecs.umich.edu                    sp_sd = sp_sd + imm;
1424524Sgblack@eecs.umich.edu                }});
1434524Sgblack@eecs.umich.edu                default: c_lui({{
1444576Sgblack@eecs.umich.edu                    imm = CIMM5 << 12;
1454524Sgblack@eecs.umich.edu                    if (CIMM1 > 0)
1464576Sgblack@eecs.umich.edu                        imm |= ~((uint64_t)0x1FFFF);
1474576Sgblack@eecs.umich.edu                }}, {{
1484524Sgblack@eecs.umich.edu                    assert(RC1 != 0 && RC1 != 2);
1494524Sgblack@eecs.umich.edu                    assert(imm != 0);
1504693Sgblack@eecs.umich.edu                    Rc1_sd = imm;
1514524Sgblack@eecs.umich.edu                }});
1524524Sgblack@eecs.umich.edu            }
1534576Sgblack@eecs.umich.edu        }
1544693Sgblack@eecs.umich.edu        0x4: decode CFUNCT2HIGH {
1554524Sgblack@eecs.umich.edu            format CUIOp {
1564524Sgblack@eecs.umich.edu                0x0: c_srli({{
1574524Sgblack@eecs.umich.edu                    imm = CIMM5 | (CIMM1 << 5);
1584693Sgblack@eecs.umich.edu                    assert(imm != 0);
1594693Sgblack@eecs.umich.edu                }}, {{
1604576Sgblack@eecs.umich.edu                    Rp1 = Rp1 >> imm;
1614524Sgblack@eecs.umich.edu                }});
1624524Sgblack@eecs.umich.edu                0x1: c_srai({{
1634524Sgblack@eecs.umich.edu                    imm = CIMM5 | (CIMM1 << 5);
1644524Sgblack@eecs.umich.edu                    assert(imm != 0);
1654524Sgblack@eecs.umich.edu                }}, {{
1664524Sgblack@eecs.umich.edu                    Rp1_sd = Rp1_sd >> imm;
1674539Sgblack@eecs.umich.edu                }});
1684524Sgblack@eecs.umich.edu                0x2: c_andi({{
1694524Sgblack@eecs.umich.edu                    imm = CIMM5;
1704524Sgblack@eecs.umich.edu                    if (CIMM1 > 0)
1714581Sgblack@eecs.umich.edu                        imm |= ~((uint64_t)0x1F);
1724524Sgblack@eecs.umich.edu                }}, {{
1734524Sgblack@eecs.umich.edu                    Rp1 = Rp1 & imm;
174                }});
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: CUIOp::c_slli({{
246            imm = CIMM5 | (CIMM1 << 5);
247            assert(imm != 0);
248        }}, {{
249            assert(RC1 != 0);
250            Rc1 = Rc1 << imm;
251        }});
252        format CompressedLoad {
253            0x1: c_fldsp({{
254                ldisp = CIMM5<4:3> << 3 |
255                        CIMM1 << 5 |
256                        CIMM5<2:0> << 6;
257            }}, {{
258                Fc1_bits = Mem;
259            }}, {{
260                EA = sp + ldisp;
261            }});
262            0x2: c_lwsp({{
263                ldisp = 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 + ldisp;
271            }});
272            0x3: c_ldsp({{
273                ldisp = 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 + ldisp;
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                sdisp = CIMM6<5:3> << 3 |
314                        CIMM6<2:0> << 6;
315            }}, {{
316                Mem_ud = Fc2_bits;
317            }}, {{
318                EA = sp + sdisp;
319            }});
320            0x6: c_swsp({{
321                sdisp = CIMM6<5:2> << 2 |
322                        CIMM6<1:0> << 6;
323            }}, {{
324                Mem_uw = Rc2_uw;
325            }}, {{
326                EA = sp + sdisp;
327            }});
328            0x7: c_sdsp({{
329                sdisp = CIMM6<5:3> << 3 |
330                        CIMM6<2:0> << 6;
331            }}, {{
332                Mem = Rc2;
333            }}, {{
334                EA = sp + sdisp;
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                }});
370                0x3: fld({{
371                    Fd_bits = Mem;
372                }});
373            }
374        }
375
376        0x03: decode FUNCT3 {
377            format IOp {
378                0x0: fence({{
379                }}, IsNonSpeculative, IsMemBarrier, No_OpClass);
380                0x1: fence_i({{
381                }}, 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 < (uint64_t)imm) ? 1 : 0;
398                }});
399                0x4: xori({{
400                    Rd = Rs1 ^ (uint64_t)imm;
401                }});
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 | (uint64_t)imm;
412                }});
413                0x7: andi({{
414                    Rd = Rs1 & (uint64_t)imm;
415                }});
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 = (int32_t)Rs1 + (int32_t)imm;
427                }});
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                }});
464                0x3: fsd({{
465                    Mem_ud = Fs2_bits;
466                }});
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 (isnan(fs1) || isnan(fs2) || isnan(fs3)) {
788                        if (issignalingnan(fs1) || issignalingnan(fs2)
789                                || issignalingnan(fs3)) {
790                            FFLAGS |= FloatInvalid;
791                        }
792                        fd = numeric_limits<float>::quiet_NaN();
793                    } else if (isinf(fs1) || isinf(fs2) ||
794                            isinf(fs3)) {
795                        if (signbit(fs1) == signbit(fs2)
796                                && !isinf(fs3)) {
797                            fd = numeric_limits<float>::infinity();
798                        } else if (signbit(fs1) != signbit(fs2)
799                                && !isinf(fs3)) {
800                            fd = -numeric_limits<float>::infinity();
801                        } else { // Fs3_sf is infinity
802                            fd = fs3;
803                        }
804                    } else {
805                        fd = fs1*fs2 + fs3;
806                    }
807                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
808                }}, FloatMultOp);
809                0x1: fmadd_d({{
810                    if (isnan(Fs1) || isnan(Fs2) || isnan(Fs3)) {
811                        if (issignalingnan(Fs1) || issignalingnan(Fs2)
812                                || issignalingnan(Fs3)) {
813                            FFLAGS |= FloatInvalid;
814                        }
815                        Fd = numeric_limits<double>::quiet_NaN();
816                    } else if (isinf(Fs1) || isinf(Fs2) ||
817                            isinf(Fs3)) {
818                        if (signbit(Fs1) == signbit(Fs2)
819                                && !isinf(Fs3)) {
820                            Fd = numeric_limits<double>::infinity();
821                        } else if (signbit(Fs1) != signbit(Fs2)
822                                && !isinf(Fs3)) {
823                            Fd = -numeric_limits<double>::infinity();
824                        } else {
825                            Fd = Fs3;
826                        }
827                    } else {
828                        Fd = Fs1*Fs2 + Fs3;
829                    }
830                }}, FloatMultOp);
831            }
832            0x11: decode FUNCT2 {
833                0x0: fmsub_s({{
834                    uint32_t temp;
835                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
836                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
837                    float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
838                    float fd;
839
840                    if (isnan(fs1) || isnan(fs2) || isnan(fs3)) {
841                        if (issignalingnan(fs1) || issignalingnan(fs2)
842                                || issignalingnan(fs3)) {
843                            FFLAGS |= FloatInvalid;
844                        }
845                        fd = numeric_limits<float>::quiet_NaN();
846                    } else if (isinf(fs1) || isinf(fs2) ||
847                            isinf(fs3)) {
848                        if (signbit(fs1) == signbit(fs2)
849                                && !isinf(fs3)) {
850                            fd = numeric_limits<float>::infinity();
851                        } else if (signbit(fs1) != signbit(fs2)
852                                && !isinf(fs3)) {
853                            fd = -numeric_limits<float>::infinity();
854                        } else { // Fs3_sf is infinity
855                            fd = -fs3;
856                        }
857                    } else {
858                        fd = fs1*fs2 - fs3;
859                    }
860                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
861                }}, FloatMultOp);
862                0x1: fmsub_d({{
863                    if (isnan(Fs1) || isnan(Fs2) || isnan(Fs3)) {
864                        if (issignalingnan(Fs1) || issignalingnan(Fs2)
865                                || issignalingnan(Fs3)) {
866                            FFLAGS |= FloatInvalid;
867                        }
868                        Fd = numeric_limits<double>::quiet_NaN();
869                    } else if (isinf(Fs1) || isinf(Fs2) ||
870                            isinf(Fs3)) {
871                        if (signbit(Fs1) == signbit(Fs2)
872                                && !isinf(Fs3)) {
873                            Fd = numeric_limits<double>::infinity();
874                        } else if (signbit(Fs1) != signbit(Fs2)
875                                && !isinf(Fs3)) {
876                            Fd = -numeric_limits<double>::infinity();
877                        } else {
878                            Fd = -Fs3;
879                        }
880                    } else {
881                        Fd = Fs1*Fs2 - Fs3;
882                    }
883                }}, FloatMultOp);
884            }
885            0x12: decode FUNCT2 {
886                0x0: fnmsub_s({{
887                    uint32_t temp;
888                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
889                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
890                    float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
891                    float fd;
892
893                    if (isnan(fs1) || isnan(fs2) || isnan(fs3)) {
894                        if (issignalingnan(fs1) || issignalingnan(fs2)
895                                || issignalingnan(fs3)) {
896                            FFLAGS |= FloatInvalid;
897                        }
898                        fd = numeric_limits<float>::quiet_NaN();
899                    } else if (isinf(fs1) || isinf(fs2) ||
900                            isinf(fs3)) {
901                        if (signbit(fs1) == signbit(fs2)
902                                && !isinf(fs3)) {
903                            fd = -numeric_limits<float>::infinity();
904                        } else if (signbit(fs1) != signbit(fs2)
905                                && !isinf(fs3)) {
906                            fd = numeric_limits<float>::infinity();
907                        } else { // Fs3_sf is infinity
908                            fd = fs3;
909                        }
910                    } else {
911                        fd = -(fs1*fs2 - fs3);
912                    }
913                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
914                }}, FloatMultOp);
915                0x1: fnmsub_d({{
916                    if (isnan(Fs1) || isnan(Fs2) || isnan(Fs3)) {
917                        if (issignalingnan(Fs1) || issignalingnan(Fs2)
918                                || issignalingnan(Fs3)) {
919                            FFLAGS |= FloatInvalid;
920                        }
921                        Fd = numeric_limits<double>::quiet_NaN();
922                    } else if (isinf(Fs1) || isinf(Fs2)
923                            || isinf(Fs3)) {
924                        if (signbit(Fs1) == signbit(Fs2)
925                                && !isinf(Fs3)) {
926                            Fd = -numeric_limits<double>::infinity();
927                        } else if (signbit(Fs1) != signbit(Fs2)
928                                && !isinf(Fs3)) {
929                            Fd = numeric_limits<double>::infinity();
930                        } else {
931                            Fd = Fs3;
932                        }
933                    } else {
934                        Fd = -(Fs1*Fs2 - Fs3);
935                    }
936                }}, FloatMultOp);
937            }
938            0x13: decode FUNCT2 {
939                0x0: fnmadd_s({{
940                    uint32_t temp;
941                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
942                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
943                    float fs3 = reinterpret_cast<float&>(temp = Fs3_bits);
944                    float fd;
945
946                    if (isnan(fs1) || isnan(fs2) || isnan(fs3)) {
947                        if (issignalingnan(fs1) || issignalingnan(fs2)
948                                || issignalingnan(fs3)) {
949                            FFLAGS |= FloatInvalid;
950                        }
951                        fd = numeric_limits<float>::quiet_NaN();
952                    } else if (isinf(fs1) || isinf(fs2) ||
953                            isinf(fs3)) {
954                        if (signbit(fs1) == signbit(fs2)
955                                && !isinf(fs3)) {
956                            fd = -numeric_limits<float>::infinity();
957                        } else if (signbit(fs1) != signbit(fs2)
958                                && !isinf(fs3)) {
959                            fd = numeric_limits<float>::infinity();
960                        } else { // Fs3_sf is infinity
961                            fd = -fs3;
962                        }
963                    } else {
964                        fd = -(fs1*fs2 + fs3);
965                    }
966                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
967                }}, FloatMultOp);
968                0x1: fnmadd_d({{
969                    if (isnan(Fs1) || isnan(Fs2) || isnan(Fs3)) {
970                        if (issignalingnan(Fs1) || issignalingnan(Fs2)
971                                || issignalingnan(Fs3)) {
972                            FFLAGS |= FloatInvalid;
973                        }
974                        Fd = numeric_limits<double>::quiet_NaN();
975                    } else if (isinf(Fs1) || isinf(Fs2) ||
976                            isinf(Fs3)) {
977                        if (signbit(Fs1) == signbit(Fs2)
978                                && !isinf(Fs3)) {
979                            Fd = -numeric_limits<double>::infinity();
980                        } else if (signbit(Fs1) != signbit(Fs2)
981                                && !isinf(Fs3)) {
982                            Fd = numeric_limits<double>::infinity();
983                        } else {
984                            Fd = -Fs3;
985                        }
986                    } else {
987                        Fd = -(Fs1*Fs2 + Fs3);
988                    }
989                }}, FloatMultOp);
990            }
991            0x14: decode FUNCT7 {
992                0x0: fadd_s({{
993                    uint32_t temp;
994                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
995                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
996                    float fd;
997
998                    if (isnan(fs1) || isnan(fs2)) {
999                        if (issignalingnan(fs1) || issignalingnan(fs2)) {
1000                            FFLAGS |= FloatInvalid;
1001                        }
1002                        fd = numeric_limits<float>::quiet_NaN();
1003                    } else {
1004                        fd = fs1 + fs2;
1005                    }
1006                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1007                }}, FloatAddOp);
1008                0x1: fadd_d({{
1009                    if (isnan(Fs1) || isnan(Fs2)) {
1010                        if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1011                            FFLAGS |= FloatInvalid;
1012                        }
1013                        Fd = numeric_limits<double>::quiet_NaN();
1014                    } else {
1015                        Fd = Fs1 + Fs2;
1016                    }
1017                }}, FloatAddOp);
1018                0x4: fsub_s({{
1019                    uint32_t temp;
1020                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1021                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1022                    float fd;
1023
1024                    if (isnan(fs1) || isnan(fs2)) {
1025                        if (issignalingnan(fs1) || issignalingnan(fs2)) {
1026                            FFLAGS |= FloatInvalid;
1027                        }
1028                        fd = numeric_limits<float>::quiet_NaN();
1029                    } else {
1030                        fd = fs1 - fs2;
1031                    }
1032                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1033                }}, FloatAddOp);
1034                0x5: fsub_d({{
1035                    if (isnan(Fs1) || isnan(Fs2)) {
1036                        if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1037                            FFLAGS |= FloatInvalid;
1038                        }
1039                        Fd = numeric_limits<double>::quiet_NaN();
1040                    } else {
1041                        Fd = Fs1 - Fs2;
1042                    }
1043                }}, FloatAddOp);
1044                0x8: fmul_s({{
1045                    uint32_t temp;
1046                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1047                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1048                    float fd;
1049
1050                    if (isnan(fs1) || isnan(fs2)) {
1051                        if (issignalingnan(fs1) || issignalingnan(fs2)) {
1052                            FFLAGS |= FloatInvalid;
1053                        }
1054                        fd = numeric_limits<float>::quiet_NaN();
1055                    } else {
1056                        fd = fs1*fs2;
1057                    }
1058                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1059                }}, FloatMultOp);
1060                0x9: fmul_d({{
1061                    if (isnan(Fs1) || isnan(Fs2)) {
1062                        if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1063                            FFLAGS |= FloatInvalid;
1064                        }
1065                        Fd = numeric_limits<double>::quiet_NaN();
1066                    } else {
1067                        Fd = Fs1*Fs2;
1068                    }
1069                }}, FloatMultOp);
1070                0xc: fdiv_s({{
1071                    uint32_t temp;
1072                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1073                    float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1074                    float fd;
1075
1076                    if (isnan(fs1) || isnan(fs2)) {
1077                        if (issignalingnan(fs1) || issignalingnan(fs2)) {
1078                            FFLAGS |= FloatInvalid;
1079                        }
1080                        fd = numeric_limits<float>::quiet_NaN();
1081                    } else {
1082                        fd = fs1/fs2;
1083                    }
1084                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1085                }}, FloatDivOp);
1086                0xd: fdiv_d({{
1087                    if (isnan(Fs1) || isnan(Fs2)) {
1088                        if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1089                            FFLAGS |= FloatInvalid;
1090                        }
1091                        Fd = numeric_limits<double>::quiet_NaN();
1092                    } else {
1093                        Fd = Fs1/Fs2;
1094                    }
1095                }}, FloatDivOp);
1096                0x10: decode ROUND_MODE {
1097                    0x0: fsgnj_s({{
1098                        uint32_t temp;
1099                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1100                        float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1101                        float fd;
1102
1103                        if (issignalingnan(fs1)) {
1104                            fd = numeric_limits<float>::signaling_NaN();
1105                            feclearexcept(FE_INVALID);
1106                        } else {
1107                            fd = copysign(fs1, fs2);
1108                        }
1109                        Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1110                    }});
1111                    0x1: fsgnjn_s({{
1112                        uint32_t temp;
1113                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1114                        float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1115                        float fd;
1116
1117                        if (issignalingnan(fs1)) {
1118                            fd = numeric_limits<float>::signaling_NaN();
1119                            feclearexcept(FE_INVALID);
1120                        } else {
1121                            fd = copysign(fs1, -fs2);
1122                        }
1123                        Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1124                    }});
1125                    0x2: fsgnjx_s({{
1126                        uint32_t temp;
1127                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1128                        float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1129                        float fd;
1130
1131                        if (issignalingnan(fs1)) {
1132                            fd = numeric_limits<float>::signaling_NaN();
1133                            feclearexcept(FE_INVALID);
1134                        } else {
1135                            fd = fs1*(signbit(fs2) ? -1.0 : 1.0);
1136                        }
1137                        Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1138                    }});
1139                }
1140                0x11: decode ROUND_MODE {
1141                    0x0: fsgnj_d({{
1142                        if (issignalingnan(Fs1)) {
1143                            Fd = numeric_limits<double>::signaling_NaN();
1144                            feclearexcept(FE_INVALID);
1145                        } else {
1146                            Fd = copysign(Fs1, Fs2);
1147                        }
1148                    }});
1149                    0x1: fsgnjn_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                    }});
1157                    0x2: fsgnjx_d({{
1158                        if (issignalingnan(Fs1)) {
1159                            Fd = numeric_limits<double>::signaling_NaN();
1160                            feclearexcept(FE_INVALID);
1161                        } else {
1162                            Fd = Fs1*(signbit(Fs2) ? -1.0 : 1.0);
1163                        }
1164                    }});
1165                }
1166                0x14: decode ROUND_MODE {
1167                    0x0: fmin_s({{
1168                        uint32_t temp;
1169                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1170                        float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1171                        float fd;
1172
1173                        if (issignalingnan(fs2)) {
1174                            fd = fs1;
1175                            FFLAGS |= FloatInvalid;
1176                        } else if (issignalingnan(fs1)) {
1177                            fd = fs2;
1178                            FFLAGS |= FloatInvalid;
1179                        } else {
1180                            fd = fmin(fs1, fs2);
1181                        }
1182                        Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1183                    }}, FloatCmpOp);
1184                    0x1: fmax_s({{
1185                        uint32_t temp;
1186                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1187                        float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1188                        float fd;
1189
1190                        if (issignalingnan(fs2)) {
1191                            fd = fs1;
1192                            FFLAGS |= FloatInvalid;
1193                        } else if (issignalingnan(fs1)) {
1194                            fd = fs2;
1195                            FFLAGS |= FloatInvalid;
1196                        } else {
1197                            fd = fmax(fs1, fs2);
1198                        }
1199                        Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1200                    }}, FloatCmpOp);
1201                }
1202                0x15: decode ROUND_MODE {
1203                    0x0: fmin_d({{
1204                        if (issignalingnan(Fs2)) {
1205                            Fd = Fs1;
1206                            FFLAGS |= FloatInvalid;
1207                        } else if (issignalingnan(Fs1)) {
1208                            Fd = Fs2;
1209                            FFLAGS |= FloatInvalid;
1210                        } else {
1211                            Fd = fmin(Fs1, Fs2);
1212                        }
1213                    }}, FloatCmpOp);
1214                    0x1: fmax_d({{
1215                        if (issignalingnan(Fs2)) {
1216                            Fd = Fs1;
1217                            FFLAGS |= FloatInvalid;
1218                        } else if (issignalingnan(Fs1)) {
1219                            Fd = Fs2;
1220                            FFLAGS |= FloatInvalid;
1221                        } else {
1222                            Fd = fmax(Fs1, Fs2);
1223                        }
1224                    }}, FloatCmpOp);
1225                }
1226                0x20: fcvt_s_d({{
1227                    assert(CONV_SGN == 1);
1228                    float fd;
1229                    if (issignalingnan(Fs1)) {
1230                        fd = numeric_limits<float>::quiet_NaN();
1231                        FFLAGS |= FloatInvalid;
1232                    } else {
1233                        fd = (float)Fs1;
1234                    }
1235                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1236                }}, FloatCvtOp);
1237                0x21: fcvt_d_s({{
1238                    assert(CONV_SGN == 0);
1239                    uint32_t temp;
1240                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1241
1242                    if (issignalingnan(fs1)) {
1243                        Fd = numeric_limits<double>::quiet_NaN();
1244                        FFLAGS |= FloatInvalid;
1245                    } else {
1246                        Fd = (double)fs1;
1247                    }
1248                }}, FloatCvtOp);
1249                0x2c: fsqrt_s({{
1250                    assert(RS2 == 0);
1251                    uint32_t temp;
1252                    float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1253                    float fd;
1254
1255                    if (issignalingnan(Fs1_sf)) {
1256                        FFLAGS |= FloatInvalid;
1257                    }
1258                    fd = sqrt(fs1);
1259                    Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd);
1260                }}, FloatSqrtOp);
1261                0x2d: fsqrt_d({{
1262                    assert(RS2 == 0);
1263                    Fd = sqrt(Fs1);
1264                }}, FloatSqrtOp);
1265                0x50: decode ROUND_MODE {
1266                    0x0: fle_s({{
1267                        uint32_t temp;
1268                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1269                        float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1270
1271                        if (isnan(fs1) || isnan(fs2)) {
1272                            FFLAGS |= FloatInvalid;
1273                            Rd = 0;
1274                        } else {
1275                            Rd = fs1 <= fs2 ? 1 : 0;
1276                        }
1277                    }}, FloatCmpOp);
1278                    0x1: flt_s({{
1279                        uint32_t temp;
1280                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1281                        float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1282
1283                        if (isnan(fs1) || isnan(fs2)) {
1284                            FFLAGS |= FloatInvalid;
1285                            Rd = 0;
1286                        } else {
1287                            Rd = fs1 < fs2 ? 1 : 0;
1288                        }
1289                    }}, FloatCmpOp);
1290                    0x2: feq_s({{
1291                        uint32_t temp;
1292                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1293                        float fs2 = reinterpret_cast<float&>(temp = Fs2_bits);
1294
1295                        if (issignalingnan(fs1) || issignalingnan(fs2)) {
1296                            FFLAGS |= FloatInvalid;
1297                        }
1298                        Rd = fs1 == fs2 ? 1 : 0;
1299                    }}, FloatCmpOp);
1300                }
1301                0x51: decode ROUND_MODE {
1302                    0x0: fle_d({{
1303                        if (isnan(Fs1) || isnan(Fs2)) {
1304                            FFLAGS |= FloatInvalid;
1305                            Rd = 0;
1306                        } else {
1307                            Rd = Fs1 <= Fs2 ? 1 : 0;
1308                        }
1309                    }}, FloatCmpOp);
1310                    0x1: flt_d({{
1311                        if (isnan(Fs1) || isnan(Fs2)) {
1312                            FFLAGS |= FloatInvalid;
1313                            Rd = 0;
1314                        } else {
1315                            Rd = Fs1 < Fs2 ? 1 : 0;
1316                        }
1317                    }}, FloatCmpOp);
1318                    0x2: feq_d({{
1319                        if (issignalingnan(Fs1) || issignalingnan(Fs2)) {
1320                            FFLAGS |= FloatInvalid;
1321                        }
1322                        Rd = Fs1 == Fs2 ? 1 : 0;
1323                    }}, FloatCmpOp);
1324                }
1325                0x60: decode CONV_SGN {
1326                    0x0: fcvt_w_s({{
1327                        uint32_t temp;
1328                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1329
1330                        if (isnan(fs1)) {
1331                            Rd_sd = numeric_limits<int32_t>::max();
1332                            FFLAGS |= FloatInvalid;
1333                        } else {
1334                            Rd_sd = (int32_t)fs1;
1335                            if (fetestexcept(FE_INVALID)) {
1336                                if (signbit(fs1)) {
1337                                    Rd_sd = numeric_limits<int32_t>::min();
1338                                } else {
1339                                    Rd_sd = numeric_limits<int32_t>::max();
1340                                }
1341                                feclearexcept(FE_INEXACT);
1342                            }
1343                        }
1344                    }}, FloatCvtOp);
1345                    0x1: fcvt_wu_s({{
1346                        uint32_t temp;
1347                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1348
1349                        if (fs1 < 0.0) {
1350                            Rd = 0;
1351                            FFLAGS |= FloatInvalid;
1352                        } else {
1353                            Rd = (uint32_t)fs1;
1354                            if (fetestexcept(FE_INVALID)) {
1355                                Rd = numeric_limits<uint64_t>::max();
1356                                feclearexcept(FE_INEXACT);
1357                            }
1358                        }
1359                    }}, FloatCvtOp);
1360                    0x2: fcvt_l_s({{
1361                        uint32_t temp;
1362                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1363
1364                        if (isnan(fs1)) {
1365                            Rd_sd = numeric_limits<int64_t>::max();
1366                            FFLAGS |= FloatInvalid;
1367                        } else {
1368                            Rd_sd = (int64_t)fs1;
1369                            if (fetestexcept(FE_INVALID)) {
1370                                if (signbit(fs1)) {
1371                                    Rd_sd = numeric_limits<int64_t>::min();
1372                                } else {
1373                                    Rd_sd = numeric_limits<int64_t>::max();
1374                                }
1375                                feclearexcept(FE_INEXACT);
1376                            }
1377                        }
1378                    }}, FloatCvtOp);
1379                    0x3: fcvt_lu_s({{
1380                        uint32_t temp;
1381                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1382
1383                        if (fs1 < 0.0) {
1384                            Rd = 0;
1385                            FFLAGS |= FloatInvalid;
1386                        } else {
1387                            Rd = (uint64_t)fs1;
1388                            if (fetestexcept(FE_INVALID)) {
1389                                Rd = numeric_limits<uint64_t>::max();
1390                                feclearexcept(FE_INEXACT);
1391                            }
1392                        }
1393                    }}, FloatCvtOp);
1394                }
1395                0x61: decode CONV_SGN {
1396                    0x0: fcvt_w_d({{
1397                        Rd_sd = (int32_t)Fs1;
1398                        if (fetestexcept(FE_INVALID)) {
1399                            if (Fs1 < 0.0) {
1400                                Rd_sd = numeric_limits<int32_t>::min();
1401                            } else {
1402                                Rd_sd = numeric_limits<int32_t>::max();
1403                            }
1404                            feclearexcept(FE_INEXACT);
1405                        }
1406                    }}, FloatCvtOp);
1407                    0x1: fcvt_wu_d({{
1408                        if (Fs1 < 0.0) {
1409                            Rd = 0;
1410                            FFLAGS |= FloatInvalid;
1411                        } else {
1412                            Rd = (uint32_t)Fs1;
1413                            if (fetestexcept(FE_INVALID)) {
1414                                Rd = numeric_limits<uint64_t>::max();
1415                                feclearexcept(FE_INEXACT);
1416                            }
1417                        }
1418                    }}, FloatCvtOp);
1419                    0x2: fcvt_l_d({{
1420                        Rd_sd = Fs1;
1421                        if (fetestexcept(FE_INVALID)) {
1422                            if (Fs1 < 0.0) {
1423                                Rd_sd = numeric_limits<int64_t>::min();
1424                            } else {
1425                                Rd_sd = numeric_limits<int64_t>::max();
1426                            }
1427                            feclearexcept(FE_INEXACT);
1428                        }
1429                    }}, FloatCvtOp);
1430                    0x3: fcvt_lu_d({{
1431                        if (Fs1 < 0.0) {
1432                            Rd = 0;
1433                            FFLAGS |= FloatInvalid;
1434                        } else {
1435                            Rd = (uint64_t)Fs1;
1436                            if (fetestexcept(FE_INVALID)) {
1437                                Rd = numeric_limits<uint64_t>::max();
1438                                feclearexcept(FE_INEXACT);
1439                            }
1440                        }
1441                    }}, FloatCvtOp);
1442                }
1443                0x68: decode CONV_SGN {
1444                    0x0: fcvt_s_w({{
1445                        float temp = (float)Rs1_sw;
1446                        Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1447                    }}, FloatCvtOp);
1448                    0x1: fcvt_s_wu({{
1449                        float temp = (float)Rs1_uw;
1450                        Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1451                    }}, FloatCvtOp);
1452                    0x2: fcvt_s_l({{
1453                        float temp = (float)Rs1_sd;
1454                        Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1455                    }}, FloatCvtOp);
1456                    0x3: fcvt_s_lu({{
1457                        float temp = (float)Rs1;
1458                        Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp);
1459                    }}, FloatCvtOp);
1460                }
1461                0x69: decode CONV_SGN {
1462                    0x0: fcvt_d_w({{
1463                        Fd = (double)Rs1_sw;
1464                    }}, FloatCvtOp);
1465                    0x1: fcvt_d_wu({{
1466                        Fd = (double)Rs1_uw;
1467                    }}, FloatCvtOp);
1468                    0x2: fcvt_d_l({{
1469                        Fd = (double)Rs1_sd;
1470                    }}, FloatCvtOp);
1471                    0x3: fcvt_d_lu({{
1472                        Fd = (double)Rs1;
1473                    }}, FloatCvtOp);
1474                }
1475                0x70: decode ROUND_MODE {
1476                    0x0: fmv_x_s({{
1477                        Rd = (uint32_t)Fs1_bits;
1478                        if ((Rd&0x80000000) != 0) {
1479                            Rd |= (0xFFFFFFFFULL << 32);
1480                        }
1481                    }}, FloatCvtOp);
1482                    0x1: fclass_s({{
1483                        uint32_t temp;
1484                        float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
1485                        switch (fpclassify(fs1)) {
1486                        case FP_INFINITE:
1487                            if (signbit(fs1)) {
1488                                Rd = 1 << 0;
1489                            } else {
1490                                Rd = 1 << 7;
1491                            }
1492                            break;
1493                        case FP_NAN:
1494                            if (issignalingnan(fs1)) {
1495                                Rd = 1 << 8;
1496                            } else {
1497                                Rd = 1 << 9;
1498                            }
1499                            break;
1500                        case FP_ZERO:
1501                            if (signbit(fs1)) {
1502                                Rd = 1 << 3;
1503                            } else {
1504                                Rd = 1 << 4;
1505                            }
1506                            break;
1507                        case FP_SUBNORMAL:
1508                            if (signbit(fs1)) {
1509                                Rd = 1 << 2;
1510                            } else {
1511                                Rd = 1 << 5;
1512                            }
1513                            break;
1514                        case FP_NORMAL:
1515                            if (signbit(fs1)) {
1516                                Rd = 1 << 1;
1517                            } else {
1518                                Rd = 1 << 6;
1519                            }
1520                            break;
1521                        default:
1522                            panic("Unknown classification for operand.");
1523                            break;
1524                        }
1525                    }});
1526                }
1527                0x71: decode ROUND_MODE {
1528                    0x0: fmv_x_d({{
1529                        Rd = Fs1_bits;
1530                    }}, FloatCvtOp);
1531                    0x1: fclass_d({{
1532                        switch (fpclassify(Fs1)) {
1533                        case FP_INFINITE:
1534                            if (signbit(Fs1)) {
1535                                Rd = 1 << 0;
1536                            } else {
1537                                Rd = 1 << 7;
1538                            }
1539                            break;
1540                        case FP_NAN:
1541                            if (issignalingnan(Fs1)) {
1542                                Rd = 1 << 8;
1543                            } else {
1544                                Rd = 1 << 9;
1545                            }
1546                            break;
1547                        case FP_ZERO:
1548                            if (signbit(Fs1)) {
1549                                Rd = 1 << 3;
1550                            } else {
1551                                Rd = 1 << 4;
1552                            }
1553                            break;
1554                        case FP_SUBNORMAL:
1555                            if (signbit(Fs1)) {
1556                                Rd = 1 << 2;
1557                            } else {
1558                                Rd = 1 << 5;
1559                            }
1560                            break;
1561                        case FP_NORMAL:
1562                            if (signbit(Fs1)) {
1563                                Rd = 1 << 1;
1564                            } else {
1565                                Rd = 1 << 6;
1566                            }
1567                            break;
1568                        default:
1569                            panic("Unknown classification for operand.");
1570                            break;
1571                        }
1572                    }});
1573                }
1574                0x78: fmv_s_x({{
1575                    Fd_bits = (uint64_t)Rs1_uw;
1576                }}, FloatCvtOp);
1577                0x79: fmv_d_x({{
1578                    Fd_bits = Rs1;
1579                }}, FloatCvtOp);
1580            }
1581        }
1582
1583        0x18: decode FUNCT3 {
1584            format BOp {
1585                0x0: beq({{
1586                    if (Rs1 == Rs2) {
1587                        NPC = PC + imm;
1588                    } else {
1589                        NPC = NPC;
1590                    }
1591                }}, IsDirectControl, IsCondControl);
1592                0x1: bne({{
1593                    if (Rs1 != Rs2) {
1594                        NPC = PC + imm;
1595                    } else {
1596                        NPC = NPC;
1597                    }
1598                }}, IsDirectControl, IsCondControl);
1599                0x4: blt({{
1600                    if (Rs1_sd < Rs2_sd) {
1601                        NPC = PC + imm;
1602                    } else {
1603                        NPC = NPC;
1604                    }
1605                }}, IsDirectControl, IsCondControl);
1606                0x5: bge({{
1607                    if (Rs1_sd >= Rs2_sd) {
1608                        NPC = PC + imm;
1609                    } else {
1610                        NPC = NPC;
1611                    }
1612                }}, IsDirectControl, IsCondControl);
1613                0x6: bltu({{
1614                    if (Rs1 < Rs2) {
1615                        NPC = PC + imm;
1616                    } else {
1617                        NPC = NPC;
1618                    }
1619                }}, IsDirectControl, IsCondControl);
1620                0x7: bgeu({{
1621                    if (Rs1 >= Rs2) {
1622                        NPC = PC + imm;
1623                    } else {
1624                        NPC = NPC;
1625                    }
1626                }}, IsDirectControl, IsCondControl);
1627            }
1628        }
1629
1630        0x19: decode FUNCT3 {
1631            0x0: Jump::jalr({{
1632                Rd = NPC;
1633                NPC = (imm + Rs1) & (~0x1);
1634            }}, IsIndirectControl, IsUncondControl, IsCall);
1635        }
1636
1637        0x1b: JOp::jal({{
1638            Rd = NPC;
1639            NPC = PC + imm;
1640        }}, IsDirectControl, IsUncondControl, IsCall);
1641
1642        0x1c: decode FUNCT3 {
1643            format SystemOp {
1644                0x0: decode FUNCT12 {
1645                    0x0: ecall({{
1646                        fault = make_shared<SyscallFault>();
1647                    }}, IsSerializeAfter, IsNonSpeculative, IsSyscall,
1648                        No_OpClass);
1649                    0x1: ebreak({{
1650                        fault = make_shared<BreakpointFault>();
1651                    }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
1652                    0x100: eret({{
1653                        fault = make_shared<UnimplementedFault>("eret");
1654                    }}, No_OpClass);
1655                }
1656            }
1657            format CSROp {
1658                0x1: csrrw({{
1659                    Rd = xc->readMiscReg(csr);
1660                    xc->setMiscReg(csr, Rs1);
1661                }}, IsNonSpeculative, No_OpClass);
1662                0x2: csrrs({{
1663                    Rd = xc->readMiscReg(csr);
1664                    if (Rs1 != 0) {
1665                        xc->setMiscReg(csr, Rd | Rs1);
1666                    }
1667                }}, IsNonSpeculative, No_OpClass);
1668                0x3: csrrc({{
1669                    Rd = xc->readMiscReg(csr);
1670                    if (Rs1 != 0) {
1671                        xc->setMiscReg(csr, Rd & ~Rs1);
1672                    }
1673                }}, IsNonSpeculative, No_OpClass);
1674                0x5: csrrwi({{
1675                    Rd = xc->readMiscReg(csr);
1676                    xc->setMiscReg(csr, uimm);
1677                }}, IsNonSpeculative, No_OpClass);
1678                0x6: csrrsi({{
1679                    Rd = xc->readMiscReg(csr);
1680                    if (uimm != 0) {
1681                        xc->setMiscReg(csr, Rd | uimm);
1682                    }
1683                }}, IsNonSpeculative, No_OpClass);
1684                0x7: csrrci({{
1685                    Rd = xc->readMiscReg(csr);
1686                    if (uimm != 0) {
1687                        xc->setMiscReg(csr, Rd & ~uimm);
1688                    }
1689                }}, IsNonSpeculative, No_OpClass);
1690            }
1691        }
1692    }
1693}