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 }
| 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 }
|
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}
| 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}
|