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