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