decoder.isa revision 12119:e9ef3ee3171d
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 FPROp { 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 0x53: decode FUNCT7 { 685 0x0: fadd_s({{ 686 uint32_t temp; 687 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 688 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 689 float fd; 690 691 if (std::isnan(fs1) || std::isnan(fs2)) { 692 if (issignalingnan(fs1) || issignalingnan(fs2)) { 693 FFLAGS |= FloatInvalid; 694 } 695 fd = std::numeric_limits<float>::quiet_NaN(); 696 } else { 697 fd = fs1 + fs2; 698 } 699 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 700 }}, FloatAddOp); 701 0x1: fadd_d({{ 702 if (std::isnan(Fs1) || std::isnan(Fs2)) { 703 if (issignalingnan(Fs1) || issignalingnan(Fs2)) { 704 FFLAGS |= FloatInvalid; 705 } 706 Fd = std::numeric_limits<double>::quiet_NaN(); 707 } else { 708 Fd = Fs1 + Fs2; 709 } 710 }}, FloatAddOp); 711 0x4: fsub_s({{ 712 uint32_t temp; 713 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 714 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 715 float fd; 716 717 if (std::isnan(fs1) || std::isnan(fs2)) { 718 if (issignalingnan(fs1) || issignalingnan(fs2)) { 719 FFLAGS |= FloatInvalid; 720 } 721 fd = std::numeric_limits<float>::quiet_NaN(); 722 } else { 723 fd = fs1 - fs2; 724 } 725 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 726 }}, FloatAddOp); 727 0x5: fsub_d({{ 728 if (std::isnan(Fs1) || std::isnan(Fs2)) { 729 if (issignalingnan(Fs1) || issignalingnan(Fs2)) { 730 FFLAGS |= FloatInvalid; 731 } 732 Fd = std::numeric_limits<double>::quiet_NaN(); 733 } else { 734 Fd = Fs1 - Fs2; 735 } 736 }}, FloatAddOp); 737 0x8: fmul_s({{ 738 uint32_t temp; 739 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 740 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 741 float fd; 742 743 if (std::isnan(fs1) || std::isnan(fs2)) { 744 if (issignalingnan(fs1) || issignalingnan(fs2)) { 745 FFLAGS |= FloatInvalid; 746 } 747 fd = std::numeric_limits<float>::quiet_NaN(); 748 } else { 749 fd = fs1*fs2; 750 } 751 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 752 }}, FloatMultOp); 753 0x9: fmul_d({{ 754 if (std::isnan(Fs1) || std::isnan(Fs2)) { 755 if (issignalingnan(Fs1) || issignalingnan(Fs2)) { 756 FFLAGS |= FloatInvalid; 757 } 758 Fd = std::numeric_limits<double>::quiet_NaN(); 759 } else { 760 Fd = Fs1*Fs2; 761 } 762 }}, FloatMultOp); 763 0xc: fdiv_s({{ 764 uint32_t temp; 765 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 766 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 767 float fd; 768 769 if (std::isnan(fs1) || std::isnan(fs2)) { 770 if (issignalingnan(fs1) || issignalingnan(fs2)) { 771 FFLAGS |= FloatInvalid; 772 } 773 fd = std::numeric_limits<float>::quiet_NaN(); 774 } else { 775 fd = fs1/fs2; 776 } 777 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 778 }}, FloatDivOp); 779 0xd: fdiv_d({{ 780 if (std::isnan(Fs1) || std::isnan(Fs2)) { 781 if (issignalingnan(Fs1) || issignalingnan(Fs2)) { 782 FFLAGS |= FloatInvalid; 783 } 784 Fd = std::numeric_limits<double>::quiet_NaN(); 785 } else { 786 Fd = Fs1/Fs2; 787 } 788 }}, FloatDivOp); 789 0x10: decode ROUND_MODE { 790 0x0: fsgnj_s({{ 791 uint32_t temp; 792 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 793 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 794 float fd; 795 796 if (issignalingnan(fs1)) { 797 fd = std::numeric_limits<float>::signaling_NaN(); 798 std::feclearexcept(FE_INVALID); 799 } else { 800 fd = std::copysign(fs1, fs2); 801 } 802 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 803 }}); 804 0x1: fsgnjn_s({{ 805 uint32_t temp; 806 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 807 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 808 float fd; 809 810 if (issignalingnan(fs1)) { 811 fd = std::numeric_limits<float>::signaling_NaN(); 812 std::feclearexcept(FE_INVALID); 813 } else { 814 fd = std::copysign(fs1, -fs2); 815 } 816 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 817 }}); 818 0x2: fsgnjx_s({{ 819 uint32_t temp; 820 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 821 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 822 float fd; 823 824 if (issignalingnan(fs1)) { 825 fd = std::numeric_limits<float>::signaling_NaN(); 826 std::feclearexcept(FE_INVALID); 827 } else { 828 fd = fs1*(std::signbit(fs2) ? -1.0 : 1.0); 829 } 830 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 831 }}); 832 } 833 0x11: decode ROUND_MODE { 834 0x0: fsgnj_d({{ 835 if (issignalingnan(Fs1)) { 836 Fd = std::numeric_limits<double>::signaling_NaN(); 837 std::feclearexcept(FE_INVALID); 838 } else { 839 Fd = std::copysign(Fs1, Fs2); 840 } 841 }}); 842 0x1: fsgnjn_d({{ 843 if (issignalingnan(Fs1)) { 844 Fd = std::numeric_limits<double>::signaling_NaN(); 845 std::feclearexcept(FE_INVALID); 846 } else { 847 Fd = std::copysign(Fs1, -Fs2); 848 } 849 }}); 850 0x2: fsgnjx_d({{ 851 if (issignalingnan(Fs1)) { 852 Fd = std::numeric_limits<double>::signaling_NaN(); 853 std::feclearexcept(FE_INVALID); 854 } else { 855 Fd = Fs1*(std::signbit(Fs2) ? -1.0 : 1.0); 856 } 857 }}); 858 } 859 0x14: decode ROUND_MODE { 860 0x0: fmin_s({{ 861 uint32_t temp; 862 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 863 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 864 float fd; 865 866 if (issignalingnan(fs2)) { 867 fd = fs1; 868 FFLAGS |= FloatInvalid; 869 } else if (issignalingnan(fs1)) { 870 fd = fs2; 871 FFLAGS |= FloatInvalid; 872 } else { 873 fd = std::fmin(fs1, fs2); 874 } 875 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 876 }}, FloatCmpOp); 877 0x1: fmax_s({{ 878 uint32_t temp; 879 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 880 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 881 float fd; 882 883 if (issignalingnan(fs2)) { 884 fd = fs1; 885 FFLAGS |= FloatInvalid; 886 } else if (issignalingnan(fs1)) { 887 fd = fs2; 888 FFLAGS |= FloatInvalid; 889 } else { 890 fd = std::fmax(fs1, fs2); 891 } 892 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 893 }}, FloatCmpOp); 894 } 895 0x15: decode ROUND_MODE { 896 0x0: fmin_d({{ 897 if (issignalingnan(Fs2)) { 898 Fd = Fs1; 899 FFLAGS |= FloatInvalid; 900 } else if (issignalingnan(Fs1)) { 901 Fd = Fs2; 902 FFLAGS |= FloatInvalid; 903 } else { 904 Fd = std::fmin(Fs1, Fs2); 905 } 906 }}, FloatCmpOp); 907 0x1: fmax_d({{ 908 if (issignalingnan(Fs2)) { 909 Fd = Fs1; 910 FFLAGS |= FloatInvalid; 911 } else if (issignalingnan(Fs1)) { 912 Fd = Fs2; 913 FFLAGS |= FloatInvalid; 914 } else { 915 Fd = std::fmax(Fs1, Fs2); 916 } 917 }}, FloatCmpOp); 918 } 919 0x20: fcvt_s_d({{ 920 assert(CONV_SGN == 1); 921 float fd; 922 if (issignalingnan(Fs1)) { 923 fd = std::numeric_limits<float>::quiet_NaN(); 924 FFLAGS |= FloatInvalid; 925 } else { 926 fd = (float)Fs1; 927 } 928 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 929 }}, FloatCvtOp); 930 0x21: fcvt_d_s({{ 931 assert(CONV_SGN == 0); 932 uint32_t temp; 933 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 934 935 if (issignalingnan(fs1)) { 936 Fd = std::numeric_limits<double>::quiet_NaN(); 937 FFLAGS |= FloatInvalid; 938 } else { 939 Fd = (double)fs1; 940 } 941 }}, FloatCvtOp); 942 0x2c: fsqrt_s({{ 943 assert(RS2 == 0); 944 uint32_t temp; 945 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 946 float fd; 947 948 if (issignalingnan(Fs1_sf)) { 949 FFLAGS |= FloatInvalid; 950 } 951 fd = std::sqrt(fs1); 952 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(fd); 953 }}, FloatSqrtOp); 954 0x2d: fsqrt_d({{ 955 assert(RS2 == 0); 956 Fd = std::sqrt(Fs1); 957 }}, FloatSqrtOp); 958 0x50: decode ROUND_MODE { 959 0x0: fle_s({{ 960 uint32_t temp; 961 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 962 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 963 964 if (std::isnan(fs1) || std::isnan(fs2)) { 965 FFLAGS |= FloatInvalid; 966 Rd = 0; 967 } else { 968 Rd = fs1 <= fs2 ? 1 : 0; 969 } 970 }}, FloatCmpOp); 971 0x1: flt_s({{ 972 uint32_t temp; 973 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 974 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 975 976 if (std::isnan(fs1) || std::isnan(fs2)) { 977 FFLAGS |= FloatInvalid; 978 Rd = 0; 979 } else { 980 Rd = fs1 < fs2 ? 1 : 0; 981 } 982 }}, FloatCmpOp); 983 0x2: feq_s({{ 984 uint32_t temp; 985 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 986 float fs2 = reinterpret_cast<float&>(temp = Fs2_bits); 987 988 if (issignalingnan(fs1) || issignalingnan(fs2)) { 989 FFLAGS |= FloatInvalid; 990 } 991 Rd = fs1 == fs2 ? 1 : 0; 992 }}, FloatCmpOp); 993 } 994 0x51: decode ROUND_MODE { 995 0x0: fle_d({{ 996 if (std::isnan(Fs1) || std::isnan(Fs2)) { 997 FFLAGS |= FloatInvalid; 998 Rd = 0; 999 } else { 1000 Rd = Fs1 <= Fs2 ? 1 : 0; 1001 } 1002 }}, FloatCmpOp); 1003 0x1: flt_d({{ 1004 if (std::isnan(Fs1) || std::isnan(Fs2)) { 1005 FFLAGS |= FloatInvalid; 1006 Rd = 0; 1007 } else { 1008 Rd = Fs1 < Fs2 ? 1 : 0; 1009 } 1010 }}, FloatCmpOp); 1011 0x2: feq_d({{ 1012 if (issignalingnan(Fs1) || issignalingnan(Fs2)) { 1013 FFLAGS |= FloatInvalid; 1014 } 1015 Rd = Fs1 == Fs2 ? 1 : 0; 1016 }}, FloatCmpOp); 1017 } 1018 0x60: decode CONV_SGN { 1019 0x0: fcvt_w_s({{ 1020 uint32_t temp; 1021 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1022 1023 if (std::isnan(fs1)) { 1024 Rd_sd = std::numeric_limits<int32_t>::max(); 1025 FFLAGS |= FloatInvalid; 1026 } else { 1027 Rd_sd = (int32_t)fs1; 1028 if (std::fetestexcept(FE_INVALID)) { 1029 if (std::signbit(fs1)) { 1030 Rd_sd = std::numeric_limits<int32_t>::min(); 1031 } else { 1032 Rd_sd = std::numeric_limits<int32_t>::max(); 1033 } 1034 std::feclearexcept(FE_INEXACT); 1035 } 1036 } 1037 }}, FloatCvtOp); 1038 0x1: fcvt_wu_s({{ 1039 uint32_t temp; 1040 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1041 1042 if (fs1 < 0.0) { 1043 Rd = 0; 1044 FFLAGS |= FloatInvalid; 1045 } else { 1046 Rd = (uint32_t)fs1; 1047 if (std::fetestexcept(FE_INVALID)) { 1048 Rd = std::numeric_limits<uint64_t>::max(); 1049 std::feclearexcept(FE_INEXACT); 1050 } 1051 } 1052 }}, FloatCvtOp); 1053 0x2: fcvt_l_s({{ 1054 uint32_t temp; 1055 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1056 1057 if (std::isnan(fs1)) { 1058 Rd_sd = std::numeric_limits<int64_t>::max(); 1059 FFLAGS |= FloatInvalid; 1060 } else { 1061 Rd_sd = (int64_t)fs1; 1062 if (std::fetestexcept(FE_INVALID)) { 1063 if (std::signbit(fs1)) { 1064 Rd_sd = std::numeric_limits<int64_t>::min(); 1065 } else { 1066 Rd_sd = std::numeric_limits<int64_t>::max(); 1067 } 1068 std::feclearexcept(FE_INEXACT); 1069 } 1070 } 1071 }}, FloatCvtOp); 1072 0x3: fcvt_lu_s({{ 1073 uint32_t temp; 1074 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1075 1076 if (fs1 < 0.0) { 1077 Rd = 0; 1078 FFLAGS |= FloatInvalid; 1079 } else { 1080 Rd = (uint64_t)fs1; 1081 if (std::fetestexcept(FE_INVALID)) { 1082 Rd = std::numeric_limits<uint64_t>::max(); 1083 std::feclearexcept(FE_INEXACT); 1084 } 1085 } 1086 }}, FloatCvtOp); 1087 } 1088 0x61: decode CONV_SGN { 1089 0x0: fcvt_w_d({{ 1090 Rd_sd = (int32_t)Fs1; 1091 if (std::fetestexcept(FE_INVALID)) { 1092 if (Fs1 < 0.0) { 1093 Rd_sd = std::numeric_limits<int32_t>::min(); 1094 } else { 1095 Rd_sd = std::numeric_limits<int32_t>::max(); 1096 } 1097 std::feclearexcept(FE_INEXACT); 1098 } 1099 }}, FloatCvtOp); 1100 0x1: fcvt_wu_d({{ 1101 if (Fs1 < 0.0) { 1102 Rd = 0; 1103 FFLAGS |= FloatInvalid; 1104 } else { 1105 Rd = (uint32_t)Fs1; 1106 if (std::fetestexcept(FE_INVALID)) { 1107 Rd = std::numeric_limits<uint64_t>::max(); 1108 std::feclearexcept(FE_INEXACT); 1109 } 1110 } 1111 }}, FloatCvtOp); 1112 0x2: fcvt_l_d({{ 1113 Rd_sd = Fs1; 1114 if (std::fetestexcept(FE_INVALID)) { 1115 if (Fs1 < 0.0) { 1116 Rd_sd = std::numeric_limits<int64_t>::min(); 1117 } else { 1118 Rd_sd = std::numeric_limits<int64_t>::max(); 1119 } 1120 std::feclearexcept(FE_INEXACT); 1121 } 1122 }}, FloatCvtOp); 1123 0x3: fcvt_lu_d({{ 1124 if (Fs1 < 0.0) { 1125 Rd = 0; 1126 FFLAGS |= FloatInvalid; 1127 } else { 1128 Rd = (uint64_t)Fs1; 1129 if (std::fetestexcept(FE_INVALID)) { 1130 Rd = std::numeric_limits<uint64_t>::max(); 1131 std::feclearexcept(FE_INEXACT); 1132 } 1133 } 1134 }}, FloatCvtOp); 1135 } 1136 0x68: decode CONV_SGN { 1137 0x0: fcvt_s_w({{ 1138 float temp = (float)Rs1_sw; 1139 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp); 1140 }}, FloatCvtOp); 1141 0x1: fcvt_s_wu({{ 1142 float temp = (float)Rs1_uw; 1143 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp); 1144 }}, FloatCvtOp); 1145 0x2: fcvt_s_l({{ 1146 float temp = (float)Rs1_sd; 1147 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp); 1148 }}, FloatCvtOp); 1149 0x3: fcvt_s_lu({{ 1150 float temp = (float)Rs1; 1151 Fd_bits = (uint64_t)reinterpret_cast<uint32_t&>(temp); 1152 }}, FloatCvtOp); 1153 } 1154 0x69: decode CONV_SGN { 1155 0x0: fcvt_d_w({{ 1156 Fd = (double)Rs1_sw; 1157 }}, FloatCvtOp); 1158 0x1: fcvt_d_wu({{ 1159 Fd = (double)Rs1_uw; 1160 }}, FloatCvtOp); 1161 0x2: fcvt_d_l({{ 1162 Fd = (double)Rs1_sd; 1163 }}, FloatCvtOp); 1164 0x3: fcvt_d_lu({{ 1165 Fd = (double)Rs1; 1166 }}, FloatCvtOp); 1167 } 1168 0x70: decode ROUND_MODE { 1169 0x0: fmv_x_s({{ 1170 Rd = (uint32_t)Fs1_bits; 1171 if ((Rd&0x80000000) != 0) { 1172 Rd |= (0xFFFFFFFFULL << 32); 1173 } 1174 }}, FloatCvtOp); 1175 0x1: fclass_s({{ 1176 uint32_t temp; 1177 float fs1 = reinterpret_cast<float&>(temp = Fs1_bits); 1178 switch (std::fpclassify(fs1)) { 1179 case FP_INFINITE: 1180 if (std::signbit(fs1)) { 1181 Rd = 1 << 0; 1182 } else { 1183 Rd = 1 << 7; 1184 } 1185 break; 1186 case FP_NAN: 1187 if (issignalingnan(fs1)) { 1188 Rd = 1 << 8; 1189 } else { 1190 Rd = 1 << 9; 1191 } 1192 break; 1193 case FP_ZERO: 1194 if (std::signbit(fs1)) { 1195 Rd = 1 << 3; 1196 } else { 1197 Rd = 1 << 4; 1198 } 1199 break; 1200 case FP_SUBNORMAL: 1201 if (std::signbit(fs1)) { 1202 Rd = 1 << 2; 1203 } else { 1204 Rd = 1 << 5; 1205 } 1206 break; 1207 case FP_NORMAL: 1208 if (std::signbit(fs1)) { 1209 Rd = 1 << 1; 1210 } else { 1211 Rd = 1 << 6; 1212 } 1213 break; 1214 default: 1215 panic("Unknown classification for operand."); 1216 break; 1217 } 1218 }}); 1219 } 1220 0x71: decode ROUND_MODE { 1221 0x0: fmv_x_d({{ 1222 Rd = Fs1_bits; 1223 }}, FloatCvtOp); 1224 0x1: fclass_d({{ 1225 switch (std::fpclassify(Fs1)) { 1226 case FP_INFINITE: 1227 if (std::signbit(Fs1)) { 1228 Rd = 1 << 0; 1229 } else { 1230 Rd = 1 << 7; 1231 } 1232 break; 1233 case FP_NAN: 1234 if (issignalingnan(Fs1)) { 1235 Rd = 1 << 8; 1236 } else { 1237 Rd = 1 << 9; 1238 } 1239 break; 1240 case FP_ZERO: 1241 if (std::signbit(Fs1)) { 1242 Rd = 1 << 3; 1243 } else { 1244 Rd = 1 << 4; 1245 } 1246 break; 1247 case FP_SUBNORMAL: 1248 if (std::signbit(Fs1)) { 1249 Rd = 1 << 2; 1250 } else { 1251 Rd = 1 << 5; 1252 } 1253 break; 1254 case FP_NORMAL: 1255 if (std::signbit(Fs1)) { 1256 Rd = 1 << 1; 1257 } else { 1258 Rd = 1 << 6; 1259 } 1260 break; 1261 default: 1262 panic("Unknown classification for operand."); 1263 break; 1264 } 1265 }}); 1266 } 1267 0x78: fmv_s_x({{ 1268 Fd_bits = (uint64_t)Rs1_uw; 1269 }}, FloatCvtOp); 1270 0x79: fmv_d_x({{ 1271 Fd_bits = Rs1; 1272 }}, FloatCvtOp); 1273 } 1274 } 1275 1276 0x63: decode FUNCT3 { 1277 format BOp { 1278 0x0: beq({{ 1279 if (Rs1 == Rs2) { 1280 NPC = PC + imm; 1281 } else { 1282 NPC = NPC; 1283 } 1284 }}, IsDirectControl, IsCondControl); 1285 0x1: bne({{ 1286 if (Rs1 != Rs2) { 1287 NPC = PC + imm; 1288 } else { 1289 NPC = NPC; 1290 } 1291 }}, IsDirectControl, IsCondControl); 1292 0x4: blt({{ 1293 if (Rs1_sd < Rs2_sd) { 1294 NPC = PC + imm; 1295 } else { 1296 NPC = NPC; 1297 } 1298 }}, IsDirectControl, IsCondControl); 1299 0x5: bge({{ 1300 if (Rs1_sd >= Rs2_sd) { 1301 NPC = PC + imm; 1302 } else { 1303 NPC = NPC; 1304 } 1305 }}, IsDirectControl, IsCondControl); 1306 0x6: bltu({{ 1307 if (Rs1 < Rs2) { 1308 NPC = PC + imm; 1309 } else { 1310 NPC = NPC; 1311 } 1312 }}, IsDirectControl, IsCondControl); 1313 0x7: bgeu({{ 1314 if (Rs1 >= Rs2) { 1315 NPC = PC + imm; 1316 } else { 1317 NPC = NPC; 1318 } 1319 }}, IsDirectControl, IsCondControl); 1320 } 1321 } 1322 1323 0x67: decode FUNCT3 { 1324 0x0: Jump::jalr({{ 1325 Rd = NPC; 1326 NPC = (imm + Rs1) & (~0x1); 1327 }}, IsIndirectControl, IsUncondControl, IsCall); 1328 } 1329 1330 0x6f: JOp::jal({{ 1331 Rd = NPC; 1332 NPC = PC + imm; 1333 }}, IsDirectControl, IsUncondControl, IsCall); 1334 1335 0x73: decode FUNCT3 { 1336 format SystemOp { 1337 0x0: decode FUNCT12 { 1338 0x0: ecall({{ 1339 fault = std::make_shared<SyscallFault>(); 1340 }}, IsSerializeAfter, IsNonSpeculative, IsSyscall, No_OpClass); 1341 0x1: ebreak({{ 1342 fault = std::make_shared<BreakpointFault>(); 1343 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass); 1344 0x100: eret({{ 1345 fault = std::make_shared<UnimplementedFault>("eret"); 1346 }}, No_OpClass); 1347 } 1348 } 1349 format CSROp { 1350 0x1: csrrw({{ 1351 Rd = xc->readMiscReg(csr); 1352 xc->setMiscReg(csr, Rs1); 1353 }}, IsNonSpeculative, No_OpClass); 1354 0x2: csrrs({{ 1355 Rd = xc->readMiscReg(csr); 1356 if (Rs1 != 0) { 1357 xc->setMiscReg(csr, Rd | Rs1); 1358 } 1359 }}, IsNonSpeculative, No_OpClass); 1360 0x3: csrrc({{ 1361 Rd = xc->readMiscReg(csr); 1362 if (Rs1 != 0) { 1363 xc->setMiscReg(csr, Rd & ~Rs1); 1364 } 1365 }}, IsNonSpeculative, No_OpClass); 1366 0x5: csrrwi({{ 1367 Rd = xc->readMiscReg(csr); 1368 xc->setMiscReg(csr, uimm); 1369 }}, IsNonSpeculative, No_OpClass); 1370 0x6: csrrsi({{ 1371 Rd = xc->readMiscReg(csr); 1372 if (uimm != 0) { 1373 xc->setMiscReg(csr, Rd | uimm); 1374 } 1375 }}, IsNonSpeculative, No_OpClass); 1376 0x7: csrrci({{ 1377 Rd = xc->readMiscReg(csr); 1378 if (uimm != 0) { 1379 xc->setMiscReg(csr, Rd & ~uimm); 1380 } 1381 }}, IsNonSpeculative, No_OpClass); 1382 } 1383 } 1384} 1385