decoder.isa revision 11724:d92c26d481b7
1// -*- mode:c++ -*- 2 3// Copyright (c) 2015 RISC-V Foundation 4// Copyright (c) 2016 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 OPCODE default Unknown::unknown() { 38 0x03: decode FUNCT3 { 39 format Load { 40 0x0: lb({{ 41 Rd_sd = Mem_sb; 42 }}); 43 0x1: lh({{ 44 Rd_sd = Mem_sh; 45 }}); 46 0x2: lw({{ 47 Rd_sd = Mem_sw; 48 }}); 49 0x3: ld({{ 50 Rd_sd = Mem_sd; 51 }}); 52 0x4: lbu({{ 53 Rd = Mem_ub; 54 }}); 55 0x5: lhu({{ 56 Rd = Mem_uh; 57 }}); 58 0x6: lwu({{ 59 Rd = Mem_uw; 60 }}); 61 } 62 } 63 64 0x0f: decode FUNCT3 { 65 format IOp { 66 0x0: fence({{ 67 }}, IsNonSpeculative, IsMemBarrier, No_OpClass); 68 0x1: fence_i({{ 69 }}, IsNonSpeculative, IsSerializeAfter, No_OpClass); 70 } 71 } 72 73 0x13: decode FUNCT3 { 74 format IOp { 75 0x0: addi({{ 76 Rd_sd = Rs1_sd + imm; 77 }}); 78 0x1: slli({{ 79 Rd = Rs1 << SHAMT6; 80 }}); 81 0x2: slti({{ 82 Rd = (Rs1_sd < imm) ? 1 : 0; 83 }}); 84 0x3: sltiu({{ 85 Rd = (Rs1 < (uint64_t)imm) ? 1 : 0; 86 }}); 87 0x4: xori({{ 88 Rd = Rs1 ^ (uint64_t)imm; 89 }}); 90 0x5: decode SRTYPE { 91 0x0: srli({{ 92 Rd = Rs1 >> SHAMT6; 93 }}); 94 0x1: srai({{ 95 Rd_sd = Rs1_sd >> SHAMT6; 96 }}); 97 } 98 0x6: ori({{ 99 Rd = Rs1 | (uint64_t)imm; 100 }}); 101 0x7: andi({{ 102 Rd = Rs1 & (uint64_t)imm; 103 }}); 104 } 105 } 106 107 0x17: UOp::auipc({{ 108 Rd = PC + imm; 109 }}); 110 111 0x1b: decode FUNCT3 { 112 format IOp { 113 0x0: addiw({{ 114 Rd_sd = (int32_t)Rs1 + (int32_t)imm; 115 }}); 116 0x1: slliw({{ 117 Rd_sd = Rs1_sw << SHAMT5; 118 }}); 119 0x5: decode SRTYPE { 120 0x0: srliw({{ 121 Rd = Rs1_uw >> SHAMT5; 122 }}); 123 0x1: sraiw({{ 124 Rd_sd = Rs1_sw >> SHAMT5; 125 }}); 126 } 127 } 128 } 129 130 0x23: decode FUNCT3 { 131 format Store { 132 0x0: sb({{ 133 Mem_ub = Rs2_ub; 134 }}); 135 0x1: sh({{ 136 Mem_uh = Rs2_uh; 137 }}); 138 0x2: sw({{ 139 Mem_uw = Rs2_uw; 140 }}); 141 0x3: sd({{ 142 Mem_ud = Rs2_ud; 143 }}); 144 } 145 } 146 147 0x33: decode FUNCT3 { 148 format ROp { 149 0x0: decode FUNCT7 { 150 0x0: add({{ 151 Rd = Rs1_sd + Rs2_sd; 152 }}); 153 0x1: mul({{ 154 Rd = Rs1_sd*Rs2_sd; 155 }}, IntMultOp); 156 0x20: sub({{ 157 Rd = Rs1_sd - Rs2_sd; 158 }}); 159 } 160 0x1: decode FUNCT7 { 161 0x0: sll({{ 162 Rd = Rs1 << Rs2<5:0>; 163 }}); 164 0x1: mulh({{ 165 bool negate = (Rs1_sd < 0) != (Rs2_sd < 0); 166 167 uint64_t Rs1_lo = (uint32_t)std::abs(Rs1_sd); 168 uint64_t Rs1_hi = (uint64_t)std::abs(Rs1_sd) >> 32; 169 uint64_t Rs2_lo = (uint32_t)std::abs(Rs2_sd); 170 uint64_t Rs2_hi = (uint64_t)std::abs(Rs2_sd) >> 32; 171 172 uint64_t hi = Rs1_hi*Rs2_hi; 173 uint64_t mid1 = Rs1_hi*Rs2_lo; 174 uint64_t mid2 = Rs1_lo*Rs2_hi; 175 uint64_t lo = Rs2_lo*Rs1_lo; 176 uint64_t carry = ((uint64_t)(uint32_t)mid1 177 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32; 178 179 uint64_t res = hi + (mid1 >> 32) + (mid2 >> 32) + carry; 180 Rd = negate ? ~res + (Rs1_sd*Rs2_sd == 0 ? 1 : 0) : res; 181 }}, IntMultOp); 182 } 183 0x2: decode FUNCT7 { 184 0x0: slt({{ 185 Rd = (Rs1_sd < Rs2_sd) ? 1 : 0; 186 }}); 187 0x1: mulhsu({{ 188 bool negate = Rs1_sd < 0; 189 uint64_t Rs1_lo = (uint32_t)std::abs(Rs1_sd); 190 uint64_t Rs1_hi = (uint64_t)std::abs(Rs1_sd) >> 32; 191 uint64_t Rs2_lo = (uint32_t)Rs2; 192 uint64_t Rs2_hi = Rs2 >> 32; 193 194 uint64_t hi = Rs1_hi*Rs2_hi; 195 uint64_t mid1 = Rs1_hi*Rs2_lo; 196 uint64_t mid2 = Rs1_lo*Rs2_hi; 197 uint64_t lo = Rs1_lo*Rs2_lo; 198 uint64_t carry = ((uint64_t)(uint32_t)mid1 199 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32; 200 201 uint64_t res = hi + (mid1 >> 32) + (mid2 >> 32) + carry; 202 Rd = negate ? ~res + (Rs1_sd*Rs2 == 0 ? 1 : 0) : res; 203 }}, IntMultOp); 204 } 205 0x3: decode FUNCT7 { 206 0x0: sltu({{ 207 Rd = (Rs1 < Rs2) ? 1 : 0; 208 }}); 209 0x1: mulhu({{ 210 uint64_t Rs1_lo = (uint32_t)Rs1; 211 uint64_t Rs1_hi = Rs1 >> 32; 212 uint64_t Rs2_lo = (uint32_t)Rs2; 213 uint64_t Rs2_hi = Rs2 >> 32; 214 215 uint64_t hi = Rs1_hi*Rs2_hi; 216 uint64_t mid1 = Rs1_hi*Rs2_lo; 217 uint64_t mid2 = Rs1_lo*Rs2_hi; 218 uint64_t lo = Rs1_lo*Rs2_lo; 219 uint64_t carry = ((uint64_t)(uint32_t)mid1 220 + (uint64_t)(uint32_t)mid2 + (lo >> 32)) >> 32; 221 222 Rd = hi + (mid1 >> 32) + (mid2 >> 32) + carry; 223 }}, IntMultOp); 224 } 225 0x4: decode FUNCT7 { 226 0x0: xor({{ 227 Rd = Rs1 ^ Rs2; 228 }}); 229 0x1: div({{ 230 if (Rs2_sd == 0) { 231 Rd_sd = -1; 232 } else if (Rs1_sd == std::numeric_limits<int64_t>::min() 233 && Rs2_sd == -1) { 234 Rd_sd = std::numeric_limits<int64_t>::min(); 235 } else { 236 Rd_sd = Rs1_sd/Rs2_sd; 237 } 238 }}, IntDivOp); 239 } 240 0x5: decode FUNCT7 { 241 0x0: srl({{ 242 Rd = Rs1 >> Rs2<5:0>; 243 }}); 244 0x1: divu({{ 245 if (Rs2 == 0) { 246 Rd = std::numeric_limits<uint64_t>::max(); 247 } else { 248 Rd = Rs1/Rs2; 249 } 250 }}, IntDivOp); 251 0x20: sra({{ 252 Rd_sd = Rs1_sd >> Rs2<5:0>; 253 }}); 254 } 255 0x6: decode FUNCT7 { 256 0x0: or({{ 257 Rd = Rs1 | Rs2; 258 }}); 259 0x1: rem({{ 260 if (Rs2_sd == 0) { 261 Rd = Rs1_sd; 262 } else if (Rs1_sd == std::numeric_limits<int64_t>::min() 263 && Rs2_sd == -1) { 264 Rd = 0; 265 } else { 266 Rd = Rs1_sd%Rs2_sd; 267 } 268 }}, IntDivOp); 269 } 270 0x7: decode FUNCT7 { 271 0x0: and({{ 272 Rd = Rs1 & Rs2; 273 }}); 274 0x1: remu({{ 275 if (Rs2 == 0) { 276 Rd = Rs1; 277 } else { 278 Rd = Rs1%Rs2; 279 } 280 }}, IntDivOp); 281 } 282 } 283 } 284 285 0x37: UOp::lui({{ 286 Rd = (uint64_t)imm; 287 }}); 288 289 0x3b: decode FUNCT3 { 290 format ROp { 291 0x0: decode FUNCT7 { 292 0x0: addw({{ 293 Rd_sd = Rs1_sw + Rs2_sw; 294 }}); 295 0x1: mulw({{ 296 Rd_sd = (int32_t)(Rs1_sw*Rs2_sw); 297 }}, IntMultOp); 298 0x20: subw({{ 299 Rd_sd = Rs1_sw - Rs2_sw; 300 }}); 301 } 302 0x1: sllw({{ 303 Rd_sd = Rs1_sw << Rs2<4:0>; 304 }}); 305 0x4: divw({{ 306 if (Rs2_sw == 0) { 307 Rd_sd = -1; 308 } else if (Rs1_sw == std::numeric_limits<int32_t>::min() 309 && Rs2_sw == -1) { 310 Rd_sd = std::numeric_limits<int32_t>::min(); 311 } else { 312 Rd_sd = Rs1_sw/Rs2_sw; 313 } 314 }}, IntDivOp); 315 0x5: decode FUNCT7 { 316 0x0: srlw({{ 317 Rd_uw = Rs1_uw >> Rs2<4:0>; 318 }}); 319 0x1: divuw({{ 320 if (Rs2_uw == 0) { 321 Rd_sd = std::numeric_limits<IntReg>::max(); 322 } else { 323 Rd_sd = (int32_t)(Rs1_uw/Rs2_uw); 324 } 325 }}, IntDivOp); 326 0x20: sraw({{ 327 Rd_sd = Rs1_sw >> Rs2<4:0>; 328 }}); 329 } 330 0x6: remw({{ 331 if (Rs2_sw == 0) { 332 Rd_sd = Rs1_sw; 333 } else if (Rs1_sw == std::numeric_limits<int32_t>::min() 334 && Rs2_sw == -1) { 335 Rd_sd = 0; 336 } else { 337 Rd_sd = Rs1_sw%Rs2_sw; 338 } 339 }}, IntDivOp); 340 0x7: remuw({{ 341 if (Rs2_uw == 0) { 342 Rd_sd = (int32_t)Rs1_uw; 343 } else { 344 Rd_sd = (int32_t)(Rs1_uw%Rs2_uw); 345 } 346 }}, IntDivOp); 347 } 348 } 349 350 0x63: decode FUNCT3 { 351 format SBOp { 352 0x0: beq({{ 353 if (Rs1 == Rs2) { 354 NPC = PC + imm; 355 } else { 356 NPC = NPC; 357 } 358 }}, IsDirectControl, IsCondControl); 359 0x1: bne({{ 360 if (Rs1 != Rs2) { 361 NPC = PC + imm; 362 } else { 363 NPC = NPC; 364 } 365 }}, IsDirectControl, IsCondControl); 366 0x4: blt({{ 367 if (Rs1_sd < Rs2_sd) { 368 NPC = PC + imm; 369 } else { 370 NPC = NPC; 371 } 372 }}, IsDirectControl, IsCondControl); 373 0x5: bge({{ 374 if (Rs1_sd >= Rs2_sd) { 375 NPC = PC + imm; 376 } else { 377 NPC = NPC; 378 } 379 }}, IsDirectControl, IsCondControl); 380 0x6: bltu({{ 381 if (Rs1 < Rs2) { 382 NPC = PC + imm; 383 } else { 384 NPC = NPC; 385 } 386 }}, IsDirectControl, IsCondControl); 387 0x7: bgeu({{ 388 if (Rs1 >= Rs2) { 389 NPC = PC + imm; 390 } else { 391 NPC = NPC; 392 } 393 }}, IsDirectControl, IsCondControl); 394 } 395 } 396 397 0x67: decode FUNCT3 { 398 0x0: Jump::jalr({{ 399 Rd = NPC; 400 NPC = (imm + Rs1) & (~0x1); 401 }}, IsIndirectControl, IsUncondControl, IsCall); 402 } 403 404 0x6f: UJOp::jal({{ 405 Rd = NPC; 406 NPC = PC + imm; 407 }}, IsDirectControl, IsUncondControl, IsCall); 408 409 0x73: decode FUNCT3 { 410 format IOp { 411 0x0: decode FUNCT12 { 412 0x0: ecall({{ 413 fault = std::make_shared<SyscallFault>(); 414 }}, IsSerializeAfter, IsNonSpeculative, IsSyscall, No_OpClass); 415 0x1: ebreak({{ 416 fault = std::make_shared<BreakpointFault>(); 417 }}, IsSerializeAfter, IsNonSpeculative, No_OpClass); 418 0x100: eret({{ 419 fault = std::make_shared<UnimplementedFault>("eret"); 420 }}, No_OpClass); 421 } 422 0x1: csrrw({{ 423 Rd = xc->readMiscReg(FUNCT12); 424 xc->setMiscReg(FUNCT12, Rs1); 425 }}, IsNonSpeculative, No_OpClass); 426 0x2: csrrs({{ 427 Rd = xc->readMiscReg(FUNCT12); 428 if (Rs1 != 0) { 429 xc->setMiscReg(FUNCT12, Rd | Rs1); 430 } 431 }}, IsNonSpeculative, No_OpClass); 432 0x3: csrrc({{ 433 Rd = xc->readMiscReg(FUNCT12); 434 if (Rs1 != 0) { 435 xc->setMiscReg(FUNCT12, Rd & ~Rs1); 436 } 437 }}, IsNonSpeculative, No_OpClass); 438 0x5: csrrwi({{ 439 Rd = xc->readMiscReg(FUNCT12); 440 xc->setMiscReg(FUNCT12, ZIMM); 441 }}, IsNonSpeculative, No_OpClass); 442 0x6: csrrsi({{ 443 Rd = xc->readMiscReg(FUNCT12); 444 if (ZIMM != 0) { 445 xc->setMiscReg(FUNCT12, Rd | ZIMM); 446 } 447 }}, IsNonSpeculative, No_OpClass); 448 0x7: csrrci({{ 449 Rd = xc->readMiscReg(FUNCT12); 450 if (ZIMM != 0) { 451 xc->setMiscReg(FUNCT12, Rd & ~ZIMM); 452 } 453 }}, IsNonSpeculative, No_OpClass); 454 } 455 } 456} 457