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