decoder.isa revision 3954:d689b611d9dc
1// -*- mode:c++ -*- 2 3// Copyright (c) 2006 The Regents of The University of Michigan 4// All rights reserved. 5// 6// Redistribution and use in source and binary forms, with or without 7// modification, are permitted provided that the following conditions are 8// met: redistributions of source code must retain the above copyright 9// notice, this list of conditions and the following disclaimer; 10// redistributions in binary form must reproduce the above copyright 11// notice, this list of conditions and the following disclaimer in the 12// documentation and/or other materials provided with the distribution; 13// neither the name of the copyright holders nor the names of its 14// contributors may be used to endorse or promote products derived from 15// this software without specific prior written permission. 16// 17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28// 29// Authors: Korey Sewell 30 31//////////////////////////////////////////////////////////////////// 32// 33// The actual MIPS32 ISA decoder 34// ----------------------------- 35// The following instructions are specified in the MIPS32 ISA 36// Specification. Decoding closely follows the style specified 37// in the MIPS32 ISA specification document starting with Table 38// A-2 (document available @ www.mips.com) 39// 40decode OPCODE_HI default Unknown::unknown() { 41 //Table A-2 42 0x0: decode OPCODE_LO { 43 0x0: decode FUNCTION_HI { 44 0x0: decode FUNCTION_LO { 45 0x1: decode MOVCI { 46 format BasicOp { 47 0: movf({{ Rd = (getCondCode(FCSR, CC) == 0) ? Rd : Rs; }}); 48 1: movt({{ Rd = (getCondCode(FCSR, CC) == 1) ? Rd : Rs; }}); 49 } 50 } 51 52 format BasicOp { 53 //Table A-3 Note: "Specific encodings of the rd, rs, and 54 //rt fields are used to distinguish SLL, SSNOP, and EHB 55 //functions 56 0x0: decode RS { 57 0x0: decode RT_RD { 58 0x0: decode SA default Nop::nop(){ 59 0x1: WarnUnimpl::ssnop(); 60 0x3: WarnUnimpl::ehb(); 61 } 62 default: sll({{ Rd = Rt.uw << SA; }}); 63 } 64 } 65 66 0x2: decode RS_SRL { 67 0x0:decode SRL { 68 0: srl({{ Rd = Rt.uw >> SA; }}); 69 70 //Hardcoded assuming 32-bit ISA, probably need parameter here 71 1: rotr({{ Rd = (Rt.uw << (32 - SA)) | (Rt.uw >> SA);}}); 72 } 73 } 74 75 0x3: decode RS { 76 0x0: sra({{ 77 uint32_t temp = Rt >> SA; 78 if ( (Rt & 0x80000000) > 0 ) { 79 uint32_t mask = 0x80000000; 80 for(int i=0; i < SA; i++) { 81 temp |= mask; 82 mask = mask >> 1; 83 } 84 } 85 Rd = temp; 86 }}); 87 } 88 89 0x4: sllv({{ Rd = Rt.uw << Rs<4:0>; }}); 90 91 0x6: decode SRLV { 92 0: srlv({{ Rd = Rt.uw >> Rs<4:0>; }}); 93 94 //Hardcoded assuming 32-bit ISA, probably need parameter here 95 1: rotrv({{ Rd = (Rt.uw << (32 - Rs<4:0>)) | (Rt.uw >> Rs<4:0>);}}); 96 } 97 98 0x7: srav({{ 99 int shift_amt = Rs<4:0>; 100 101 uint32_t temp = Rt >> shift_amt; 102 103 if ( (Rt & 0x80000000) > 0 ) { 104 uint32_t mask = 0x80000000; 105 for(int i=0; i < shift_amt; i++) { 106 temp |= mask; 107 mask = mask >> 1; 108 } 109 } 110 111 Rd = temp; 112 }}); 113 } 114 } 115 116 0x1: decode FUNCTION_LO { 117 //Table A-3 Note: "Specific encodings of the hint field are 118 //used to distinguish JR from JR.HB and JALR from JALR.HB" 119 format Jump { 120 0x0: decode HINT { 121 0x1: jr_hb({{ NNPC = Rs & ~1; }}, IsReturn, ClearHazards); 122 default: jr({{ NNPC = Rs & ~1; }}, IsReturn); 123 } 124 125 0x1: decode HINT { 126 0x1: jalr_hb({{ Rd = NNPC; NNPC = Rs; }}, IsCall, Link 127 , ClearHazards); 128 default: jalr({{ Rd = NNPC; NNPC = Rs; }}, IsCall, 129 Link); 130 } 131 } 132 133 format BasicOp { 134 0x2: movz({{ Rd = (Rt == 0) ? Rs : Rd; }}); 135 0x3: movn({{ Rd = (Rt != 0) ? Rs : Rd; }}); 136 0x4: syscall({{ xc->syscall(R2); }}, 137 IsSerializeAfter, IsNonSpeculative); 138 0x7: sync({{ ; }}, IsMemBarrier); 139 } 140 141 format FailUnimpl { 142 0x5: break(); 143 } 144 } 145 146 0x2: decode FUNCTION_LO { 147 format HiLoMiscOp { 148 0x0: mfhi({{ Rd = HI; }}); 149 0x1: mthi({{ HI = Rs; }}); 150 0x2: mflo({{ Rd = LO; }}); 151 0x3: mtlo({{ LO = Rs; }}); 152 } 153 } 154 155 0x3: decode FUNCTION_LO { 156 format HiLoOp { 157 0x0: mult({{ int64_t val = Rs.sd * Rt.sd; }}); 158 0x1: multu({{ uint64_t val = Rs.ud * Rt.ud; }}); 159 0x2: div({{ int64_t val; 160 if (Rt.sd != 0) { 161 int64_t hi = Rs.sd % Rt.sd; 162 int64_t lo = Rs.sd / Rt.sd; 163 val = (hi << 32) | lo; 164 } 165 }}); 166 0x3: divu({{ uint64_t val; 167 if (Rt.ud != 0) { 168 uint64_t hi = Rs.ud % Rt.ud; 169 uint64_t lo = Rs.ud / Rt.ud; 170 val = (hi << 32) | lo; 171 } 172 }}); 173 } 174 } 175 176 0x4: decode HINT { 177 0x0: decode FUNCTION_LO { 178 format IntOp { 179 0x0: add({{ Rd.sw = Rs.sw + Rt.sw; /*Trap on Overflow*/}}); 180 0x1: addu({{ Rd.sw = Rs.sw + Rt.sw;}}); 181 0x2: sub({{ Rd.sw = Rs.sw - Rt.sw; /*Trap on Overflow*/}}); 182 0x3: subu({{ Rd.sw = Rs.sw - Rt.sw;}}); 183 0x4: and({{ Rd = Rs & Rt;}}); 184 0x5: or({{ Rd = Rs | Rt;}}); 185 0x6: xor({{ Rd = Rs ^ Rt;}}); 186 0x7: nor({{ Rd = ~(Rs | Rt);}}); 187 } 188 } 189 } 190 191 0x5: decode HINT { 192 0x0: decode FUNCTION_LO { 193 format IntOp{ 194 0x2: slt({{ Rd.sw = ( Rs.sw < Rt.sw ) ? 1 : 0}}); 195 0x3: sltu({{ Rd.uw = ( Rs.uw < Rt.uw ) ? 1 : 0}}); 196 } 197 } 198 } 199 200 0x6: decode FUNCTION_LO { 201 format Trap { 202 0x0: tge({{ cond = (Rs.sw >= Rt.sw); }}); 203 0x1: tgeu({{ cond = (Rs.uw >= Rt.uw); }}); 204 0x2: tlt({{ cond = (Rs.sw < Rt.sw); }}); 205 0x3: tltu({{ cond = (Rs.uw >= Rt.uw); }}); 206 0x4: teq({{ cond = (Rs.sw == Rt.sw); }}); 207 0x6: tne({{ cond = (Rs.sw != Rt.sw); }}); 208 } 209 } 210 } 211 212 0x1: decode REGIMM_HI { 213 0x0: decode REGIMM_LO { 214 format Branch { 215 0x0: bltz({{ cond = (Rs.sw < 0); }}); 216 0x1: bgez({{ cond = (Rs.sw >= 0); }}); 217 0x2: bltzl({{ cond = (Rs.sw < 0); }}, Likely); 218 0x3: bgezl({{ cond = (Rs.sw >= 0); }}, Likely); 219 } 220 } 221 222 0x1: decode REGIMM_LO { 223 format Trap { 224 0x0: tgei( {{ cond = (Rs.sw >= INTIMM); }}); 225 0x1: tgeiu({{ cond = (Rs.uw >= INTIMM); }}); 226 0x2: tlti( {{ cond = (Rs.sw < INTIMM); }}); 227 0x3: tltiu({{ cond = (Rs.uw < INTIMM); }}); 228 0x4: teqi( {{ cond = (Rs.sw == INTIMM);}}); 229 0x6: tnei( {{ cond = (Rs.sw != INTIMM);}}); 230 } 231 } 232 233 0x2: decode REGIMM_LO { 234 format Branch { 235 0x0: bltzal({{ cond = (Rs.sw < 0); }}, Link); 236 0x1: decode RS { 237 0x0: bal ({{ cond = 1; }}, IsCall, Link); 238 default: bgezal({{ cond = (Rs.sw >= 0); }}, Link); 239 } 240 0x2: bltzall({{ cond = (Rs.sw < 0); }}, Link, Likely); 241 0x3: bgezall({{ cond = (Rs.sw >= 0); }}, Link, Likely); 242 } 243 } 244 245 0x3: decode REGIMM_LO { 246 format WarnUnimpl { 247 0x7: synci(); 248 } 249 } 250 } 251 252 format Jump { 253 0x2: j({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2);}}); 254 0x3: jal({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2); }}, IsCall, 255 Link); 256 } 257 258 format Branch { 259 0x4: decode RS_RT { 260 0x0: b({{ cond = 1; }}); 261 default: beq({{ cond = (Rs.sw == Rt.sw); }}); 262 } 263 0x5: bne({{ cond = (Rs.sw != Rt.sw); }}); 264 0x6: blez({{ cond = (Rs.sw <= 0); }}); 265 0x7: bgtz({{ cond = (Rs.sw > 0); }}); 266 } 267 } 268 269 0x1: decode OPCODE_LO { 270 format IntImmOp { 271 0x0: addi({{ Rt.sw = Rs.sw + imm; /*Trap If Overflow*/}}); 272 0x1: addiu({{ Rt.sw = Rs.sw + imm;}}); 273 0x2: slti({{ Rt.sw = ( Rs.sw < imm) ? 1 : 0 }}); 274 0x3: sltiu({{ Rt.uw = ( Rs.uw < (uint32_t)sextImm ) ? 1 : 0 }}); 275 0x4: andi({{ Rt.sw = Rs.sw & zextImm;}}); 276 0x5: ori({{ Rt.sw = Rs.sw | zextImm;}}); 277 0x6: xori({{ Rt.sw = Rs.sw ^ zextImm;}}); 278 279 0x7: decode RS { 280 0x0: lui({{ Rt = imm << 16}}); 281 } 282 } 283 } 284 285 0x2: decode OPCODE_LO { 286 //Table A-11 MIPS32 COP0 Encoding of rs Field 287 0x0: decode RS_MSB { 288 0x0: decode RS { 289 format CP0Control { 290 0x0: mfc0({{ Rt = xc->readMiscReg(RD << 5 | SEL); }}); 291 0x4: mtc0({{ xc->setMiscReg(RD << 5 | SEL, Rt); }}); 292 } 293 294 format MipsMT { 295 0x8: mftr(); 296 0xC: mttr(); 297 0xB: decode RD { 298 0x0: decode SC { 299 0x0: dvpe(); 300 0x1: evpe(); 301 } 302 0x1: decode SC { 303 0x0: dmt(); 304 0x1: emt(); 305 0xC: decode SC { 306 0x0: di(); 307 0x1: ei(); 308 } 309 } 310 } 311 } 312 313 format FailUnimpl { 314 0xA: rdpgpr(); 315 0xE: wrpgpr(); 316 } 317 } 318 319 //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO 320 0x1: decode FUNCTION { 321 format FailUnimpl { 322 0x01: tlbr(); 323 0x02: tlbwi(); 324 0x06: tlbwr(); 325 0x08: tlbp(); 326 327 0x18: eret(); 328 0x1F: deret(); 329 0x20: wait(); 330 } 331 } 332 } 333 334 //Table A-13 MIPS32 COP1 Encoding of rs Field 335 0x1: decode RS_MSB { 336 337 0x0: decode RS_HI { 338 0x0: decode RS_LO { 339 format CP1Control { 340 0x0: mfc1 ({{ Rt.uw = Fs.uw; }}); 341 342 0x2: cfc1({{ 343 switch (FS) 344 { 345 case 0: 346 Rt = FIR; 347 break; 348 case 25: 349 Rt = 0 | (FCSR & 0xFE000000) >> 24 | (FCSR & 0x00800000) >> 23; 350 break; 351 case 26: 352 Rt = 0 | (FCSR & 0x0003F07C); 353 break; 354 case 28: 355 Rt = 0 | (FCSR & 0x00000F80) | (FCSR & 0x01000000) >> 21 | (FCSR & 0x00000003); 356 break; 357 case 31: 358 Rt = FCSR; 359 break; 360 default: 361 panic("FP Control Value (%d) Not Valid"); 362 } 363 }}); 364 365 0x3: mfhc1({{ Rt.uw = Fs.ud<63:32>;}}); 366 367 0x4: mtc1 ({{ Fs.uw = Rt.uw; }}); 368 369 0x6: ctc1({{ 370 switch (FS) 371 { 372 case 25: 373 FCSR = 0 | (Rt.uw<7:1> << 25) // move 31...25 374 | (FCSR & 0x01000000) // bit 24 375 | (FCSR & 0x004FFFFF);// bit 22...0 376 break; 377 378 case 26: 379 FCSR = 0 | (FCSR & 0xFFFC0000) // move 31...18 380 | Rt.uw<17:12> << 12 // bit 17...12 381 | (FCSR & 0x00000F80) << 7// bit 11...7 382 | Rt.uw<6:2> << 2 // bit 6...2 383 | (FCSR & 0x00000002); // bit 1...0 384 break; 385 386 case 28: 387 FCSR = 0 | (FCSR & 0xFE000000) // move 31...25 388 | Rt.uw<2:2> << 24 // bit 24 389 | (FCSR & 0x00FFF000) << 23// bit 23...12 390 | Rt.uw<11:7> << 7 // bit 24 391 | (FCSR & 0x000007E) 392 | Rt.uw<1:0>;// bit 22...0 393 break; 394 395 case 31: 396 FCSR = Rt.uw; 397 break; 398 399 default: 400 panic("FP Control Value (%d) Not Available. Ignoring Access to" 401 "Floating Control Status Register", FS); 402 } 403 }}); 404 405 0x7: mthc1({{ 406 uint64_t fs_hi = Rt.uw; 407 uint64_t fs_lo = Fs.ud & 0x0FFFFFFFF; 408 Fs.ud = (fs_hi << 32) | fs_lo; 409 }}); 410 411 } 412 } 413 414 0x1: decode ND { 415 format Branch { 416 0x0: decode TF { 417 0x0: bc1f({{ cond = getCondCode(FCSR, BRANCH_CC) == 0; 418 }}); 419 0x1: bc1t({{ cond = getCondCode(FCSR, BRANCH_CC) == 1; 420 }}); 421 } 422 0x1: decode TF { 423 0x0: bc1fl({{ cond = getCondCode(FCSR, BRANCH_CC) == 0; 424 }}, Likely); 425 0x1: bc1tl({{ cond = getCondCode(FCSR, BRANCH_CC) == 1; 426 }}, Likely); 427 } 428 } 429 } 430 } 431 432 0x1: decode RS_HI { 433 0x2: decode RS_LO { 434 //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S 435 //(( single-precision floating point)) 436 0x0: decode FUNCTION_HI { 437 0x0: decode FUNCTION_LO { 438 format FloatOp { 439 0x0: add_s({{ Fd.sf = Fs.sf + Ft.sf;}}); 440 0x1: sub_s({{ Fd.sf = Fs.sf - Ft.sf;}}); 441 0x2: mul_s({{ Fd.sf = Fs.sf * Ft.sf;}}); 442 0x3: div_s({{ Fd.sf = Fs.sf / Ft.sf;}}); 443 0x4: sqrt_s({{ Fd.sf = sqrt(Fs.sf);}}); 444 0x5: abs_s({{ Fd.sf = fabs(Fs.sf);}}); 445 0x7: neg_s({{ Fd.sf = -Fs.sf;}}); 446 } 447 448 0x6: BasicOp::mov_s({{ Fd.sf = Fs.sf;}}); 449 } 450 451 0x1: decode FUNCTION_LO { 452 format FloatConvertOp { 453 0x0: round_l_s({{ val = Fs.sf; }}, ToLong, 454 Round); 455 0x1: trunc_l_s({{ val = Fs.sf; }}, ToLong, 456 Trunc); 457 0x2: ceil_l_s({{ val = Fs.sf; }}, ToLong, 458 Ceil); 459 0x3: floor_l_s({{ val = Fs.sf; }}, ToLong, 460 Floor); 461 0x4: round_w_s({{ val = Fs.sf; }}, ToWord, 462 Round); 463 0x5: trunc_w_s({{ val = Fs.sf; }}, ToWord, 464 Trunc); 465 0x6: ceil_w_s({{ val = Fs.sf; }}, ToWord, 466 Ceil); 467 0x7: floor_w_s({{ val = Fs.sf; }}, ToWord, 468 Floor); 469 } 470 } 471 472 0x2: decode FUNCTION_LO { 473 0x1: decode MOVCF { 474 format BasicOp { 475 0x0: movf_s({{ Fd = (getCondCode(FCSR,CC) == 0) ? Fs : Fd; }}); 476 0x1: movt_s({{ Fd = (getCondCode(FCSR,CC) == 1) ? Fs : Fd; }}); 477 } 478 } 479 480 format BasicOp { 481 0x2: movz_s({{ Fd = (Rt == 0) ? Fs : Fd; }}); 482 0x3: movn_s({{ Fd = (Rt != 0) ? Fs : Fd; }}); 483 } 484 485 format FloatOp { 486 0x5: recip_s({{ Fd = 1 / Fs; }}); 487 0x6: rsqrt_s({{ Fd = 1 / sqrt(Fs);}}); 488 } 489 } 490 491 0x4: decode FUNCTION_LO { 492 format FloatConvertOp { 493 0x1: cvt_d_s({{ val = Fs.sf; }}, ToDouble); 494 0x4: cvt_w_s({{ val = Fs.sf; }}, ToWord); 495 0x5: cvt_l_s({{ val = Fs.sf; }}, ToLong); 496 } 497 498 0x6: FloatOp::cvt_ps_s({{ 499 Fd.ud = (uint64_t) Fs.uw << 32 | 500 (uint64_t) Ft.uw; 501 }}); 502 } 503 504 0x6: decode FUNCTION_LO { 505 format FloatCompareOp { 506 0x0: c_f_s({{ cond = 0; }}, SinglePrecision, 507 UnorderedFalse); 508 0x1: c_un_s({{ cond = 0; }}, SinglePrecision, 509 UnorderedTrue); 510 0x2: c_eq_s({{ cond = (Fs.sf == Ft.sf); }}, 511 UnorderedFalse); 512 0x3: c_ueq_s({{ cond = (Fs.sf == Ft.sf); }}, 513 UnorderedTrue); 514 0x4: c_olt_s({{ cond = (Fs.sf < Ft.sf); }}, 515 UnorderedFalse); 516 0x5: c_ult_s({{ cond = (Fs.sf < Ft.sf); }}, 517 UnorderedTrue); 518 0x6: c_ole_s({{ cond = (Fs.sf <= Ft.sf); }}, 519 UnorderedFalse); 520 0x7: c_ule_s({{ cond = (Fs.sf <= Ft.sf); }}, 521 UnorderedTrue); 522 } 523 } 524 525 0x7: decode FUNCTION_LO { 526 format FloatCompareOp { 527 0x0: c_sf_s({{ cond = 0; }}, SinglePrecision, 528 UnorderedFalse, QnanException); 529 0x1: c_ngle_s({{ cond = 0; }}, SinglePrecision, 530 UnorderedTrue, QnanException); 531 0x2: c_seq_s({{ cond = (Fs.sf == Ft.sf);}}, 532 UnorderedFalse, QnanException); 533 0x3: c_ngl_s({{ cond = (Fs.sf == Ft.sf); }}, 534 UnorderedTrue, QnanException); 535 0x4: c_lt_s({{ cond = (Fs.sf < Ft.sf); }}, 536 UnorderedFalse, QnanException); 537 0x5: c_nge_s({{ cond = (Fs.sf < Ft.sf); }}, 538 UnorderedTrue, QnanException); 539 0x6: c_le_s({{ cond = (Fs.sf <= Ft.sf); }}, 540 UnorderedFalse, QnanException); 541 0x7: c_ngt_s({{ cond = (Fs.sf <= Ft.sf); }}, 542 UnorderedTrue, QnanException); 543 } 544 } 545 } 546 547 //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D 548 0x1: decode FUNCTION_HI { 549 0x0: decode FUNCTION_LO { 550 format FloatOp { 551 0x0: add_d({{ Fd.df = Fs.df + Ft.df; }}); 552 0x1: sub_d({{ Fd.df = Fs.df - Ft.df; }}); 553 0x2: mul_d({{ Fd.df = Fs.df * Ft.df; }}); 554 0x3: div_d({{ Fd.df = Fs.df / Ft.df; }}); 555 0x4: sqrt_d({{ Fd.df = sqrt(Fs.df); }}); 556 0x5: abs_d({{ Fd.df = fabs(Fs.df); }}); 557 0x7: neg_d({{ Fd.df = -1 * Fs.df; }}); 558 } 559 560 0x6: BasicOp::mov_d({{ Fd.df = Fs.df; }}); 561 } 562 563 0x1: decode FUNCTION_LO { 564 format FloatConvertOp { 565 0x0: round_l_d({{ val = Fs.df; }}, ToLong, 566 Round); 567 0x1: trunc_l_d({{ val = Fs.df; }}, ToLong, 568 Trunc); 569 0x2: ceil_l_d({{ val = Fs.df; }}, ToLong, 570 Ceil); 571 0x3: floor_l_d({{ val = Fs.df; }}, ToLong, 572 Floor); 573 0x4: round_w_d({{ val = Fs.df; }}, ToWord, 574 Round); 575 0x5: trunc_w_d({{ val = Fs.df; }}, ToWord, 576 Trunc); 577 0x6: ceil_w_d({{ val = Fs.df; }}, ToWord, 578 Ceil); 579 0x7: floor_w_d({{ val = Fs.df; }}, ToWord, 580 Floor); 581 } 582 } 583 584 0x2: decode FUNCTION_LO { 585 0x1: decode MOVCF { 586 format BasicOp { 587 0x0: movf_d({{ Fd.df = (getCondCode(FCSR,CC) == 0) ? 588 Fs.df : Fd.df; 589 }}); 590 0x1: movt_d({{ Fd.df = (getCondCode(FCSR,CC) == 1) ? 591 Fs.df : Fd.df; 592 }}); 593 } 594 } 595 596 format BasicOp { 597 0x2: movz_d({{ Fd.df = (Rt == 0) ? Fs.df : Fd.df; }}); 598 0x3: movn_d({{ Fd.df = (Rt != 0) ? Fs.df : Fd.df; }}); 599 } 600 601 format FloatOp { 602 0x5: recip_d({{ Fd.df = 1 / Fs.df }}); 603 0x6: rsqrt_d({{ Fd.df = 1 / sqrt(Fs.df) }}); 604 } 605 } 606 607 0x4: decode FUNCTION_LO { 608 format FloatConvertOp { 609 0x0: cvt_s_d({{ val = Fs.df; }}, ToSingle); 610 0x4: cvt_w_d({{ val = Fs.df; }}, ToWord); 611 0x5: cvt_l_d({{ val = Fs.df; }}, ToLong); 612 } 613 } 614 615 0x6: decode FUNCTION_LO { 616 format FloatCompareOp { 617 0x0: c_f_d({{ cond = 0; }}, DoublePrecision, 618 UnorderedFalse); 619 0x1: c_un_d({{ cond = 0; }}, DoublePrecision, 620 UnorderedTrue); 621 0x2: c_eq_d({{ cond = (Fs.df == Ft.df); }}, 622 UnorderedFalse); 623 0x3: c_ueq_d({{ cond = (Fs.df == Ft.df); }}, 624 UnorderedTrue); 625 0x4: c_olt_d({{ cond = (Fs.df < Ft.df); }}, 626 UnorderedFalse); 627 0x5: c_ult_d({{ cond = (Fs.df < Ft.df); }}, 628 UnorderedTrue); 629 0x6: c_ole_d({{ cond = (Fs.df <= Ft.df); }}, 630 UnorderedFalse); 631 0x7: c_ule_d({{ cond = (Fs.df <= Ft.df); }}, 632 UnorderedTrue); 633 } 634 } 635 636 0x7: decode FUNCTION_LO { 637 format FloatCompareOp { 638 0x0: c_sf_d({{ cond = 0; }}, DoublePrecision, 639 UnorderedFalse, QnanException); 640 0x1: c_ngle_d({{ cond = 0; }}, DoublePrecision, 641 UnorderedTrue, QnanException); 642 0x2: c_seq_d({{ cond = (Fs.df == Ft.df); }}, 643 UnorderedFalse, QnanException); 644 0x3: c_ngl_d({{ cond = (Fs.df == Ft.df); }}, 645 UnorderedTrue, QnanException); 646 0x4: c_lt_d({{ cond = (Fs.df < Ft.df); }}, 647 UnorderedFalse, QnanException); 648 0x5: c_nge_d({{ cond = (Fs.df < Ft.df); }}, 649 UnorderedTrue, QnanException); 650 0x6: c_le_d({{ cond = (Fs.df <= Ft.df); }}, 651 UnorderedFalse, QnanException); 652 0x7: c_ngt_d({{ cond = (Fs.df <= Ft.df); }}, 653 UnorderedTrue, QnanException); 654 } 655 } 656 } 657 658 //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W 659 0x4: decode FUNCTION { 660 format FloatConvertOp { 661 0x20: cvt_s_w({{ val = Fs.uw; }}, ToSingle); 662 0x21: cvt_d_w({{ val = Fs.uw; }}, ToDouble); 663 0x26: FailUnimpl::cvt_ps_w(); 664 } 665 } 666 667 //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=L1 668 //Note: "1. Format type L is legal only if 64-bit floating point operations 669 //are enabled." 670 0x5: decode FUNCTION_HI { 671 format FloatConvertOp { 672 0x20: cvt_s_l({{ val = Fs.ud; }}, ToSingle); 673 0x21: cvt_d_l({{ val = Fs.ud; }}, ToDouble); 674 0x26: FailUnimpl::cvt_ps_l(); 675 } 676 } 677 678 //Table A-17 MIPS64 COP1 Encoding of Function Field When rs=PS1 679 //Note: "1. Format type PS is legal only if 64-bit floating point operations 680 //are enabled. " 681 0x6: decode FUNCTION_HI { 682 0x0: decode FUNCTION_LO { 683 format Float64Op { 684 0x0: add_ps({{ 685 Fd1.sf = Fs1.sf + Ft2.sf; 686 Fd2.sf = Fs2.sf + Ft2.sf; 687 }}); 688 0x1: sub_ps({{ 689 Fd1.sf = Fs1.sf - Ft2.sf; 690 Fd2.sf = Fs2.sf - Ft2.sf; 691 }}); 692 0x2: mul_ps({{ 693 Fd1.sf = Fs1.sf * Ft2.sf; 694 Fd2.sf = Fs2.sf * Ft2.sf; 695 }}); 696 0x5: abs_ps({{ 697 Fd1.sf = fabs(Fs1.sf); 698 Fd2.sf = fabs(Fs2.sf); 699 }}); 700 0x6: mov_ps({{ 701 Fd1.sf = Fs1.sf; 702 Fd2.sf = Fs2.sf; 703 }}); 704 0x7: neg_ps({{ 705 Fd1.sf = -(Fs1.sf); 706 Fd2.sf = -(Fs2.sf); 707 }}); 708 } 709 } 710 711 0x2: decode FUNCTION_LO { 712 0x1: decode MOVCF { 713 format Float64Op { 714 0x0: movf_ps({{ 715 Fd1 = (getCondCode(FCSR, CC) == 0) ? 716 Fs1 : Fd1; 717 Fd2 = (getCondCode(FCSR, CC+1) == 0) ? 718 Fs2 : Fd2; 719 }}); 720 0x1: movt_ps({{ 721 Fd2 = (getCondCode(FCSR, CC) == 1) ? 722 Fs1 : Fd1; 723 Fd2 = (getCondCode(FCSR, CC+1) == 1) ? 724 Fs2 : Fd2; 725 }}); 726 } 727 } 728 729 format Float64Op { 730 0x2: movz_ps({{ 731 Fd1 = (getCondCode(FCSR, CC) == 0) ? 732 Fs1 : Fd1; 733 Fd2 = (getCondCode(FCSR, CC) == 0) ? 734 Fs2 : Fd2; 735 }}); 736 0x3: movn_ps({{ 737 Fd1 = (getCondCode(FCSR, CC) == 1) ? 738 Fs1 : Fd1; 739 Fd2 = (getCondCode(FCSR, CC) == 1) ? 740 Fs2 : Fd2; 741 }}); 742 } 743 744 } 745 746 0x4: decode FUNCTION_LO { 747 0x0: FloatOp::cvt_s_pu({{ Fd.sf = Fs2.sf; }}); 748 } 749 750 0x5: decode FUNCTION_LO { 751 0x0: FloatOp::cvt_s_pl({{ Fd.sf = Fs1.sf; }}); 752 753 format Float64Op { 754 0x4: pll({{ Fd.ud = (uint64_t) Fs1.uw << 32 | 755 Ft1.uw; 756 }}); 757 0x5: plu({{ Fd.ud = (uint64_t) Fs1.uw << 32 | 758 Ft2.uw; 759 }}); 760 0x6: pul({{ Fd.ud = (uint64_t) Fs2.uw << 32 | 761 Ft1.uw; 762 }}); 763 0x7: puu({{ Fd.ud = (uint64_t) Fs2.uw << 32 | 764 Ft2.uw; 765 }}); 766 } 767 } 768 769 0x6: decode FUNCTION_LO { 770 format FloatPSCompareOp { 771 0x0: c_f_ps({{ cond1 = 0; }}, {{ cond2 = 0; }}, 772 UnorderedFalse); 773 0x1: c_un_ps({{ cond1 = 0; }}, {{ cond2 = 0; }}, 774 UnorderedTrue); 775 0x2: c_eq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }}, 776 {{ cond2 = (Fs2.sf == Ft2.sf); }}, 777 UnorderedFalse); 778 0x3: c_ueq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }}, 779 {{ cond2 = (Fs2.sf == Ft2.sf); }}, 780 UnorderedTrue); 781 0x4: c_olt_ps({{ cond1 = (Fs1.sf < Ft1.sf); }}, 782 {{ cond2 = (Fs2.sf < Ft2.sf); }}, 783 UnorderedFalse); 784 0x5: c_ult_ps({{ cond1 = (Fs.sf < Ft.sf); }}, 785 {{ cond2 = (Fs2.sf < Ft2.sf); }}, 786 UnorderedTrue); 787 0x6: c_ole_ps({{ cond1 = (Fs.sf <= Ft.sf); }}, 788 {{ cond2 = (Fs2.sf <= Ft2.sf); }}, 789 UnorderedFalse); 790 0x7: c_ule_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }}, 791 {{ cond2 = (Fs2.sf <= Ft2.sf); }}, 792 UnorderedTrue); 793 } 794 } 795 796 0x7: decode FUNCTION_LO { 797 format FloatPSCompareOp { 798 0x0: c_sf_ps({{ cond1 = 0; }}, {{ cond2 = 0; }}, 799 UnorderedFalse, QnanException); 800 0x1: c_ngle_ps({{ cond1 = 0; }}, 801 {{ cond2 = 0; }}, 802 UnorderedTrue, QnanException); 803 0x2: c_seq_ps({{ cond1 = (Fs1.sf == Ft1.sf); }}, 804 {{ cond2 = (Fs2.sf == Ft2.sf); }}, 805 UnorderedFalse, QnanException); 806 0x3: c_ngl_ps({{ cond1 = (Fs1.sf == Ft1.sf); }}, 807 {{ cond2 = (Fs2.sf == Ft2.sf); }}, 808 UnorderedTrue, QnanException); 809 0x4: c_lt_ps({{ cond1 = (Fs1.sf < Ft1.sf); }}, 810 {{ cond2 = (Fs2.sf < Ft2.sf); }}, 811 UnorderedFalse, QnanException); 812 0x5: c_nge_ps({{ cond1 = (Fs1.sf < Ft1.sf); }}, 813 {{ cond2 = (Fs2.sf < Ft2.sf); }}, 814 UnorderedTrue, QnanException); 815 0x6: c_le_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }}, 816 {{ cond2 = (Fs2.sf <= Ft2.sf); }}, 817 UnorderedFalse, QnanException); 818 0x7: c_ngt_ps({{ cond1 = (Fs1.sf <= Ft1.sf); }}, 819 {{ cond2 = (Fs2.sf <= Ft2.sf); }}, 820 UnorderedTrue, QnanException); 821 } 822 } 823 } 824 } 825 } 826 } 827 828 //Table A-19 MIPS32 COP2 Encoding of rs Field 829 0x2: decode RS_MSB { 830 format FailUnimpl { 831 0x0: decode RS_HI { 832 0x0: decode RS_LO { 833 0x0: mfc2(); 834 0x2: cfc2(); 835 0x3: mfhc2(); 836 0x4: mtc2(); 837 0x6: ctc2(); 838 0x7: mftc2(); 839 } 840 841 0x1: decode ND { 842 0x0: decode TF { 843 0x0: bc2f(); 844 0x1: bc2t(); 845 } 846 847 0x1: decode TF { 848 0x0: bc2fl(); 849 0x1: bc2tl(); 850 } 851 } 852 } 853 } 854 } 855 856 //Table A-20 MIPS64 COP1X Encoding of Function Field 1 857 //Note: "COP1X instructions are legal only if 64-bit floating point 858 //operations are enabled." 859 0x3: decode FUNCTION_HI { 860 0x0: decode FUNCTION_LO { 861 format LoadIndexedMemory { 862 0x0: lwxc1({{ Fd.uw = Mem.uw;}}); 863 0x1: ldxc1({{ Fd.ud = Mem.ud;}}); 864 0x5: luxc1({{ Fd.ud = Mem.ud;}}, 865 {{ EA = (Rs + Rt) & ~7; }}); 866 } 867 } 868 869 0x1: decode FUNCTION_LO { 870 format StoreIndexedMemory { 871 0x0: swxc1({{ Mem.uw = Fs.uw;}}); 872 0x1: sdxc1({{ Mem.ud = Fs.ud;}}); 873 0x5: suxc1({{ Mem.ud = Fs.ud;}}, 874 {{ EA = (Rs + Rt) & ~7; }}); 875 } 876 877 0x7: Prefetch::prefx({{ EA = Rs + Rt; }}); 878 } 879 880 0x3: decode FUNCTION_LO { 881 0x6: Float64Op::alnv_ps({{ if (Rs<2:0> == 0) { 882 Fd.ud = Fs.ud; 883 } else if (Rs<2:0> == 4) { 884 #if BYTE_ORDER == BIG_ENDIAN 885 Fd.ud = Fs.ud<31:0> << 32 | 886 Ft.ud<63:32>; 887 #elif BYTE_ORDER == LITTLE_ENDIAN 888 Fd.ud = Ft.ud<31:0> << 32 | 889 Fs.ud<63:32>; 890 #endif 891 } else { 892 Fd.ud = Fd.ud; 893 } 894 }}); 895 } 896 897 format FloatAccOp { 898 0x4: decode FUNCTION_LO { 899 0x0: madd_s({{ Fd.sf = (Fs.sf * Ft.sf) + Fr.sf; }}); 900 0x1: madd_d({{ Fd.df = (Fs.df * Ft.df) + Fr.df; }}); 901 0x6: madd_ps({{ 902 Fd1.sf = (Fs1.df * Ft1.df) + Fr1.df; 903 Fd2.sf = (Fs2.df * Ft2.df) + Fr2.df; 904 }}); 905 } 906 907 0x5: decode FUNCTION_LO { 908 0x0: msub_s({{ Fd.sf = (Fs.sf * Ft.sf) - Fr.sf; }}); 909 0x1: msub_d({{ Fd.df = (Fs.df * Ft.df) - Fr.df; }}); 910 0x6: msub_ps({{ 911 Fd1.sf = (Fs1.df * Ft1.df) - Fr1.df; 912 Fd2.sf = (Fs2.df * Ft2.df) - Fr2.df; 913 }}); 914 } 915 916 0x6: decode FUNCTION_LO { 917 0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }}); 918 0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Ft.df) + Fr.df; }}); 919 0x6: nmadd_ps({{ 920 Fd1.sf = -((Fs1.df * Ft1.df) + Fr1.df); 921 Fd2.sf = -((Fs2.df * Ft2.df) + Fr2.df); 922 }}); 923 } 924 925 0x7: decode FUNCTION_LO { 926 0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }}); 927 0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Ft.df) - Fr.df; }}); 928 0x6: nmsub_ps({{ 929 Fd1.sf = -((Fs1.df * Ft1.df) - Fr1.df); 930 Fd2.sf = -((Fs2.df * Ft2.df) - Fr2.df); 931 }}); 932 } 933 934 } 935 } 936 937 format Branch { 938 0x4: beql({{ cond = (Rs.sw == Rt.sw); }}, Likely); 939 0x5: bnel({{ cond = (Rs.sw != Rt.sw); }}, Likely); 940 0x6: blezl({{ cond = (Rs.sw <= 0); }}, Likely); 941 0x7: bgtzl({{ cond = (Rs.sw > 0); }}, Likely); 942 } 943 } 944 945 0x3: decode OPCODE_LO { 946 //Table A-5 MIPS32 SPECIAL2 Encoding of Function Field 947 0x4: decode FUNCTION_HI { 948 0x0: decode FUNCTION_LO { 949 0x2: IntOp::mul({{ int64_t temp1 = Rs.sd * Rt.sd; 950 Rd.sw = temp1<31:0> 951 }}); 952 953 format HiLoOp { 954 0x0: madd({{ int64_t val = ((int64_t) HI << 32 | LO) + 955 (Rs.sd * Rt.sd); 956 }}); 957 0x1: maddu({{ uint64_t val = ((uint64_t) HI << 32 | LO) + 958 (Rs.ud * Rt.ud); 959 }}); 960 0x4: msub({{ int64_t val = ((int64_t) HI << 32 | LO) - 961 (Rs.sd * Rt.sd); 962 }}); 963 0x5: msubu({{ uint64_t val = ((uint64_t) HI << 32 | LO) - 964 (Rs.ud * Rt.ud); 965 }}); 966 } 967 } 968 969 0x4: decode FUNCTION_LO { 970 format BasicOp { 971 0x0: clz({{ int cnt = 32; 972 for (int idx = 31; idx >= 0; idx--) { 973 if( Rs<idx:idx> == 1) { 974 cnt = 31 - idx; 975 break; 976 } 977 } 978 Rd.uw = cnt; 979 }}); 980 0x1: clo({{ int cnt = 32; 981 for (int idx = 31; idx >= 0; idx--) { 982 if( Rs<idx:idx> == 0) { 983 cnt = 31 - idx; 984 break; 985 } 986 } 987 Rd.uw = cnt; 988 }}); 989 } 990 } 991 992 0x7: decode FUNCTION_LO { 993 0x7: FailUnimpl::sdbbp(); 994 } 995 } 996 997 //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2 998 //of the Architecture 999 0x7: decode FUNCTION_HI { 1000 0x0: decode FUNCTION_LO { 1001 format BasicOp { 1002 0x0: ext({{ Rt.uw = bits(Rs.uw, MSB+LSB, LSB); }}); 1003 0x4: ins({{ Rt.uw = bits(Rt.uw, 31, MSB+1) << (MSB+1) | 1004 bits(Rs.uw, MSB-LSB, 0) << LSB | 1005 bits(Rt.uw, LSB-1, 0); 1006 }}); 1007 } 1008 } 1009 1010 0x1: decode FUNCTION_LO { 1011 format MipsMT { 1012 0x0: fork(); 1013 0x1: yield(); 1014 } 1015 } 1016 1017 //Table A-10 MIPS32 BSHFL Encoding of sa Field 1018 0x4: decode SA { 1019 format BasicOp { 1020 0x02: wsbh({{ Rd.uw = Rt.uw<23:16> << 24 | 1021 Rt.uw<31:24> << 16 | 1022 Rt.uw<7:0> << 8 | 1023 Rt.uw<15:8>; 1024 }}); 1025 0x10: seb({{ Rd.sw = Rt.sb; }}); 1026 0x18: seh({{ Rd.sw = Rt.sh; }}); 1027 } 1028 } 1029 1030 0x6: decode FUNCTION_LO { 1031 0x7: FailUnimpl::rdhwr(); 1032 } 1033 } 1034 } 1035 1036 0x4: decode OPCODE_LO { 1037 format LoadMemory { 1038 0x0: lb({{ Rt.sw = Mem.sb; }}); 1039 0x1: lh({{ Rt.sw = Mem.sh; }}); 1040 0x3: lw({{ Rt.sw = Mem.sw; }}); 1041 0x4: lbu({{ Rt.uw = Mem.ub; }}); 1042 0x5: lhu({{ Rt.uw = Mem.uh; }}); 1043 } 1044 1045 format LoadUnalignedMemory { 1046 0x2: lwl({{ uint32_t mem_shift = 24 - (8 * byte_offset); 1047 Rt.uw = mem_word << mem_shift | 1048 Rt.uw & mask(mem_shift); 1049 }}); 1050 0x6: lwr({{ uint32_t mem_shift = 8 * byte_offset; 1051 Rt.uw = Rt.uw & (mask(mem_shift) << (32 - mem_shift)) | 1052 mem_word >> mem_shift; 1053 }}); 1054 } 1055 } 1056 1057 0x5: decode OPCODE_LO { 1058 format StoreMemory { 1059 0x0: sb({{ Mem.ub = Rt<7:0>; }}); 1060 0x1: sh({{ Mem.uh = Rt<15:0>; }}); 1061 0x3: sw({{ Mem.uw = Rt<31:0>; }}); 1062 } 1063 1064 format StoreUnalignedMemory { 1065 0x2: swl({{ uint32_t reg_shift = 24 - (8 * byte_offset); 1066 uint32_t mem_shift = 32 - reg_shift; 1067 mem_word = mem_word & (mask(reg_shift) << mem_shift) | 1068 Rt.uw >> reg_shift; 1069 }}); 1070 0x6: swr({{ uint32_t reg_shift = 8 * byte_offset; 1071 mem_word = Rt.uw << reg_shift | 1072 mem_word & (mask(reg_shift)); 1073 }}); 1074 } 1075 1076 0x7: FailUnimpl::cache(); 1077 } 1078 1079 0x6: decode OPCODE_LO { 1080 format LoadMemory { 1081 0x0: ll({{ Rt.uw = Mem.uw; }}, mem_flags=LOCKED); 1082 0x1: lwc1({{ Ft.uw = Mem.uw; }}); 1083 0x5: ldc1({{ Ft.ud = Mem.ud; }}); 1084 } 1085 1086 0x3: Prefetch::pref(); 1087 } 1088 1089 1090 0x7: decode OPCODE_LO { 1091 0x0: StoreCond::sc({{ Mem.uw = Rt.uw;}}, 1092 {{ uint64_t tmp = write_result; 1093 Rt.uw = (tmp == 0 || tmp == 1) ? tmp : Rt.uw; 1094 }}, mem_flags=LOCKED, inst_flags = IsStoreConditional); 1095 1096 format StoreMemory { 1097 0x1: swc1({{ Mem.uw = Ft.uw; }}); 1098 0x5: sdc1({{ Mem.ud = Ft.ud; }}); 1099 } 1100 } 1101} 1102 1103 1104