decoder.isa revision 11965:41e942451f59
1// -*- mode:c++ -*- 2 3// Copyright (c) 2015 RISC-V Foundation 4// Copyright (c) 2016 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 OPCODE default Unknown::unknown() { 38 0x03: decode FUNCT3 { 39 format Load { 40 0x0: lb({{ 41 Rd_sd = Mem_sb; 42 }}); 43 0x1: lh({{ 44 Rd_sd = Mem_sh; 45 }}); 46 0x2: lw({{ 47 Rd_sd = Mem_sw; 48 }}); 49 0x3: ld({{ 50 Rd_sd = Mem_sd; 51 }}); 52 0x4: lbu({{ 53 Rd = Mem_ub; 54 }}); 55 0x5: lhu({{ 56 Rd = Mem_uh; 57 }}); 58 0x6: lwu({{ 59 Rd = Mem_uw; 60 }}); 61 } 62 } 63 64 0x07: decode FUNCT3 { 65 format Load { 66 0x2: flw({{ 67 Fd_bits = (uint64_t)Mem_uw; 68 }}); 69 0x3: fld({{ 70 Fd_bits = Mem; 71 }}); 72 } 73 } 74 75 0x0f: decode FUNCT3 { 76 format IOp { 77 0x0: fence({{ 78 }}, IsNonSpeculative, IsMemBarrier, No_OpClass); 79 0x1: fence_i({{ 80 }}, IsNonSpeculative, IsSerializeAfter, No_OpClass); 81 } 82 } 83 84 0x13: decode FUNCT3 { 85 format IOp { 86 0x0: addi({{ 87 Rd_sd = Rs1_sd + imm; 88 }}); 89 0x1: slli({{ 90 Rd = Rs1 << SHAMT6; 91 }}); 92 0x2: slti({{ 93 Rd = (Rs1_sd < imm) ? 1 : 0; 94 }}); 95 0x3: sltiu({{ 96 Rd = (Rs1 < (uint64_t)imm) ? 1 : 0; 97 }}); 98 0x4: xori({{ 99 Rd = Rs1 ^ (uint64_t)imm; 100 }}); 101 0x5: decode SRTYPE { 102 0x0: srli({{ 103 Rd = Rs1 >> SHAMT6; 104 }}); 105 0x1: srai({{ 106 Rd_sd = Rs1_sd >> SHAMT6; 107 }}); 108 } 109 0x6: ori({{ 110 Rd = Rs1 | (uint64_t)imm; 111 }}); 112 0x7: andi({{ 113 Rd = Rs1 & (uint64_t)imm; 114 }}); 115 } 116 } 117 118 0x17: UOp::auipc({{ 119 Rd = PC + imm; 120 }}); 121 122 0x1b: decode FUNCT3 { 123 format IOp { 124 0x0: addiw({{ 125 Rd_sd = (int32_t)Rs1 + (int32_t)imm; 126 }}); 127 0x1: slliw({{ 128 Rd_sd = Rs1_sw << SHAMT5; 129 }}); 130 0x5: decode SRTYPE { 131 0x0: srliw({{ 132 Rd = Rs1_uw >> SHAMT5; 133 }}); 134 0x1: sraiw({{ 135 Rd_sd = Rs1_sw >> SHAMT5; 136 }}); 137 } 138 } 139 } 140 141 0x23: decode FUNCT3 { 142 format Store { 143 0x0: sb({{ 144 Mem_ub = Rs2_ub; 145 }}); 146 0x1: sh({{ 147 Mem_uh = Rs2_uh; 148 }}); 149 0x2: sw({{ 150 Mem_uw = Rs2_uw; 151 }}); 152 0x3: sd({{ 153 Mem_ud = Rs2_ud; 154 }}); 155 } 156 } 157 158 0x27: decode FUNCT3 { 159 format Store { 160 0x2: fsw({{ 161 Mem_uw = (uint32_t)Fs2_bits; 162 }}); 163 0x3: fsd({{ 164 Mem_ud = Fs2_bits; 165 }}); 166 } 167 } 168 169 0x2f: decode FUNCT3 { 170 0x2: decode AMOFUNCT { 171 0x2: LoadReserved::lr_w({{ 172 Rd_sd = Mem_sw; 173 }}, mem_flags=LLSC); 174 0x3: StoreCond::sc_w({{ 175 Mem_uw = Rs2_uw; 176 }}, {{ 177 Rd = result; 178 }}, inst_flags=IsStoreConditional, mem_flags=LLSC); 179 format AtomicMemOp { 180 0x0: amoadd_w({{Rt_sd = Mem_sw;}}, {{ 181 Mem_sw = Rs2_sw + Rt_sd; 182 Rd_sd = Rt_sd; 183 }}, {{EA = Rs1;}}); 184 0x1: amoswap_w({{Rt_sd = Mem_sw;}}, {{ 185 Mem_sw = Rs2_uw; 186 Rd_sd = Rt_sd; 187 }}, {{EA = Rs1;}}); 188 0x4: amoxor_w({{Rt_sd = Mem_sw;}}, {{ 189 Mem_sw = Rs2_uw^Rt_sd; 190 Rd_sd = Rt_sd; 191 }}, {{EA = Rs1;}}); 192 0x8: amoor_w({{Rt_sd = Mem_sw;}}, {{ 193 Mem_sw = Rs2_uw | Rt_sd; 194 Rd_sd = Rt_sd; 195 }}, {{EA = Rs1;}}); 196 0xc: amoand_w({{Rt_sd = Mem_sw;}}, {{ 197 Mem_sw = Rs2_uw&Rt_sd; 198 Rd_sd = Rt_sd; 199 }}, {{EA = Rs1;}}); 200 0x10: amomin_w({{Rt_sd = Mem_sw;}}, {{ 201 Mem_sw = std::min<int32_t>(Rs2_sw, Rt_sd); 202 Rd_sd = Rt_sd; 203 }}, {{EA = Rs1;}}); 204 0x14: amomax_w({{Rt_sd = Mem_sw;}}, {{ 205 Mem_sw = std::max<int32_t>(Rs2_sw, Rt_sd); 206 Rd_sd = Rt_sd; 207 }}, {{EA = Rs1;}}); 208 0x18: amominu_w({{Rt_sd = Mem_sw;}}, {{ 209 Mem_sw = std::min<uint32_t>(Rs2_uw, Rt_sd); 210 Rd_sd = Rt_sd; 211 }}, {{EA = Rs1;}}); 212 0x1c: amomaxu_w({{Rt_sd = Mem_sw;}}, {{ 213 Mem_sw = std::max<uint32_t>(Rs2_uw, Rt_sd); 214 Rd_sd = Rt_sd; 215 }}, {{EA = Rs1;}}); 216 } 217 } 218 0x3: decode AMOFUNCT { 219 0x2: LoadReserved::lr_d({{ 220 Rd_sd = Mem_sd; 221 }}, mem_flags=LLSC); 222 0x3: StoreCond::sc_d({{ 223 Mem = Rs2; 224 }}, {{ 225 Rd = result; 226 }}, mem_flags=LLSC, inst_flags=IsStoreConditional); 227 format AtomicMemOp { 228 0x0: amoadd_d({{Rt_sd = Mem_sd;}}, {{ 229 Mem_sd = Rs2_sd + Rt_sd; 230 Rd_sd = Rt_sd; 231 }}, {{EA = Rs1;}}); 232 0x1: amoswap_d({{Rt = Mem;}}, {{ 233 Mem = Rs2; 234 Rd = Rt; 235 }}, {{EA = Rs1;}}); 236 0x4: amoxor_d({{Rt = Mem;}}, {{ 237 Mem = Rs2^Rt; 238 Rd = Rt; 239 }}, {{EA = Rs1;}}); 240 0x8: amoor_d({{Rt = Mem;}}, {{ 241 Mem = Rs2 | Rt; 242 Rd = Rt; 243 }}, {{EA = Rs1;}}); 244 0xc: amoand_d({{Rt = Mem;}}, {{ 245 Mem = Rs2&Rt; 246 Rd = Rt; 247 }}, {{EA = Rs1;}}); 248 0x10: amomin_d({{Rt_sd = Mem_sd;}}, {{ 249 Mem_sd = std::min(Rs2_sd, Rt_sd); 250 Rd_sd = Rt_sd; 251 }}, {{EA = Rs1;}}); 252 0x14: amomax_d({{Rt_sd = Mem_sd;}}, {{ 253 Mem_sd = std::max(Rs2_sd, Rt_sd); 254 Rd_sd = Rt_sd; 255 }}, {{EA = Rs1;}}); 256 0x18: amominu_d({{Rt = Mem;}}, {{ 257 Mem = std::min(Rs2, Rt); 258 Rd = Rt; 259 }}, {{EA = Rs1;}}); 260 0x1c: amomaxu_d({{Rt = Mem;}}, {{ 261 Mem = std::max(Rs2, Rt); 262 Rd = Rt; 263 }}, {{EA = Rs1;}}); 264 } 265 } 266 } 267 0x33: decode FUNCT3 { 268 format ROp { 269 0x0: decode FUNCT7 { 270 0x0: add({{ 271 Rd = Rs1_sd + Rs2_sd; 272 }}); 273 0x1: mul({{ 274 Rd = Rs1_sd*Rs2_sd; 275 }}, IntMultOp); 276 0x20: sub({{ 277 Rd = Rs1_sd - Rs2_sd; 278 }}); 279 } 280 0x1: decode FUNCT7 { 281 0x0: sll({{ 282 Rd = Rs1 << Rs2<5:0>; 283 }}); 284 0x1: mulh({{ 285 bool negate = (Rs1_sd < 0) != (Rs2_sd < 0); 286 287 uint64_t Rs1_lo = (uint32_t)std::abs(Rs1_sd); 288 uint64_t Rs1_hi = (uint64_t)std::abs(Rs1_sd) >> 32; 289 uint64_t Rs2_lo = (uint32_t)std::abs(Rs2_sd); 290 uint64_t Rs2_hi = (uint64_t)std::abs(Rs2_sd) >> 32; 291 292 uint64_t hi = Rs1_hi*Rs2_hi; 293 uint64_t mid1 = Rs1_hi*Rs2_lo; 294 uint64_t mid2 = Rs1_lo*Rs2_hi; 295 uint64_t lo = Rs2_lo*Rs1_lo; 296 uint64_t carry = ((uint64_t)(uint32_t)mid1 297 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32; 298 299 uint64_t res = hi + (mid1 >> 32) + (mid2 >> 32) + carry; 300 Rd = negate ? ~res + (Rs1_sd*Rs2_sd == 0 ? 1 : 0) : res; 301 }}, IntMultOp); 302 } 303 0x2: decode FUNCT7 { 304 0x0: slt({{ 305 Rd = (Rs1_sd < Rs2_sd) ? 1 : 0; 306 }}); 307 0x1: mulhsu({{ 308 bool negate = Rs1_sd < 0; 309 uint64_t Rs1_lo = (uint32_t)std::abs(Rs1_sd); 310 uint64_t Rs1_hi = (uint64_t)std::abs(Rs1_sd) >> 32; 311 uint64_t Rs2_lo = (uint32_t)Rs2; 312 uint64_t Rs2_hi = Rs2 >> 32; 313 314 uint64_t hi = Rs1_hi*Rs2_hi; 315 uint64_t mid1 = Rs1_hi*Rs2_lo; 316 uint64_t mid2 = Rs1_lo*Rs2_hi; 317 uint64_t lo = Rs1_lo*Rs2_lo; 318 uint64_t carry = ((uint64_t)(uint32_t)mid1 319 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32; 320 321 uint64_t res = hi + (mid1 >> 32) + (mid2 >> 32) + carry; 322 Rd = negate ? ~res + (Rs1_sd*Rs2 == 0 ? 1 : 0) : res; 323 }}, IntMultOp); 324 } 325 0x3: decode FUNCT7 { 326 0x0: sltu({{ 327 Rd = (Rs1 < Rs2) ? 1 : 0; 328 }}); 329 0x1: mulhu({{ 330 uint64_t Rs1_lo = (uint32_t)Rs1; 331 uint64_t Rs1_hi = Rs1 >> 32; 332 uint64_t Rs2_lo = (uint32_t)Rs2; 333 uint64_t Rs2_hi = Rs2 >> 32; 334 335 uint64_t hi = Rs1_hi*Rs2_hi; 336 uint64_t mid1 = Rs1_hi*Rs2_lo; 337 uint64_t mid2 = Rs1_lo*Rs2_hi; 338 uint64_t lo = Rs1_lo*Rs2_lo; 339 uint64_t carry = ((uint64_t)(uint32_t)mid1 340 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32; 341 342 Rd = hi + (mid1 >> 32) + (mid2 >> 32) + carry; 343 }}, IntMultOp); 344 } 345 0x4: decode FUNCT7 { 346 0x0: xor({{ 347 Rd = Rs1 ^ Rs2; 348 }}); 349 0x1: div({{ 350 if (Rs2_sd == 0) { 351 Rd_sd = -1; 352 } else if (Rs1_sd == std::numeric_limits<int64_t>::min() 353 && Rs2_sd == -1) { 354 Rd_sd = std::numeric_limits<int64_t>::min(); 355 } else { 356 Rd_sd = Rs1_sd/Rs2_sd; 357 } 358 }}, IntDivOp); 359 } 360 0x5: decode FUNCT7 { 361 0x0: srl({{ 362 Rd = Rs1 >> Rs2<5:0>; 363 }}); 364 0x1: divu({{ 365 if (Rs2 == 0) { 366 Rd = std::numeric_limits<uint64_t>::max(); 367 } else { 368 Rd = Rs1/Rs2; 369 } 370 }}, IntDivOp); 371 0x20: sra({{ 372 Rd_sd = Rs1_sd >> Rs2<5:0>; 373 }}); 374 } 375 0x6: decode FUNCT7 { 376 0x0: or({{ 377 Rd = Rs1 | Rs2; 378 }}); 379 0x1: rem({{ 380 if (Rs2_sd == 0) { 381 Rd = Rs1_sd; 382 } else if (Rs1_sd == std::numeric_limits<int64_t>::min() 383 && Rs2_sd == -1) { 384 Rd = 0; 385 } else { 386 Rd = Rs1_sd%Rs2_sd; 387 } 388 }}, IntDivOp); 389 } 390 0x7: decode FUNCT7 { 391 0x0: and({{ 392 Rd = Rs1 & Rs2; 393 }}); 394 0x1: remu({{ 395 if (Rs2 == 0) { 396 Rd = Rs1; 397 } else { 398 Rd = Rs1%Rs2; 399 } 400 }}, IntDivOp); 401 } 402 } 403 } 404 405 0x37: UOp::lui({{ 406 Rd = (uint64_t)imm; 407 }}); 408 409 0x3b: decode FUNCT3 { 410 format ROp { 411 0x0: decode FUNCT7 { 412 0x0: addw({{ 413 Rd_sd = Rs1_sw + Rs2_sw; 414 }}); 415 0x1: mulw({{ 416 Rd_sd = (int32_t)(Rs1_sw*Rs2_sw); 417 }}, IntMultOp); 418 0x20: subw({{ 419 Rd_sd = Rs1_sw - Rs2_sw; 420 }}); 421 } 422 0x1: sllw({{ 423 Rd_sd = Rs1_sw << Rs2<4:0>; 424 }}); 425 0x4: divw({{ 426 if (Rs2_sw == 0) { 427 Rd_sd = -1; 428 } else if (Rs1_sw == std::numeric_limits<int32_t>::min() 429 && Rs2_sw == -1) { 430 Rd_sd = std::numeric_limits<int32_t>::min(); 431 } else { 432 Rd_sd = Rs1_sw/Rs2_sw; 433 } 434 }}, IntDivOp); 435 0x5: decode FUNCT7 { 436 0x0: srlw({{ 437 Rd_uw = Rs1_uw >> Rs2<4:0>; 438 }}); 439 0x1: divuw({{ 440 if (Rs2_uw == 0) { 441 Rd_sd = std::numeric_limits<IntReg>::max(); 442 } else { 443 Rd_sd = (int32_t)(Rs1_uw/Rs2_uw); 444 } 445 }}, IntDivOp); 446 0x20: sraw({{ 447 Rd_sd = Rs1_sw >> Rs2<4:0>; 448 }}); 449 } 450 0x6: remw({{ 451 if (Rs2_sw == 0) { 452 Rd_sd = Rs1_sw; 453 } else if (Rs1_sw == std::numeric_limits<int32_t>::min() 454 && Rs2_sw == -1) { 455 Rd_sd = 0; 456 } else { 457 Rd_sd = Rs1_sw%Rs2_sw; 458 } 459 }}, IntDivOp); 460 0x7: remuw({{ 461 if (Rs2_uw == 0) { 462 Rd_sd = (int32_t)Rs1_uw; 463 } else { 464 Rd_sd = (int32_t)(Rs1_uw%Rs2_uw); 465 } 466 }}, IntDivOp); 467 } 468 } 469 470 format FPR4Op { 471 0x43: decode FUNCT2 { 472 0x0: fmadd_s({{ 473 uint32_t temp; 474 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 475 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 476 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits); 477 float fd; 478 479 if (std::isnan(fs1) || std::isnan(fs2) || std::isnan(fs3)) { 480 if (issignalingnan(fs1) || issignalingnan(fs2) 481 || issignalingnan(fs3)) { 482 FFLAGS |= FloatInvalid; 483 } 484 fd = std::numeric_limits<float>::quiet_NaN(); 485 } else if (std::isinf(fs1) || std::isinf(fs2) || 486 std::isinf(fs3)) { 487 if (std::signbit(fs1) == std::signbit(fs2) 488 && !std::isinf(fs3)) { 489 fd = std::numeric_limits<float>::infinity(); 490 } else if (std::signbit(fs1) != std::signbit(fs2) 491 && !std::isinf(fs3)) { 492 fd = -std::numeric_limits<float>::infinity(); 493 } else { // Fs3_sf is infinity 494 fd = fs3; 495 } 496 } else { 497 fd = fs1*fs2 + fs3; 498 } 499 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 500 }}, FloatMultOp); 501 0x1: fmadd_d({{ 502 if (std::isnan(Fs1) || std::isnan(Fs2) || std::isnan(Fs3)) { 503 if (issignalingnan(Fs1) || issignalingnan(Fs2) 504 || issignalingnan(Fs3)) { 505 FFLAGS |= FloatInvalid; 506 } 507 Fd = std::numeric_limits<double>::quiet_NaN(); 508 } else if (std::isinf(Fs1) || std::isinf(Fs2) || 509 std::isinf(Fs3)) { 510 if (std::signbit(Fs1) == std::signbit(Fs2) 511 && !std::isinf(Fs3)) { 512 Fd = std::numeric_limits<double>::infinity(); 513 } else if (std::signbit(Fs1) != std::signbit(Fs2) 514 && !std::isinf(Fs3)) { 515 Fd = -std::numeric_limits<double>::infinity(); 516 } else { 517 Fd = Fs3; 518 } 519 } else { 520 Fd = Fs1*Fs2 + Fs3; 521 } 522 }}, FloatMultOp); 523 } 524 0x47: decode FUNCT2 { 525 0x0: fmsub_s({{ 526 uint32_t temp; 527 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 528 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 529 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits); 530 float fd; 531 532 if (std::isnan(fs1) || std::isnan(fs2) || std::isnan(fs3)) { 533 if (issignalingnan(fs1) || issignalingnan(fs2) 534 || issignalingnan(fs3)) { 535 FFLAGS |= FloatInvalid; 536 } 537 fd = std::numeric_limits<float>::quiet_NaN(); 538 } else if (std::isinf(fs1) || std::isinf(fs2) || 539 std::isinf(fs3)) { 540 if (std::signbit(fs1) == std::signbit(fs2) 541 && !std::isinf(fs3)) { 542 fd = std::numeric_limits<float>::infinity(); 543 } else if (std::signbit(fs1) != std::signbit(fs2) 544 && !std::isinf(fs3)) { 545 fd = -std::numeric_limits<float>::infinity(); 546 } else { // Fs3_sf is infinity 547 fd = -fs3; 548 } 549 } else { 550 fd = fs1*fs2 - fs3; 551 } 552 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 553 }}, FloatMultOp); 554 0x1: fmsub_d({{ 555 if (std::isnan(Fs1) || std::isnan(Fs2) || std::isnan(Fs3)) { 556 if (issignalingnan(Fs1) || issignalingnan(Fs2) 557 || issignalingnan(Fs3)) { 558 FFLAGS |= FloatInvalid; 559 } 560 Fd = std::numeric_limits<double>::quiet_NaN(); 561 } else if (std::isinf(Fs1) || std::isinf(Fs2) || 562 std::isinf(Fs3)) { 563 if (std::signbit(Fs1) == std::signbit(Fs2) 564 && !std::isinf(Fs3)) { 565 Fd = std::numeric_limits<double>::infinity(); 566 } else if (std::signbit(Fs1) != std::signbit(Fs2) 567 && !std::isinf(Fs3)) { 568 Fd = -std::numeric_limits<double>::infinity(); 569 } else { 570 Fd = -Fs3; 571 } 572 } else { 573 Fd = Fs1*Fs2 - Fs3; 574 } 575 }}, FloatMultOp); 576 } 577 0x4b: decode FUNCT2 { 578 0x0: fnmsub_s({{ 579 uint32_t temp; 580 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 581 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 582 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits); 583 float fd; 584 585 if (std::isnan(fs1) || std::isnan(fs2) || std::isnan(fs3)) { 586 if (issignalingnan(fs1) || issignalingnan(fs2) 587 || issignalingnan(fs3)) { 588 FFLAGS |= FloatInvalid; 589 } 590 fd = std::numeric_limits<float>::quiet_NaN(); 591 } else if (std::isinf(fs1) || std::isinf(fs2) || 592 std::isinf(fs3)) { 593 if (std::signbit(fs1) == std::signbit(fs2) 594 && !std::isinf(fs3)) { 595 fd = -std::numeric_limits<float>::infinity(); 596 } else if (std::signbit(fs1) != std::signbit(fs2) 597 && !std::isinf(fs3)) { 598 fd = std::numeric_limits<float>::infinity(); 599 } else { // Fs3_sf is infinity 600 fd = fs3; 601 } 602 } else { 603 fd = -(fs1*fs2 - fs3); 604 } 605 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 606 }}, FloatMultOp); 607 0x1: fnmsub_d({{ 608 if (std::isnan(Fs1) || std::isnan(Fs2) || std::isnan(Fs3)) { 609 if (issignalingnan(Fs1) || issignalingnan(Fs2) 610 || issignalingnan(Fs3)) { 611 FFLAGS |= FloatInvalid; 612 } 613 Fd = std::numeric_limits<double>::quiet_NaN(); 614 } else if (std::isinf(Fs1) || std::isinf(Fs2) 615 || std::isinf(Fs3)) { 616 if (std::signbit(Fs1) == std::signbit(Fs2) 617 && !std::isinf(Fs3)) { 618 Fd = -std::numeric_limits<double>::infinity(); 619 } else if (std::signbit(Fs1) != std::signbit(Fs2) 620 && !std::isinf(Fs3)) { 621 Fd = std::numeric_limits<double>::infinity(); 622 } else { 623 Fd = Fs3; 624 } 625 } else { 626 Fd = -(Fs1*Fs2 - Fs3); 627 } 628 }}, FloatMultOp); 629 } 630 0x4f: decode FUNCT2 { 631 0x0: fnmadd_s({{ 632 uint32_t temp; 633 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 634 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 635 float fs3 = reinterpret_cast<float&>(temp = Fs3_bits); 636 float fd; 637 638 if (std::isnan(fs1) || std::isnan(fs2) || std::isnan(fs3)) { 639 if (issignalingnan(fs1) || issignalingnan(fs2) 640 || issignalingnan(fs3)) { 641 FFLAGS |= FloatInvalid; 642 } 643 fd = std::numeric_limits<float>::quiet_NaN(); 644 } else if (std::isinf(fs1) || std::isinf(fs2) || 645 std::isinf(fs3)) { 646 if (std::signbit(fs1) == std::signbit(fs2) 647 && !std::isinf(fs3)) { 648 fd = -std::numeric_limits<float>::infinity(); 649 } else if (std::signbit(fs1) != std::signbit(fs2) 650 && !std::isinf(fs3)) { 651 fd = std::numeric_limits<float>::infinity(); 652 } else { // Fs3_sf is infinity 653 fd = -fs3; 654 } 655 } else { 656 fd = -(fs1*fs2 + fs3); 657 } 658 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 659 }}, FloatMultOp); 660 0x1: fnmadd_d({{ 661 if (std::isnan(Fs1) || std::isnan(Fs2) || std::isnan(Fs3)) { 662 if (issignalingnan(Fs1) || issignalingnan(Fs2) 663 || issignalingnan(Fs3)) { 664 FFLAGS |= FloatInvalid; 665 } 666 Fd = std::numeric_limits<double>::quiet_NaN(); 667 } else if (std::isinf(Fs1) || std::isinf(Fs2) || 668 std::isinf(Fs3)) { 669 if (std::signbit(Fs1) == std::signbit(Fs2) 670 && !std::isinf(Fs3)) { 671 Fd = -std::numeric_limits<double>::infinity(); 672 } else if (std::signbit(Fs1) != std::signbit(Fs2) 673 && !std::isinf(Fs3)) { 674 Fd = std::numeric_limits<double>::infinity(); 675 } else { 676 Fd = -Fs3; 677 } 678 } else { 679 Fd = -(Fs1*Fs2 + Fs3); 680 } 681 }}, FloatMultOp); 682 } 683 } 684 685 0x53: decode FUNCT7 { 686 format FPROp { 687 0x0: fadd_s({{ 688 uint32_t temp; 689 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 690 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 691 float fd; 692 693 if (std::isnan(fs1) || std::isnan(fs2)) { 694 if (issignalingnan(fs1) || issignalingnan(fs2)) { 695 FFLAGS |= FloatInvalid; 696 } 697 fd = std::numeric_limits<float>::quiet_NaN(); 698 } else { 699 fd = fs1 + fs2; 700 } 701 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 702 }}, FloatAddOp); 703 0x1: fadd_d({{ 704 if (std::isnan(Fs1) || std::isnan(Fs2)) { 705 if (issignalingnan(Fs1) || issignalingnan(Fs2)) { 706 FFLAGS |= FloatInvalid; 707 } 708 Fd = std::numeric_limits<double>::quiet_NaN(); 709 } else { 710 Fd = Fs1 + Fs2; 711 } 712 }}, FloatAddOp); 713 0x4: fsub_s({{ 714 uint32_t temp; 715 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 716 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 717 float fd; 718 719 if (std::isnan(fs1) || std::isnan(fs2)) { 720 if (issignalingnan(fs1) || issignalingnan(fs2)) { 721 FFLAGS |= FloatInvalid; 722 } 723 fd = std::numeric_limits<float>::quiet_NaN(); 724 } else { 725 fd = fs1 - fs2; 726 } 727 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 728 }}, FloatAddOp); 729 0x5: fsub_d({{ 730 if (std::isnan(Fs1) || std::isnan(Fs2)) { 731 if (issignalingnan(Fs1) || issignalingnan(Fs2)) { 732 FFLAGS |= FloatInvalid; 733 } 734 Fd = std::numeric_limits<double>::quiet_NaN(); 735 } else { 736 Fd = Fs1 - Fs2; 737 } 738 }}, FloatAddOp); 739 0x8: fmul_s({{ 740 uint32_t temp; 741 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 742 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 743 float fd; 744 745 if (std::isnan(fs1) || std::isnan(fs2)) { 746 if (issignalingnan(fs1) || issignalingnan(fs2)) { 747 FFLAGS |= FloatInvalid; 748 } 749 fd = std::numeric_limits<float>::quiet_NaN(); 750 } else { 751 fd = fs1*fs2; 752 } 753 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 754 }}, FloatMultOp); 755 0x9: fmul_d({{ 756 if (std::isnan(Fs1) || std::isnan(Fs2)) { 757 if (issignalingnan(Fs1) || issignalingnan(Fs2)) { 758 FFLAGS |= FloatInvalid; 759 } 760 Fd = std::numeric_limits<double>::quiet_NaN(); 761 } else { 762 Fd = Fs1*Fs2; 763 } 764 }}, FloatMultOp); 765 0xc: fdiv_s({{ 766 uint32_t temp; 767 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 768 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 769 float fd; 770 771 if (std::isnan(fs1) || std::isnan(fs2)) { 772 if (issignalingnan(fs1) || issignalingnan(fs2)) { 773 FFLAGS |= FloatInvalid; 774 } 775 fd = std::numeric_limits<float>::quiet_NaN(); 776 } else { 777 fd = fs1/fs2; 778 } 779 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 780 }}, FloatDivOp); 781 0xd: fdiv_d({{ 782 if (std::isnan(Fs1) || std::isnan(Fs2)) { 783 if (issignalingnan(Fs1) || issignalingnan(Fs2)) { 784 FFLAGS |= FloatInvalid; 785 } 786 Fd = std::numeric_limits<double>::quiet_NaN(); 787 } else { 788 Fd = Fs1/Fs2; 789 } 790 }}, FloatDivOp); 791 0x10: decode ROUND_MODE { 792 0x0: fsgnj_s({{ 793 uint32_t temp; 794 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 795 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 796 float fd; 797 798 if (issignalingnan(fs1)) { 799 fd = std::numeric_limits<float>::signaling_NaN(); 800 std::feclearexcept(FE_INVALID); 801 } else { 802 fd = std::copysign(fs1, fs2); 803 } 804 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 805 }}); 806 0x1: fsgnjn_s({{ 807 uint32_t temp; 808 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 809 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 810 float fd; 811 812 if (issignalingnan(fs1)) { 813 fd = std::numeric_limits<float>::signaling_NaN(); 814 std::feclearexcept(FE_INVALID); 815 } else { 816 fd = std::copysign(fs1, -fs2); 817 } 818 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 819 }}); 820 0x2: fsgnjx_s({{ 821 uint32_t temp; 822 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 823 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 824 float fd; 825 826 if (issignalingnan(fs1)) { 827 fd = std::numeric_limits<float>::signaling_NaN(); 828 std::feclearexcept(FE_INVALID); 829 } else { 830 fd = fs1*(std::signbit(fs2) ? -1.0 : 1.0); 831 } 832 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 833 }}); 834 } 835 0x11: decode ROUND_MODE { 836 0x0: fsgnj_d({{ 837 if (issignalingnan(Fs1)) { 838 Fd = std::numeric_limits<double>::signaling_NaN(); 839 std::feclearexcept(FE_INVALID); 840 } else { 841 Fd = std::copysign(Fs1, Fs2); 842 } 843 }}); 844 0x1: fsgnjn_d({{ 845 if (issignalingnan(Fs1)) { 846 Fd = std::numeric_limits<double>::signaling_NaN(); 847 std::feclearexcept(FE_INVALID); 848 } else { 849 Fd = std::copysign(Fs1, -Fs2); 850 } 851 }}); 852 0x2: fsgnjx_d({{ 853 if (issignalingnan(Fs1)) { 854 Fd = std::numeric_limits<double>::signaling_NaN(); 855 std::feclearexcept(FE_INVALID); 856 } else { 857 Fd = Fs1*(std::signbit(Fs2) ? -1.0 : 1.0); 858 } 859 }}); 860 } 861 0x14: decode ROUND_MODE { 862 0x0: fmin_s({{ 863 uint32_t temp; 864 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 865 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 866 float fd; 867 868 if (issignalingnan(fs2)) { 869 fd = fs1; 870 FFLAGS |= FloatInvalid; 871 } else if (issignalingnan(fs1)) { 872 fd = fs2; 873 FFLAGS |= FloatInvalid; 874 } else { 875 fd = std::fmin(fs1, fs2); 876 } 877 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 878 }}, FloatCmpOp); 879 0x1: fmax_s({{ 880 uint32_t temp; 881 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 882 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 883 float fd; 884 885 if (issignalingnan(fs2)) { 886 fd = fs1; 887 FFLAGS |= FloatInvalid; 888 } else if (issignalingnan(fs1)) { 889 fd = fs2; 890 FFLAGS |= FloatInvalid; 891 } else { 892 fd = std::fmax(fs1, fs2); 893 } 894 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 895 }}, FloatCmpOp); 896 } 897 0x15: decode ROUND_MODE { 898 0x0: fmin_d({{ 899 if (issignalingnan(Fs2)) { 900 Fd = Fs1; 901 FFLAGS |= FloatInvalid; 902 } else if (issignalingnan(Fs1)) { 903 Fd = Fs2; 904 FFLAGS |= FloatInvalid; 905 } else { 906 Fd = std::fmin(Fs1, Fs2); 907 } 908 }}, FloatCmpOp); 909 0x1: fmax_d({{ 910 if (issignalingnan(Fs2)) { 911 Fd = Fs1; 912 FFLAGS |= FloatInvalid; 913 } else if (issignalingnan(Fs1)) { 914 Fd = Fs2; 915 FFLAGS |= FloatInvalid; 916 } else { 917 Fd = std::fmax(Fs1, Fs2); 918 } 919 }}, FloatCmpOp); 920 } 921 0x20: fcvt_s_d({{ 922 assert(CONV_SGN == 1); 923 float fd; 924 if (issignalingnan(Fs1)) { 925 fd = std::numeric_limits<float>::quiet_NaN(); 926 FFLAGS |= FloatInvalid; 927 } else { 928 fd = (float)Fs1; 929 } 930 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 931 }}, FloatCvtOp); 932 0x21: fcvt_d_s({{ 933 assert(CONV_SGN == 0); 934 uint32_t temp; 935 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 936 937 if (issignalingnan(fs1)) { 938 Fd = std::numeric_limits<double>::quiet_NaN(); 939 FFLAGS |= FloatInvalid; 940 } else { 941 Fd = (double)fs1; 942 } 943 }}, FloatCvtOp); 944 0x2c: fsqrt_s({{ 945 assert(RS2 == 0); 946 uint32_t temp; 947 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 948 float fd; 949 950 if (issignalingnan(Fs1_sf)) { 951 FFLAGS |= FloatInvalid; 952 } 953 fd = std::sqrt(fs1); 954 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 955 }}, FloatSqrtOp); 956 0x2d: fsqrt_d({{ 957 assert(RS2 == 0); 958 Fd = std::sqrt(Fs1); 959 }}, FloatSqrtOp); 960 0x50: decode ROUND_MODE { 961 0x0: fle_s({{ 962 uint32_t temp; 963 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 964 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 965 966 if (std::isnan(fs1) || std::isnan(fs2)) { 967 FFLAGS |= FloatInvalid; 968 Rd = 0; 969 } else { 970 Rd = fs1 <= fs2 ? 1 : 0; 971 } 972 }}, FloatCmpOp); 973 0x1: flt_s({{ 974 uint32_t temp; 975 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 976 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 977 978 if (std::isnan(fs1) || std::isnan(fs2)) { 979 FFLAGS |= FloatInvalid; 980 Rd = 0; 981 } else { 982 Rd = fs1 < fs2 ? 1 : 0; 983 } 984 }}, FloatCmpOp); 985 0x2: feq_s({{ 986 uint32_t temp; 987 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 988 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 989 990 if (issignalingnan(fs1) || issignalingnan(fs2)) { 991 FFLAGS |= FloatInvalid; 992 } 993 Rd = fs1 == fs2 ? 1 : 0; 994 }}, FloatCmpOp); 995 } 996 0x51: decode ROUND_MODE { 997 0x0: fle_d({{ 998 if (std::isnan(Fs1) || std::isnan(Fs2)) { 999 FFLAGS |= FloatInvalid; 1000 Rd = 0; 1001 } else { 1002 Rd = Fs1 <= Fs2 ? 1 : 0; 1003 } 1004 }}, FloatCmpOp); 1005 0x1: flt_d({{ 1006 if (std::isnan(Fs1) || std::isnan(Fs2)) { 1007 FFLAGS |= FloatInvalid; 1008 Rd = 0; 1009 } else { 1010 Rd = Fs1 < Fs2 ? 1 : 0; 1011 } 1012 }}, FloatCmpOp); 1013 0x2: feq_d({{ 1014 if (issignalingnan(Fs1) || issignalingnan(Fs2)) { 1015 FFLAGS |= FloatInvalid; 1016 } 1017 Rd = Fs1 == Fs2 ? 1 : 0; 1018 }}, FloatCmpOp); 1019 } 1020 0x60: decode CONV_SGN { 1021 0x0: fcvt_w_s({{ 1022 uint32_t temp; 1023 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1024 1025 if (std::isnan(fs1)) { 1026 Rd_sd = std::numeric_limits<int32_t>::max(); 1027 FFLAGS |= FloatInvalid; 1028 } else { 1029 Rd_sd = (int32_t)fs1; 1030 if (std::fetestexcept(FE_INVALID)) { 1031 if (std::signbit(fs1)) { 1032 Rd_sd = std::numeric_limits<int32_t>::min(); 1033 } else { 1034 Rd_sd = std::numeric_limits<int32_t>::max(); 1035 } 1036 std::feclearexcept(FE_INEXACT); 1037 } 1038 } 1039 }}, FloatCvtOp); 1040 0x1: fcvt_wu_s({{ 1041 uint32_t temp; 1042 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1043 1044 if (fs1 < 0.0) { 1045 Rd = 0; 1046 FFLAGS |= FloatInvalid; 1047 } else { 1048 Rd = (uint32_t)fs1; 1049 if (std::fetestexcept(FE_INVALID)) { 1050 Rd = std::numeric_limits<uint64_t>::max(); 1051 std::feclearexcept(FE_INEXACT); 1052 } 1053 } 1054 }}, FloatCvtOp); 1055 0x2: fcvt_l_s({{ 1056 uint32_t temp; 1057 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1058 1059 if (std::isnan(fs1)) { 1060 Rd_sd = std::numeric_limits<int64_t>::max(); 1061 FFLAGS |= FloatInvalid; 1062 } else { 1063 Rd_sd = (int64_t)fs1; 1064 if (std::fetestexcept(FE_INVALID)) { 1065 if (std::signbit(fs1)) { 1066 Rd_sd = std::numeric_limits<int64_t>::min(); 1067 } else { 1068 Rd_sd = std::numeric_limits<int64_t>::max(); 1069 } 1070 std::feclearexcept(FE_INEXACT); 1071 } 1072 } 1073 }}, FloatCvtOp); 1074 0x3: fcvt_lu_s({{ 1075 uint32_t temp; 1076 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1077 1078 if (fs1 < 0.0) { 1079 Rd = 0; 1080 FFLAGS |= FloatInvalid; 1081 } else { 1082 Rd = (uint64_t)fs1; 1083 if (std::fetestexcept(FE_INVALID)) { 1084 Rd = std::numeric_limits<uint64_t>::max(); 1085 std::feclearexcept(FE_INEXACT); 1086 } 1087 } 1088 }}, FloatCvtOp); 1089 } 1090 0x61: decode CONV_SGN { 1091 0x0: fcvt_w_d({{ 1092 Rd_sd = (int32_t)Fs1; 1093 if (std::fetestexcept(FE_INVALID)) { 1094 if (Fs1 < 0.0) { 1095 Rd_sd = std::numeric_limits<int32_t>::min(); 1096 } else { 1097 Rd_sd = std::numeric_limits<int32_t>::max(); 1098 } 1099 std::feclearexcept(FE_INEXACT); 1100 } 1101 }}, FloatCvtOp); 1102 0x1: fcvt_wu_d({{ 1103 if (Fs1 < 0.0) { 1104 Rd = 0; 1105 FFLAGS |= FloatInvalid; 1106 } else { 1107 Rd = (uint32_t)Fs1; 1108 if (std::fetestexcept(FE_INVALID)) { 1109 Rd = std::numeric_limits<uint64_t>::max(); 1110 std::feclearexcept(FE_INEXACT); 1111 } 1112 } 1113 }}, FloatCvtOp); 1114 0x2: fcvt_l_d({{ 1115 Rd_sd = Fs1; 1116 if (std::fetestexcept(FE_INVALID)) { 1117 if (Fs1 < 0.0) { 1118 Rd_sd = std::numeric_limits<int64_t>::min(); 1119 } else { 1120 Rd_sd = std::numeric_limits<int64_t>::max(); 1121 } 1122 std::feclearexcept(FE_INEXACT); 1123 } 1124 }}, FloatCvtOp); 1125 0x3: fcvt_lu_d({{ 1126 if (Fs1 < 0.0) { 1127 Rd = 0; 1128 FFLAGS |= FloatInvalid; 1129 } else { 1130 Rd = (uint64_t)Fs1; 1131 if (std::fetestexcept(FE_INVALID)) { 1132 Rd = std::numeric_limits<uint64_t>::max(); 1133 std::feclearexcept(FE_INEXACT); 1134 } 1135 } 1136 }}, FloatCvtOp); 1137 } 1138 0x68: decode CONV_SGN { 1139 0x0: fcvt_s_w({{ 1140 float temp = (float)Rs1_sw; 1141 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp); 1142 }}, FloatCvtOp); 1143 0x1: fcvt_s_wu({{ 1144 float temp = (float)Rs1_uw; 1145 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp); 1146 }}, FloatCvtOp); 1147 0x2: fcvt_s_l({{ 1148 float temp = (float)Rs1_sd; 1149 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp); 1150 }}, FloatCvtOp); 1151 0x3: fcvt_s_lu({{ 1152 float temp = (float)Rs1; 1153 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp); 1154 }}, FloatCvtOp); 1155 } 1156 0x69: decode CONV_SGN { 1157 0x0: fcvt_d_w({{ 1158 Fd = (double)Rs1_sw; 1159 }}, FloatCvtOp); 1160 0x1: fcvt_d_wu({{ 1161 Fd = (double)Rs1_uw; 1162 }}, FloatCvtOp); 1163 0x2: fcvt_d_l({{ 1164 Fd = (double)Rs1_sd; 1165 }}, FloatCvtOp); 1166 0x3: fcvt_d_lu({{ 1167 Fd = (double)Rs1; 1168 }}, FloatCvtOp); 1169 } 1170 0x70: decode ROUND_MODE { 1171 0x0: fmv_x_s({{ 1172 Rd = (uint32_t)Fs1_bits; 1173 if ((Rd&0x80000000) != 0) { 1174 Rd |= (0xFFFFFFFFULL << 32); 1175 } 1176 }}, FloatCvtOp); 1177 0x1: fclass_s({{ 1178 uint32_t temp; 1179 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1180 switch (std::fpclassify(fs1)) { 1181 case FP_INFINITE: 1182 if (std::signbit(fs1)) { 1183 Rd = 1 << 0; 1184 } else { 1185 Rd = 1 << 7; 1186 } 1187 break; 1188 case FP_NAN: 1189 if (issignalingnan(fs1)) { 1190 Rd = 1 << 8; 1191 } else { 1192 Rd = 1 << 9; 1193 } 1194 break; 1195 case FP_ZERO: 1196 if (std::signbit(fs1)) { 1197 Rd = 1 << 3; 1198 } else { 1199 Rd = 1 << 4; 1200 } 1201 break; 1202 case FP_SUBNORMAL: 1203 if (std::signbit(fs1)) { 1204 Rd = 1 << 2; 1205 } else { 1206 Rd = 1 << 5; 1207 } 1208 break; 1209 case FP_NORMAL: 1210 if (std::signbit(fs1)) { 1211 Rd = 1 << 1; 1212 } else { 1213 Rd = 1 << 6; 1214 } 1215 break; 1216 default: 1217 panic("Unknown classification for operand."); 1218 break; 1219 } 1220 }}); 1221 } 1222 0x71: decode ROUND_MODE { 1223 0x0: fmv_x_d({{ 1224 Rd = Fs1_bits; 1225 }}, FloatCvtOp); 1226 0x1: fclass_d({{ 1227 switch (std::fpclassify(Fs1)) { 1228 case FP_INFINITE: 1229 if (std::signbit(Fs1)) { 1230 Rd = 1 << 0; 1231 } else { 1232 Rd = 1 << 7; 1233 } 1234 break; 1235 case FP_NAN: 1236 if (issignalingnan(Fs1)) { 1237 Rd = 1 << 8; 1238 } else { 1239 Rd = 1 << 9; 1240 } 1241 break; 1242 case FP_ZERO: 1243 if (std::signbit(Fs1)) { 1244 Rd = 1 << 3; 1245 } else { 1246 Rd = 1 << 4; 1247 } 1248 break; 1249 case FP_SUBNORMAL: 1250 if (std::signbit(Fs1)) { 1251 Rd = 1 << 2; 1252 } else { 1253 Rd = 1 << 5; 1254 } 1255 break; 1256 case FP_NORMAL: 1257 if (std::signbit(Fs1)) { 1258 Rd = 1 << 1; 1259 } else { 1260 Rd = 1 << 6; 1261 } 1262 break; 1263 default: 1264 panic("Unknown classification for operand."); 1265 break; 1266 } 1267 }}); 1268 } 1269 0x78: fmv_s_x({{ 1270 Fd_bits = (uint64_t)Rs1_uw; 1271 }}, FloatCvtOp); 1272 0x79: fmv_d_x({{ 1273 Fd_bits = Rs1; 1274 }}, FloatCvtOp); 1275 } 1276 } 1277 0x63: decode FUNCT3 { 1278 format SBOp { 1279 0x0: beq({{ 1280 if (Rs1 == Rs2) { 1281 NPC = PC + imm; 1282 } else { 1283 NPC = NPC; 1284 } 1285 }}, IsDirectControl, IsCondControl); 1286 0x1: bne({{ 1287 if (Rs1 != Rs2) { 1288 NPC = PC + imm; 1289 } else { 1290 NPC = NPC; 1291 } 1292 }}, IsDirectControl, IsCondControl); 1293 0x4: blt({{ 1294 if (Rs1_sd < Rs2_sd) { 1295 NPC = PC + imm; 1296 } else { 1297 NPC = NPC; 1298 } 1299 }}, IsDirectControl, IsCondControl); 1300 0x5: bge({{ 1301 if (Rs1_sd >= Rs2_sd) { 1302 NPC = PC + imm; 1303 } else { 1304 NPC = NPC; 1305 } 1306 }}, IsDirectControl, IsCondControl); 1307 0x6: bltu({{ 1308 if (Rs1 < Rs2) { 1309 NPC = PC + imm; 1310 } else { 1311 NPC = NPC; 1312 } 1313 }}, IsDirectControl, IsCondControl); 1314 0x7: bgeu({{ 1315 if (Rs1 >= Rs2) { 1316 NPC = PC + imm; 1317 } else { 1318 NPC = NPC; 1319 } 1320 }}, IsDirectControl, IsCondControl); 1321 } 1322 } 1323 1324 0x67: decode FUNCT3 { 1325 0x0: Jump::jalr({{ 1326 Rd = NPC; 1327 NPC = (imm + Rs1) & (~0x1); 1328 }}, IsIndirectControl, IsUncondControl, IsCall); 1329 } 1330 1331 0x6f: UJOp::jal({{ 1332 Rd = NPC; 1333 NPC = PC + imm; 1334 }}, IsDirectControl, IsUncondControl, IsCall); 1335 1336 0x73: decode FUNCT3 { 1337 format IOp { 1338 0x0: decode FUNCT12 { 1339 0x0: ecall({{ 1340 fault = std::make_shared<SyscallFault>(); 1341 }}, IsSerializeAfter, IsNonSpeculative, IsSyscall, No_OpClass); 1342 0x1: ebreak({{ 1343 fault = std::make_shared<BreakpointFault>(); 1344 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass); 1345 0x100: eret({{ 1346 fault = std::make_shared<UnimplementedFault>("eret"); 1347 }}, No_OpClass); 1348 } 1349 0x1: csrrw({{ 1350 Rd = xc->readMiscReg(FUNCT12); 1351 xc->setMiscReg(FUNCT12, Rs1); 1352 }}, IsNonSpeculative, No_OpClass); 1353 0x2: csrrs({{ 1354 Rd = xc->readMiscReg(FUNCT12); 1355 if (Rs1 != 0) { 1356 xc->setMiscReg(FUNCT12, Rd | Rs1); 1357 } 1358 }}, IsNonSpeculative, No_OpClass); 1359 0x3: csrrc({{ 1360 Rd = xc->readMiscReg(FUNCT12); 1361 if (Rs1 != 0) { 1362 xc->setMiscReg(FUNCT12, Rd & ~Rs1); 1363 } 1364 }}, IsNonSpeculative, No_OpClass); 1365 0x5: csrrwi({{ 1366 Rd = xc->readMiscReg(FUNCT12); 1367 xc->setMiscReg(FUNCT12, ZIMM); 1368 }}, IsNonSpeculative, No_OpClass); 1369 0x6: csrrsi({{ 1370 Rd = xc->readMiscReg(FUNCT12); 1371 if (ZIMM != 0) { 1372 xc->setMiscReg(FUNCT12, Rd | ZIMM); 1373 } 1374 }}, IsNonSpeculative, No_OpClass); 1375 0x7: csrrci({{ 1376 Rd = xc->readMiscReg(FUNCT12); 1377 if (ZIMM != 0) { 1378 xc->setMiscReg(FUNCT12, Rd & ~ZIMM); 1379 } 1380 }}, IsNonSpeculative, No_OpClass); 1381 } 1382 } 1383} 1384