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