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