1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 2 * Mupen64plus - interpreter.def * 3 * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ * 4 * Copyright (C) 2002 Hacktarux * 5 * * 6 * This program is free software; you can redistribute it and/or modify * 7 * it under the terms of the GNU General Public License as published by * 8 * the Free Software Foundation; either version 2 of the License, or * 9 * (at your option) any later version. * 10 * * 11 * This program is distributed in the hope that it will be useful, * 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 14 * GNU General Public License for more details. * 15 * * 16 * You should have received a copy of the GNU General Public License * 17 * along with this program; if not, write to the * 18 * Free Software Foundation, Inc., * 19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 20 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 21 22/* Before #including this file, <stdint.h> and <inttypes.h> must be included, 23 * and the following macros must be defined: 24 * 25 * PCADDR: Program counter (memory address of the current instruction). 26 * 27 * ADD_TO_PC(x): Increment the program counter in 'x' instructions. 28 * This is only used for small changes to PC, so the new program counter 29 * is guaranteed to fall in the current cached interpreter or dynarec block. 30 * 31 * DECLARE_INSTRUCTION(name) 32 * Declares an instruction function which is not a jump. 33 * Followed by a block of code. 34 * 35 * DECLARE_JUMP(name, destination, condition, link, likely, cop1) 36 * name is the name of the jump or branch instruction. 37 * destination is the destination memory address of the jump. 38 * If condition is nonzero, the jump is taken. 39 * link is a pointer to a variable where (PC+8) is written unconditionally. 40 * To avoid linking, pass ®[0] 41 * If likely is nonzero, the delay slot is only executed if the jump is taken. 42 * If cop1 is nonzero, a COP1 unusable check will be done. 43 * 44 * CHECK_MEMORY(): A snippet to be run after a store instruction, 45 * to check if the store affected executable blocks. 46 * The memory address of the store is in the 'address' global. 47 */ 48 49#include "../main/device.h" 50#include "fpu.h" 51 52DECLARE_INSTRUCTION(NI) 53{ 54 DebugMessage(M64MSG_ERROR, "NI() @ 0x%" PRIX32, PCADDR); 55 DebugMessage(M64MSG_ERROR, "opcode not implemented: %" PRIX32 ":%" PRIX32, PCADDR, *fast_mem_access(PCADDR)); 56 stop=1; 57} 58 59DECLARE_INSTRUCTION(RESERVED) 60{ 61 DebugMessage(M64MSG_ERROR, "reserved opcode: %" PRIX32 ":%" PRIX32, PCADDR, *fast_mem_access(PCADDR)); 62 stop=1; 63} 64 65/* R4300 */ 66DECLARE_JUMP(J, (jinst_index<<2) | ((PCADDR+4) & UINT32_C(0xF0000000)), 1, ®[0], 0, 0) 67DECLARE_JUMP(JAL, (jinst_index<<2) | ((PCADDR+4) & UINT32_C(0xF0000000)), 1, ®[31], 0, 0) 68DECLARE_JUMP(BEQ, PCADDR + (iimmediate+1)*4, irs == irt, ®[0], 0, 0) 69DECLARE_JUMP(BNE, PCADDR + (iimmediate+1)*4, irs != irt, ®[0], 0, 0) 70DECLARE_JUMP(BLEZ, PCADDR + (iimmediate+1)*4, irs <= 0, ®[0], 0, 0) 71DECLARE_JUMP(BGTZ, PCADDR + (iimmediate+1)*4, irs > 0, ®[0], 0, 0) 72 73DECLARE_INSTRUCTION(ADDI) 74{ 75 irt = SE32((uint32_t)irs32 + (uint32_t)iimmediate); 76 ADD_TO_PC(1); 77} 78 79DECLARE_INSTRUCTION(ADDIU) 80{ 81 irt = SE32((uint32_t)irs32 + (uint32_t)iimmediate); 82 ADD_TO_PC(1); 83} 84 85DECLARE_INSTRUCTION(SLTI) 86{ 87 if (irs < iimmediate) irt = 1; 88 else irt = 0; 89 ADD_TO_PC(1); 90} 91 92DECLARE_INSTRUCTION(SLTIU) 93{ 94 if ((uint64_t) irs < (uint64_t) ((int64_t) iimmediate)) 95 irt = 1; 96 else irt = 0; 97 ADD_TO_PC(1); 98} 99 100DECLARE_INSTRUCTION(ANDI) 101{ 102 irt = irs & (uint16_t) iimmediate; 103 ADD_TO_PC(1); 104} 105 106DECLARE_INSTRUCTION(ORI) 107{ 108 irt = irs | (uint16_t) iimmediate; 109 ADD_TO_PC(1); 110} 111 112DECLARE_INSTRUCTION(XORI) 113{ 114 irt = irs ^ (uint16_t) iimmediate; 115 ADD_TO_PC(1); 116} 117 118DECLARE_INSTRUCTION(LUI) 119{ 120 irt = SE32((uint32_t)iimmediate << 16); 121 ADD_TO_PC(1); 122} 123 124DECLARE_JUMP(BEQL, PCADDR + (iimmediate+1)*4, irs == irt, ®[0], 1, 0) 125DECLARE_JUMP(BNEL, PCADDR + (iimmediate+1)*4, irs != irt, ®[0], 1, 0) 126DECLARE_JUMP(BLEZL, PCADDR + (iimmediate+1)*4, irs <= 0, ®[0], 1, 0) 127DECLARE_JUMP(BGTZL, PCADDR + (iimmediate+1)*4, irs > 0, ®[0], 1, 0) 128 129DECLARE_INSTRUCTION(DADDI) 130{ 131 irt = irs + iimmediate; 132 ADD_TO_PC(1); 133} 134 135DECLARE_INSTRUCTION(DADDIU) 136{ 137 irt = irs + iimmediate; 138 ADD_TO_PC(1); 139} 140 141/* Assists unaligned memory accessors with making masks to preserve or apply 142 * bits in registers and memory. 143 * 144 * BITS_BELOW_MASK32 and BITS_BELOW_MASK64 make masks where bits 0 to (x - 1) 145 * are set. 146 * 147 * BITS_ABOVE_MASK32 makes masks where bits x to 31 are set. 148 * BITS_ABOVE_MASK64 makes masks where bits x to 63 are set. 149 * 150 * e.g. x = 8 151 * 0000 0000 0000 0000 0000 0000 1111 1111 <- BITS_BELOW_MASK32(8) 152 * 1111 1111 1111 1111 1111 1111 0000 0000 <- BITS_ABOVE_MASK32(8) 153 * 154 * Giving a negative value or one that is >= the bit count of the mask results 155 * in undefined behavior. 156 */ 157 158#define BITS_BELOW_MASK32(x) ((UINT32_C(1) << (x)) - 1) 159#define BITS_ABOVE_MASK32(x) (~((UINT32_C(1) << (x)) - 1)) 160 161#define BITS_BELOW_MASK64(x) ((UINT64_C(1) << (x)) - 1) 162#define BITS_ABOVE_MASK64(x) (~((UINT64_C(1) << (x)) - 1)) 163 164DECLARE_INSTRUCTION(LDL) 165{ 166 const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate; 167 int64_t *lsrtp = &irt; 168 uint64_t word = 0; 169 ADD_TO_PC(1); 170 if ((lsaddr & 7) == 0) 171 { 172 address = lsaddr; 173 rdword = (uint64_t*) lsrtp; 174 read_dword_in_memory(); 175 } 176 else 177 { 178 address = lsaddr & UINT32_C(0xFFFFFFF8); 179 rdword = &word; 180 read_dword_in_memory(); 181 if (address) 182 { 183 /* How many low bits do we want to preserve from the old value? */ 184 uint64_t old_mask = BITS_BELOW_MASK64((lsaddr & 7) * 8); 185 /* How many bits up do we want to add the low bits of the new value in? */ 186 int new_shift = (lsaddr & 7) * 8; 187 *lsrtp = (*lsrtp & old_mask) | (word << new_shift); 188 } 189 } 190} 191 192DECLARE_INSTRUCTION(LDR) 193{ 194 const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate; 195 int64_t *lsrtp = &irt; 196 uint64_t word = 0; 197 ADD_TO_PC(1); 198 address = lsaddr & UINT32_C(0xFFFFFFF8); 199 if ((lsaddr & 7) == 7) 200 { 201 rdword = (uint64_t*) lsrtp; 202 read_dword_in_memory(); 203 } 204 else 205 { 206 rdword = &word; 207 read_dword_in_memory(); 208 if (address) 209 { 210 /* How many high bits do we want to preserve from the old value? */ 211 uint64_t old_mask = BITS_ABOVE_MASK64(((lsaddr & 7) + 1) * 8); 212 /* How many bits down do we want to add the high bits of the new value in? */ 213 int new_shift = (7 - (lsaddr & 7)) * 8; 214 *lsrtp = (*lsrtp & old_mask) | (word >> new_shift); 215 } 216 } 217} 218 219DECLARE_INSTRUCTION(LB) 220{ 221 const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate; 222 int64_t *lsrtp = &irt; 223 ADD_TO_PC(1); 224 address = lsaddr; 225 rdword = (uint64_t*) lsrtp; 226 read_byte_in_memory(); 227 if (address) 228 *lsrtp = SE8(*lsrtp); 229} 230 231DECLARE_INSTRUCTION(LH) 232{ 233 const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate; 234 int64_t *lsrtp = &irt; 235 ADD_TO_PC(1); 236 address = lsaddr; 237 rdword = (uint64_t*) lsrtp; 238 read_hword_in_memory(); 239 if (address) 240 *lsrtp = SE16(*lsrtp); 241} 242 243DECLARE_INSTRUCTION(LWL) 244{ 245 const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate; 246 int64_t *lsrtp = &irt; 247 uint64_t word = 0; 248 ADD_TO_PC(1); 249 if ((lsaddr & 3) == 0) 250 { 251 address = lsaddr; 252 rdword = (uint64_t*) lsrtp; 253 read_word_in_memory(); 254 if (address) 255 *lsrtp = SE32(*lsrtp); 256 } 257 else 258 { 259 address = lsaddr & UINT32_C(0xFFFFFFFC); 260 rdword = &word; 261 read_word_in_memory(); 262 if (address) 263 { 264 /* How many low bits do we want to preserve from the old value? */ 265 uint32_t old_mask = BITS_BELOW_MASK32((lsaddr & 3) * 8); 266 /* How many bits up do we want to add the low bits of the new value in? */ 267 int new_shift = (lsaddr & 3) * 8; 268 *lsrtp = SE32(((uint32_t) *lsrtp & old_mask) | ((uint32_t) word << new_shift)); 269 } 270 } 271} 272 273DECLARE_INSTRUCTION(LW) 274{ 275 const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate; 276 int64_t *lsrtp = &irt; 277 ADD_TO_PC(1); 278 address = lsaddr; 279 rdword = (uint64_t*) lsrtp; 280 read_word_in_memory(); 281 if (address) 282 *lsrtp = SE32(*lsrtp); 283} 284 285DECLARE_INSTRUCTION(LBU) 286{ 287 const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate; 288 int64_t *lsrtp = &irt; 289 ADD_TO_PC(1); 290 address = lsaddr; 291 rdword = (uint64_t*) lsrtp; 292 read_byte_in_memory(); 293} 294 295DECLARE_INSTRUCTION(LHU) 296{ 297 const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate; 298 int64_t *lsrtp = &irt; 299 ADD_TO_PC(1); 300 address = lsaddr; 301 rdword = (uint64_t*) lsrtp; 302 read_hword_in_memory(); 303} 304 305DECLARE_INSTRUCTION(LWR) 306{ 307 const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate; 308 int64_t *lsrtp = &irt; 309 uint64_t word = 0; 310 ADD_TO_PC(1); 311 address = lsaddr & UINT32_C(0xFFFFFFFC); 312 if ((lsaddr & 3) == 3) 313 { 314 rdword = (uint64_t*) lsrtp; 315 read_word_in_memory(); 316 if (address) 317 *lsrtp = SE32(*lsrtp); 318 } 319 else 320 { 321 rdword = &word; 322 read_word_in_memory(); 323 if (address) 324 { 325 /* How many high bits do we want to preserve from the old value? */ 326 uint32_t old_mask = BITS_ABOVE_MASK32(((lsaddr & 3) + 1) * 8); 327 /* How many bits down do we want to add the new value in? */ 328 int new_shift = (3 - (lsaddr & 3)) * 8; 329 *lsrtp = SE32(((uint32_t) *lsrtp & old_mask) | ((uint32_t) word >> new_shift)); 330 } 331 } 332} 333 334DECLARE_INSTRUCTION(LWU) 335{ 336 const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate; 337 int64_t *lsrtp = &irt; 338 ADD_TO_PC(1); 339 address = lsaddr; 340 rdword = (uint64_t*) lsrtp; 341 read_word_in_memory(); 342} 343 344DECLARE_INSTRUCTION(SB) 345{ 346 const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate; 347 int64_t *lsrtp = &irt; 348 ADD_TO_PC(1); 349 address = lsaddr; 350 cpu_byte = (uint8_t) *lsrtp; 351 write_byte_in_memory(); 352 CHECK_MEMORY(); 353} 354 355DECLARE_INSTRUCTION(SH) 356{ 357 const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate; 358 int64_t *lsrtp = &irt; 359 ADD_TO_PC(1); 360 address = lsaddr; 361 cpu_hword = (uint16_t) *lsrtp; 362 write_hword_in_memory(); 363 CHECK_MEMORY(); 364} 365 366DECLARE_INSTRUCTION(SWL) 367{ 368 const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate; 369 int64_t *lsrtp = &irt; 370 uint64_t old_word = 0; 371 ADD_TO_PC(1); 372 if ((lsaddr & 3) == 0) 373 { 374 address = lsaddr; 375 cpu_word = (uint32_t) *lsrtp; 376 write_word_in_memory(); 377 CHECK_MEMORY(); 378 } 379 else 380 { 381 address = lsaddr & UINT32_C(0xFFFFFFFC); 382 rdword = &old_word; 383 read_word_in_memory(); 384 if (address) 385 { 386 /* How many high bits do we want to preserve from what was in memory 387 * before? */ 388 uint32_t old_mask = BITS_ABOVE_MASK32((4 - (lsaddr & 3)) * 8); 389 /* How many bits down do we need to shift the register to store some 390 * of its high bits into the low bits of the memory word? */ 391 int new_shift = (lsaddr & 3) * 8; 392 cpu_word = ((uint32_t) old_word & old_mask) | ((uint32_t) *lsrtp >> new_shift); 393 write_word_in_memory(); 394 CHECK_MEMORY(); 395 } 396 } 397} 398 399DECLARE_INSTRUCTION(SW) 400{ 401 const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate; 402 int64_t *lsrtp = &irt; 403 ADD_TO_PC(1); 404 address = lsaddr; 405 cpu_word = (uint32_t) *lsrtp; 406 write_word_in_memory(); 407 CHECK_MEMORY(); 408} 409 410DECLARE_INSTRUCTION(SDL) 411{ 412 const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate; 413 int64_t *lsrtp = &irt; 414 uint64_t old_word = 0; 415 ADD_TO_PC(1); 416 if ((lsaddr & 7) == 0) 417 { 418 address = lsaddr; 419 cpu_dword = *lsrtp; 420 write_dword_in_memory(); 421 CHECK_MEMORY(); 422 } 423 else 424 { 425 address = lsaddr & UINT32_C(0xFFFFFFF8); 426 rdword = &old_word; 427 read_dword_in_memory(); 428 if (address) 429 { 430 /* How many high bits do we want to preserve from what was in memory 431 * before? */ 432 uint64_t old_mask = BITS_ABOVE_MASK64((8 - (lsaddr & 7)) * 8); 433 /* How many bits down do we need to shift the register to store some 434 * of its high bits into the low bits of the memory word? */ 435 int new_shift = (lsaddr & 7) * 8; 436 cpu_dword = (old_word & old_mask) | ((uint64_t) *lsrtp >> new_shift); 437 write_dword_in_memory(); 438 CHECK_MEMORY(); 439 } 440 } 441} 442 443DECLARE_INSTRUCTION(SDR) 444{ 445 const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate; 446 int64_t *lsrtp = &irt; 447 uint64_t old_word = 0; 448 ADD_TO_PC(1); 449 address = lsaddr & UINT32_C(0xFFFFFFF8); 450 if ((lsaddr & 7) == 7) 451 { 452 cpu_dword = *lsrtp; 453 write_dword_in_memory(); 454 CHECK_MEMORY(); 455 } 456 else 457 { 458 rdword = &old_word; 459 read_dword_in_memory(); 460 if (address) 461 { 462 /* How many low bits do we want to preserve from what was in memory 463 * before? */ 464 uint64_t old_mask = BITS_BELOW_MASK64((7 - (lsaddr & 7)) * 8); 465 /* How many bits up do we need to shift the register to store some 466 * of its low bits into the high bits of the memory word? */ 467 int new_shift = (7 - (lsaddr & 7)) * 8; 468 cpu_dword = (old_word & old_mask) | (*lsrtp << new_shift); 469 write_dword_in_memory(); 470 CHECK_MEMORY(); 471 } 472 } 473} 474 475DECLARE_INSTRUCTION(SWR) 476{ 477 const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate; 478 int64_t *lsrtp = &irt; 479 uint64_t old_word = 0; 480 ADD_TO_PC(1); 481 address = lsaddr & UINT32_C(0xFFFFFFFC); 482 if ((lsaddr & 3) == 3) 483 { 484 cpu_word = (uint32_t) *lsrtp; 485 write_word_in_memory(); 486 CHECK_MEMORY(); 487 } 488 else 489 { 490 rdword = &old_word; 491 read_word_in_memory(); 492 if (address) 493 { 494 /* How many low bits do we want to preserve from what was in memory 495 * before? */ 496 int32_t old_mask = BITS_BELOW_MASK32((3 - (lsaddr & 3)) * 8); 497 /* How many bits up do we need to shift the register to store some 498 * of its low bits into the high bits of the memory word? */ 499 int new_shift = (3 - (lsaddr & 3)) * 8; 500 cpu_word = ((uint32_t) old_word & old_mask) | ((uint32_t) *lsrtp << new_shift); 501 write_word_in_memory(); 502 CHECK_MEMORY(); 503 } 504 } 505} 506 507DECLARE_INSTRUCTION(CACHE) 508{ 509 ADD_TO_PC(1); 510} 511 512DECLARE_INSTRUCTION(LL) 513{ 514 const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate; 515 int64_t *lsrtp = &irt; 516 ADD_TO_PC(1); 517 address = lsaddr; 518 rdword = (uint64_t*) lsrtp; 519 read_word_in_memory(); 520 if (address) 521 { 522 *lsrtp = SE32(*lsrtp); 523 llbit = 1; 524 } 525} 526 527DECLARE_INSTRUCTION(LWC1) 528{ 529 const unsigned char lslfft = lfft; 530 const uint32_t lslfaddr = (uint32_t) reg[lfbase] + lfoffset; 531 uint64_t temp; 532 if (check_cop1_unusable()) return; 533 ADD_TO_PC(1); 534 address = lslfaddr; 535 rdword = &temp; 536 read_word_in_memory(); 537 if (address) 538 *((uint32_t*) reg_cop1_simple[lslfft]) = (uint32_t) *rdword; 539} 540 541DECLARE_INSTRUCTION(LDC1) 542{ 543 const unsigned char lslfft = lfft; 544 const uint32_t lslfaddr = (uint32_t) reg[lfbase] + lfoffset; 545 if (check_cop1_unusable()) return; 546 ADD_TO_PC(1); 547 address = lslfaddr; 548 rdword = (uint64_t*) reg_cop1_double[lslfft]; 549 read_dword_in_memory(); 550} 551 552DECLARE_INSTRUCTION(LD) 553{ 554 const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate; 555 int64_t *lsrtp = &irt; 556 ADD_TO_PC(1); 557 address = lsaddr; 558 rdword = (uint64_t*) lsrtp; 559 read_dword_in_memory(); 560} 561 562DECLARE_INSTRUCTION(SC) 563{ 564 const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate; 565 int64_t *lsrtp = &irt; 566 ADD_TO_PC(1); 567 if(llbit) 568 { 569 address = lsaddr; 570 cpu_word = (uint32_t) *lsrtp; 571 write_word_in_memory(); 572 CHECK_MEMORY(); 573 llbit = 0; 574 *lsrtp = 1; 575 } 576 else 577 { 578 *lsrtp = 0; 579 } 580} 581 582DECLARE_INSTRUCTION(SWC1) 583{ 584 const unsigned char lslfft = lfft; 585 const uint32_t lslfaddr = (uint32_t) reg[lfbase] + lfoffset; 586 if (check_cop1_unusable()) return; 587 ADD_TO_PC(1); 588 address = lslfaddr; 589 cpu_word = *((uint32_t*) reg_cop1_simple[lslfft]); 590 write_word_in_memory(); 591 CHECK_MEMORY(); 592} 593 594DECLARE_INSTRUCTION(SDC1) 595{ 596 const unsigned char lslfft = lfft; 597 const uint32_t lslfaddr = (uint32_t) reg[lfbase] + lfoffset; 598 if (check_cop1_unusable()) return; 599 ADD_TO_PC(1); 600 address = lslfaddr; 601 cpu_dword = *((uint64_t*) reg_cop1_double[lslfft]); 602 write_dword_in_memory(); 603 CHECK_MEMORY(); 604} 605 606DECLARE_INSTRUCTION(SD) 607{ 608 const uint32_t lsaddr = (uint32_t)irs32 + (uint32_t)iimmediate; 609 int64_t *lsrtp = &irt; 610 ADD_TO_PC(1); 611 address = lsaddr; 612 cpu_dword = *lsrtp; 613 write_dword_in_memory(); 614 CHECK_MEMORY(); 615} 616 617/* COP0 */ 618DECLARE_INSTRUCTION(MFC0) 619{ 620 switch(rfs) 621 { 622 case CP0_RANDOM_REG: 623 cp0_update_count(); 624 g_cp0_regs[CP0_RANDOM_REG] = (g_cp0_regs[CP0_COUNT_REG]/2 % (32 - g_cp0_regs[CP0_WIRED_REG])) 625 + g_cp0_regs[CP0_WIRED_REG]; 626 break; 627 case CP0_COUNT_REG: 628 cp0_update_count(); 629 break; 630 } 631 632 rrt = SE32(g_cp0_regs[rfs]); 633 ADD_TO_PC(1); 634} 635 636DECLARE_INSTRUCTION(MTC0) 637{ 638 switch(rfs) 639 { 640 case CP0_INDEX_REG: 641 g_cp0_regs[CP0_INDEX_REG] = rrt32 & UINT32_C(0x8000003F); 642 if ((g_cp0_regs[CP0_INDEX_REG] & UINT32_C(0x3F)) > UINT32_C(31)) 643 { 644 DebugMessage(M64MSG_ERROR, "MTC0 instruction writing Index register with TLB index > 31"); 645 stop=1; 646 } 647 break; 648 case CP0_RANDOM_REG: 649 break; 650 case CP0_ENTRYLO0_REG: 651 g_cp0_regs[CP0_ENTRYLO0_REG] = rrt32 & UINT32_C(0x3FFFFFFF); 652 break; 653 case CP0_ENTRYLO1_REG: 654 g_cp0_regs[CP0_ENTRYLO1_REG] = rrt32 & UINT32_C(0x3FFFFFFF); 655 break; 656 case CP0_CONTEXT_REG: 657 g_cp0_regs[CP0_CONTEXT_REG] = (rrt32 & UINT32_C(0xFF800000)) 658 | (g_cp0_regs[CP0_CONTEXT_REG] & UINT32_C(0x007FFFF0)); 659 break; 660 case CP0_PAGEMASK_REG: 661 g_cp0_regs[CP0_PAGEMASK_REG] = rrt32 & UINT32_C(0x01FFE000); 662 break; 663 case CP0_WIRED_REG: 664 g_cp0_regs[CP0_WIRED_REG] = rrt32; 665 g_cp0_regs[CP0_RANDOM_REG] = UINT32_C(31); 666 break; 667 case CP0_BADVADDR_REG: 668 break; 669 case CP0_COUNT_REG: 670 cp0_update_count(); 671 interrupt_unsafe_state = 1; 672 if (next_interrupt <= g_cp0_regs[CP0_COUNT_REG]) gen_interrupt(); 673 interrupt_unsafe_state = 0; 674 translate_event_queue(rrt32); 675 g_cp0_regs[CP0_COUNT_REG] = rrt32; 676 break; 677 case CP0_ENTRYHI_REG: 678 g_cp0_regs[CP0_ENTRYHI_REG] = rrt32 & UINT32_C(0xFFFFE0FF); 679 break; 680 case CP0_COMPARE_REG: 681 cp0_update_count(); 682 remove_event(COMPARE_INT); 683 add_interrupt_event_count(COMPARE_INT, rrt32); 684 g_cp0_regs[CP0_COMPARE_REG] = rrt32; 685 g_cp0_regs[CP0_CAUSE_REG] &= ~CP0_CAUSE_IP7; 686 break; 687 case CP0_STATUS_REG: 688 if((rrt32 & CP0_STATUS_FR) != (g_cp0_regs[CP0_STATUS_REG] & CP0_STATUS_FR)) 689 { 690 shuffle_fpr_data(g_cp0_regs[CP0_STATUS_REG], rrt32); 691 set_fpr_pointers(rrt32); 692 } 693 g_cp0_regs[CP0_STATUS_REG] = rrt32; 694 cp0_update_count(); 695 ADD_TO_PC(1); 696 check_interrupt(); 697 interrupt_unsafe_state = 1; 698 if (next_interrupt <= g_cp0_regs[CP0_COUNT_REG]) gen_interrupt(); 699 interrupt_unsafe_state = 0; 700 ADD_TO_PC(-1); 701 break; 702 case CP0_CAUSE_REG: 703 if (rrt32!=0) 704 { 705 DebugMessage(M64MSG_ERROR, "MTC0 instruction trying to write Cause register with non-0 value"); 706 stop = 1; 707 } 708 else g_cp0_regs[CP0_CAUSE_REG] = rrt32; 709 break; 710 case CP0_EPC_REG: 711 g_cp0_regs[CP0_EPC_REG] = rrt32; 712 break; 713 case CP0_PREVID_REG: 714 break; 715 case CP0_CONFIG_REG: 716 g_cp0_regs[CP0_CONFIG_REG] = rrt32; 717 break; 718 case CP0_WATCHLO_REG: 719 g_cp0_regs[CP0_WATCHLO_REG] = rrt32; 720 break; 721 case CP0_WATCHHI_REG: 722 g_cp0_regs[CP0_WATCHHI_REG] = rrt32; 723 break; 724 case CP0_TAGLO_REG: 725 g_cp0_regs[CP0_TAGLO_REG] = rrt32 & UINT32_C(0x0FFFFFC0); 726 break; 727 case CP0_TAGHI_REG: 728 g_cp0_regs[CP0_TAGHI_REG] = 0; 729 break; 730 case CP0_ERROREPC_REG: 731 g_cp0_regs[CP0_ERROREPC_REG] = rrt32; 732 break; 733 default: 734 DebugMessage(M64MSG_ERROR, "Unknown MTC0 write: %d", rfs); 735 stop=1; 736 } 737 ADD_TO_PC(1); 738} 739 740/* COP1 */ 741DECLARE_JUMP(BC1F, PCADDR + (iimmediate+1)*4, (FCR31 & FCR31_CMP_BIT)==0, ®[0], 0, 1) 742DECLARE_JUMP(BC1T, PCADDR + (iimmediate+1)*4, (FCR31 & FCR31_CMP_BIT)!=0, ®[0], 0, 1) 743DECLARE_JUMP(BC1FL, PCADDR + (iimmediate+1)*4, (FCR31 & FCR31_CMP_BIT)==0, ®[0], 1, 1) 744DECLARE_JUMP(BC1TL, PCADDR + (iimmediate+1)*4, (FCR31 & FCR31_CMP_BIT)!=0, ®[0], 1, 1) 745 746DECLARE_INSTRUCTION(MFC1) 747{ 748 if (check_cop1_unusable()) return; 749 rrt = SE32(*((int32_t*) reg_cop1_simple[rfs])); 750 ADD_TO_PC(1); 751} 752 753DECLARE_INSTRUCTION(DMFC1) 754{ 755 if (check_cop1_unusable()) return; 756 rrt = *((int64_t*) reg_cop1_double[rfs]); 757 ADD_TO_PC(1); 758} 759 760DECLARE_INSTRUCTION(CFC1) 761{ 762 if (check_cop1_unusable()) return; 763 if (rfs==31) 764 { 765 rrt32 = SE32(FCR31); 766 } 767 if (rfs==0) 768 { 769 rrt32 = SE32(FCR0); 770 } 771 ADD_TO_PC(1); 772} 773 774DECLARE_INSTRUCTION(MTC1) 775{ 776 if (check_cop1_unusable()) return; 777 *((int32_t*) reg_cop1_simple[rfs]) = rrt32; 778 ADD_TO_PC(1); 779} 780 781DECLARE_INSTRUCTION(DMTC1) 782{ 783 if (check_cop1_unusable()) return; 784 *((int64_t*) reg_cop1_double[rfs]) = rrt; 785 ADD_TO_PC(1); 786} 787 788DECLARE_INSTRUCTION(CTC1) 789{ 790 if (check_cop1_unusable()) return; 791 if (rfs==31) 792 { 793 FCR31 = rrt32; 794 update_x86_rounding_mode(rrt32); 795 } 796 //if ((FCR31 >> 7) & 0x1F) printf("FPU Exception enabled : %x\n", 797 // (int)((FCR31 >> 7) & 0x1F)); 798 ADD_TO_PC(1); 799} 800 801// COP1_D 802DECLARE_INSTRUCTION(ADD_D) 803{ 804 if (check_cop1_unusable()) return; 805 add_d(reg_cop1_double[cffs], reg_cop1_double[cfft], reg_cop1_double[cffd]); 806 ADD_TO_PC(1); 807} 808 809DECLARE_INSTRUCTION(SUB_D) 810{ 811 if (check_cop1_unusable()) return; 812 sub_d(reg_cop1_double[cffs], reg_cop1_double[cfft], reg_cop1_double[cffd]); 813 ADD_TO_PC(1); 814} 815 816DECLARE_INSTRUCTION(MUL_D) 817{ 818 if (check_cop1_unusable()) return; 819 mul_d(reg_cop1_double[cffs], reg_cop1_double[cfft], reg_cop1_double[cffd]); 820 ADD_TO_PC(1); 821} 822 823DECLARE_INSTRUCTION(DIV_D) 824{ 825 if (check_cop1_unusable()) return; 826 if((FCR31 & UINT32_C(0x400)) && *reg_cop1_double[cfft] == 0) 827 { 828 //FCR31 |= 0x8020; 829 /*FCR31 |= 0x8000; 830 Cause = 15 << 2; 831 exception_general();*/ 832 DebugMessage(M64MSG_ERROR, "DIV_D by 0"); 833 //return; 834 } 835 div_d(reg_cop1_double[cffs], reg_cop1_double[cfft], reg_cop1_double[cffd]); 836 ADD_TO_PC(1); 837} 838 839DECLARE_INSTRUCTION(SQRT_D) 840{ 841 if (check_cop1_unusable()) return; 842 sqrt_d(reg_cop1_double[cffs], reg_cop1_double[cffd]); 843 ADD_TO_PC(1); 844} 845 846DECLARE_INSTRUCTION(ABS_D) 847{ 848 if (check_cop1_unusable()) return; 849 abs_d(reg_cop1_double[cffs], reg_cop1_double[cffd]); 850 ADD_TO_PC(1); 851} 852 853DECLARE_INSTRUCTION(MOV_D) 854{ 855 if (check_cop1_unusable()) return; 856 mov_d(reg_cop1_double[cffs], reg_cop1_double[cffd]); 857 ADD_TO_PC(1); 858} 859 860DECLARE_INSTRUCTION(NEG_D) 861{ 862 if (check_cop1_unusable()) return; 863 neg_d(reg_cop1_double[cffs], reg_cop1_double[cffd]); 864 ADD_TO_PC(1); 865} 866 867DECLARE_INSTRUCTION(ROUND_L_D) 868{ 869 if (check_cop1_unusable()) return; 870 round_l_d(reg_cop1_double[cffs], (int64_t*) reg_cop1_double[cffd]); 871 ADD_TO_PC(1); 872} 873 874DECLARE_INSTRUCTION(TRUNC_L_D) 875{ 876 if (check_cop1_unusable()) return; 877 trunc_l_d(reg_cop1_double[cffs], (int64_t*) reg_cop1_double[cffd]); 878 ADD_TO_PC(1); 879} 880 881DECLARE_INSTRUCTION(CEIL_L_D) 882{ 883 if (check_cop1_unusable()) return; 884 ceil_l_d(reg_cop1_double[cffs], (int64_t*) reg_cop1_double[cffd]); 885 ADD_TO_PC(1); 886} 887 888DECLARE_INSTRUCTION(FLOOR_L_D) 889{ 890 if (check_cop1_unusable()) return; 891 floor_l_d(reg_cop1_double[cffs], (int64_t*) reg_cop1_double[cffd]); 892 ADD_TO_PC(1); 893} 894 895DECLARE_INSTRUCTION(ROUND_W_D) 896{ 897 if (check_cop1_unusable()) return; 898 round_w_d(reg_cop1_double[cffs], (int32_t*) reg_cop1_simple[cffd]); 899 ADD_TO_PC(1); 900} 901 902DECLARE_INSTRUCTION(TRUNC_W_D) 903{ 904 if (check_cop1_unusable()) return; 905 trunc_w_d(reg_cop1_double[cffs], (int32_t*) reg_cop1_simple[cffd]); 906 ADD_TO_PC(1); 907} 908 909DECLARE_INSTRUCTION(CEIL_W_D) 910{ 911 if (check_cop1_unusable()) return; 912 ceil_w_d(reg_cop1_double[cffs], (int32_t*) reg_cop1_simple[cffd]); 913 ADD_TO_PC(1); 914} 915 916DECLARE_INSTRUCTION(FLOOR_W_D) 917{ 918 if (check_cop1_unusable()) return; 919 floor_w_d(reg_cop1_double[cffs], (int32_t*) reg_cop1_simple[cffd]); 920 ADD_TO_PC(1); 921} 922 923DECLARE_INSTRUCTION(CVT_S_D) 924{ 925 if (check_cop1_unusable()) return; 926 cvt_s_d(reg_cop1_double[cffs], reg_cop1_simple[cffd]); 927 ADD_TO_PC(1); 928} 929 930DECLARE_INSTRUCTION(CVT_W_D) 931{ 932 if (check_cop1_unusable()) return; 933 cvt_w_d(reg_cop1_double[cffs], (int32_t*) reg_cop1_simple[cffd]); 934 ADD_TO_PC(1); 935} 936 937DECLARE_INSTRUCTION(CVT_L_D) 938{ 939 if (check_cop1_unusable()) return; 940 cvt_l_d(reg_cop1_double[cffs], (int64_t*) reg_cop1_double[cffd]); 941 ADD_TO_PC(1); 942} 943 944DECLARE_INSTRUCTION(C_F_D) 945{ 946 if (check_cop1_unusable()) return; 947 c_f_d(); 948 ADD_TO_PC(1); 949} 950 951DECLARE_INSTRUCTION(C_UN_D) 952{ 953 if (check_cop1_unusable()) return; 954 c_un_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); 955 ADD_TO_PC(1); 956} 957 958DECLARE_INSTRUCTION(C_EQ_D) 959{ 960 if (check_cop1_unusable()) return; 961 c_eq_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); 962 ADD_TO_PC(1); 963} 964 965DECLARE_INSTRUCTION(C_UEQ_D) 966{ 967 if (check_cop1_unusable()) return; 968 c_ueq_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); 969 ADD_TO_PC(1); 970} 971 972DECLARE_INSTRUCTION(C_OLT_D) 973{ 974 if (check_cop1_unusable()) return; 975 c_olt_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); 976 ADD_TO_PC(1); 977} 978 979DECLARE_INSTRUCTION(C_ULT_D) 980{ 981 if (check_cop1_unusable()) return; 982 c_ult_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); 983 ADD_TO_PC(1); 984} 985 986DECLARE_INSTRUCTION(C_OLE_D) 987{ 988 if (check_cop1_unusable()) return; 989 c_ole_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); 990 ADD_TO_PC(1); 991} 992 993DECLARE_INSTRUCTION(C_ULE_D) 994{ 995 if (check_cop1_unusable()) return; 996 c_ule_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); 997 ADD_TO_PC(1); 998} 999 1000DECLARE_INSTRUCTION(C_SF_D) 1001{ 1002 if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft])) 1003 { 1004 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); 1005 stop=1; 1006 } 1007 c_sf_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); 1008 ADD_TO_PC(1); 1009} 1010 1011DECLARE_INSTRUCTION(C_NGLE_D) 1012{ 1013 if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft])) 1014 { 1015 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); 1016 stop=1; 1017 } 1018 c_ngle_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); 1019 ADD_TO_PC(1); 1020} 1021 1022DECLARE_INSTRUCTION(C_SEQ_D) 1023{ 1024 if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft])) 1025 { 1026 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); 1027 stop=1; 1028 } 1029 c_seq_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); 1030 ADD_TO_PC(1); 1031} 1032 1033DECLARE_INSTRUCTION(C_NGL_D) 1034{ 1035 if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft])) 1036 { 1037 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); 1038 stop=1; 1039 } 1040 c_ngl_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); 1041 ADD_TO_PC(1); 1042} 1043 1044DECLARE_INSTRUCTION(C_LT_D) 1045{ 1046 if (check_cop1_unusable()) return; 1047 if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft])) 1048 { 1049 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); 1050 stop=1; 1051 } 1052 c_lt_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); 1053 ADD_TO_PC(1); 1054} 1055 1056DECLARE_INSTRUCTION(C_NGE_D) 1057{ 1058 if (check_cop1_unusable()) return; 1059 if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft])) 1060 { 1061 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); 1062 stop=1; 1063 } 1064 c_nge_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); 1065 ADD_TO_PC(1); 1066} 1067 1068DECLARE_INSTRUCTION(C_LE_D) 1069{ 1070 if (check_cop1_unusable()) return; 1071 if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft])) 1072 { 1073 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); 1074 stop=1; 1075 } 1076 c_le_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); 1077 ADD_TO_PC(1); 1078} 1079 1080DECLARE_INSTRUCTION(C_NGT_D) 1081{ 1082 if (check_cop1_unusable()) return; 1083 if (isnan(*reg_cop1_double[cffs]) || isnan(*reg_cop1_double[cfft])) 1084 { 1085 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); 1086 stop=1; 1087 } 1088 c_ngt_d(reg_cop1_double[cffs], reg_cop1_double[cfft]); 1089 ADD_TO_PC(1); 1090} 1091 1092// COP1_L 1093DECLARE_INSTRUCTION(CVT_S_L) 1094{ 1095 if (check_cop1_unusable()) return; 1096 cvt_s_l((int64_t*) reg_cop1_double[cffs], reg_cop1_simple[cffd]); 1097 ADD_TO_PC(1); 1098} 1099 1100DECLARE_INSTRUCTION(CVT_D_L) 1101{ 1102 if (check_cop1_unusable()) return; 1103 cvt_d_l((int64_t*) reg_cop1_double[cffs], reg_cop1_double[cffd]); 1104 ADD_TO_PC(1); 1105} 1106 1107// COP1_S 1108DECLARE_INSTRUCTION(ADD_S) 1109{ 1110 if (check_cop1_unusable()) return; 1111 add_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft], reg_cop1_simple[cffd]); 1112 ADD_TO_PC(1); 1113} 1114 1115DECLARE_INSTRUCTION(SUB_S) 1116{ 1117 if (check_cop1_unusable()) return; 1118 sub_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft], reg_cop1_simple[cffd]); 1119 ADD_TO_PC(1); 1120} 1121 1122DECLARE_INSTRUCTION(MUL_S) 1123{ 1124 if (check_cop1_unusable()) return; 1125 mul_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft], reg_cop1_simple[cffd]); 1126 ADD_TO_PC(1); 1127} 1128 1129DECLARE_INSTRUCTION(DIV_S) 1130{ 1131 if (check_cop1_unusable()) return; 1132 if((FCR31 & UINT32_C(0x400)) && *reg_cop1_simple[cfft] == 0) 1133 { 1134 DebugMessage(M64MSG_ERROR, "DIV_S by 0"); 1135 } 1136 div_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft], reg_cop1_simple[cffd]); 1137 ADD_TO_PC(1); 1138} 1139 1140DECLARE_INSTRUCTION(SQRT_S) 1141{ 1142 if (check_cop1_unusable()) return; 1143 sqrt_s(reg_cop1_simple[cffs], reg_cop1_simple[cffd]); 1144 ADD_TO_PC(1); 1145} 1146 1147DECLARE_INSTRUCTION(ABS_S) 1148{ 1149 if (check_cop1_unusable()) return; 1150 abs_s(reg_cop1_simple[cffs], reg_cop1_simple[cffd]); 1151 ADD_TO_PC(1); 1152} 1153 1154DECLARE_INSTRUCTION(MOV_S) 1155{ 1156 if (check_cop1_unusable()) return; 1157 mov_s(reg_cop1_simple[cffs], reg_cop1_simple[cffd]); 1158 ADD_TO_PC(1); 1159} 1160 1161DECLARE_INSTRUCTION(NEG_S) 1162{ 1163 if (check_cop1_unusable()) return; 1164 neg_s(reg_cop1_simple[cffs], reg_cop1_simple[cffd]); 1165 ADD_TO_PC(1); 1166} 1167 1168DECLARE_INSTRUCTION(ROUND_L_S) 1169{ 1170 if (check_cop1_unusable()) return; 1171 round_l_s(reg_cop1_simple[cffs], (int64_t*) reg_cop1_double[cffd]); 1172 ADD_TO_PC(1); 1173} 1174 1175DECLARE_INSTRUCTION(TRUNC_L_S) 1176{ 1177 if (check_cop1_unusable()) return; 1178 trunc_l_s(reg_cop1_simple[cffs], (int64_t*) reg_cop1_double[cffd]); 1179 ADD_TO_PC(1); 1180} 1181 1182DECLARE_INSTRUCTION(CEIL_L_S) 1183{ 1184 if (check_cop1_unusable()) return; 1185 ceil_l_s(reg_cop1_simple[cffs], (int64_t*) reg_cop1_double[cffd]); 1186 ADD_TO_PC(1); 1187} 1188 1189DECLARE_INSTRUCTION(FLOOR_L_S) 1190{ 1191 if (check_cop1_unusable()) return; 1192 floor_l_s(reg_cop1_simple[cffs], (int64_t*) reg_cop1_double[cffd]); 1193 ADD_TO_PC(1); 1194} 1195 1196DECLARE_INSTRUCTION(ROUND_W_S) 1197{ 1198 if (check_cop1_unusable()) return; 1199 round_w_s(reg_cop1_simple[cffs], (int32_t*) reg_cop1_simple[cffd]); 1200 ADD_TO_PC(1); 1201} 1202 1203DECLARE_INSTRUCTION(TRUNC_W_S) 1204{ 1205 if (check_cop1_unusable()) return; 1206 trunc_w_s(reg_cop1_simple[cffs], (int32_t*) reg_cop1_simple[cffd]); 1207 ADD_TO_PC(1); 1208} 1209 1210DECLARE_INSTRUCTION(CEIL_W_S) 1211{ 1212 if (check_cop1_unusable()) return; 1213 ceil_w_s(reg_cop1_simple[cffs], (int32_t*) reg_cop1_simple[cffd]); 1214 ADD_TO_PC(1); 1215} 1216 1217DECLARE_INSTRUCTION(FLOOR_W_S) 1218{ 1219 if (check_cop1_unusable()) return; 1220 floor_w_s(reg_cop1_simple[cffs], (int32_t*) reg_cop1_simple[cffd]); 1221 ADD_TO_PC(1); 1222} 1223 1224DECLARE_INSTRUCTION(CVT_D_S) 1225{ 1226 if (check_cop1_unusable()) return; 1227 cvt_d_s(reg_cop1_simple[cffs], reg_cop1_double[cffd]); 1228 ADD_TO_PC(1); 1229} 1230 1231DECLARE_INSTRUCTION(CVT_W_S) 1232{ 1233 if (check_cop1_unusable()) return; 1234 cvt_w_s(reg_cop1_simple[cffs], (int32_t*) reg_cop1_simple[cffd]); 1235 ADD_TO_PC(1); 1236} 1237 1238DECLARE_INSTRUCTION(CVT_L_S) 1239{ 1240 if (check_cop1_unusable()) return; 1241 cvt_l_s(reg_cop1_simple[cffs], (int64_t*) reg_cop1_double[cffd]); 1242 ADD_TO_PC(1); 1243} 1244 1245DECLARE_INSTRUCTION(C_F_S) 1246{ 1247 if (check_cop1_unusable()) return; 1248 c_f_s(); 1249 ADD_TO_PC(1); 1250} 1251 1252DECLARE_INSTRUCTION(C_UN_S) 1253{ 1254 if (check_cop1_unusable()) return; 1255 c_un_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); 1256 ADD_TO_PC(1); 1257} 1258 1259DECLARE_INSTRUCTION(C_EQ_S) 1260{ 1261 if (check_cop1_unusable()) return; 1262 c_eq_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); 1263 ADD_TO_PC(1); 1264} 1265 1266DECLARE_INSTRUCTION(C_UEQ_S) 1267{ 1268 if (check_cop1_unusable()) return; 1269 c_ueq_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); 1270 ADD_TO_PC(1); 1271} 1272 1273DECLARE_INSTRUCTION(C_OLT_S) 1274{ 1275 if (check_cop1_unusable()) return; 1276 c_olt_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); 1277 ADD_TO_PC(1); 1278} 1279 1280DECLARE_INSTRUCTION(C_ULT_S) 1281{ 1282 if (check_cop1_unusable()) return; 1283 c_ult_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); 1284 ADD_TO_PC(1); 1285} 1286 1287DECLARE_INSTRUCTION(C_OLE_S) 1288{ 1289 if (check_cop1_unusable()) return; 1290 c_ole_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); 1291 ADD_TO_PC(1); 1292} 1293 1294DECLARE_INSTRUCTION(C_ULE_S) 1295{ 1296 if (check_cop1_unusable()) return; 1297 c_ule_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); 1298 ADD_TO_PC(1); 1299} 1300 1301DECLARE_INSTRUCTION(C_SF_S) 1302{ 1303 if (check_cop1_unusable()) return; 1304 if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft])) 1305 { 1306 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); 1307 stop=1; 1308 } 1309 c_sf_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); 1310 ADD_TO_PC(1); 1311} 1312 1313DECLARE_INSTRUCTION(C_NGLE_S) 1314{ 1315 if (check_cop1_unusable()) return; 1316 if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft])) 1317 { 1318 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); 1319 stop=1; 1320 } 1321 c_ngle_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); 1322 ADD_TO_PC(1); 1323} 1324 1325DECLARE_INSTRUCTION(C_SEQ_S) 1326{ 1327 if (check_cop1_unusable()) return; 1328 if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft])) 1329 { 1330 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); 1331 stop=1; 1332 } 1333 c_seq_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); 1334 ADD_TO_PC(1); 1335} 1336 1337DECLARE_INSTRUCTION(C_NGL_S) 1338{ 1339 if (check_cop1_unusable()) return; 1340 if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft])) 1341 { 1342 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); 1343 stop=1; 1344 } 1345 c_ngl_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); 1346 ADD_TO_PC(1); 1347} 1348 1349DECLARE_INSTRUCTION(C_LT_S) 1350{ 1351 if (check_cop1_unusable()) return; 1352 if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft])) 1353 { 1354 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); 1355 stop=1; 1356 } 1357 c_lt_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); 1358 ADD_TO_PC(1); 1359} 1360 1361DECLARE_INSTRUCTION(C_NGE_S) 1362{ 1363 if (check_cop1_unusable()) return; 1364 if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft])) 1365 { 1366 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); 1367 stop=1; 1368 } 1369 c_nge_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); 1370 ADD_TO_PC(1); 1371} 1372 1373DECLARE_INSTRUCTION(C_LE_S) 1374{ 1375 if (check_cop1_unusable()) return; 1376 if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft])) 1377 { 1378 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); 1379 stop=1; 1380 } 1381 c_le_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); 1382 ADD_TO_PC(1); 1383} 1384 1385DECLARE_INSTRUCTION(C_NGT_S) 1386{ 1387 if (check_cop1_unusable()) return; 1388 if (isnan(*reg_cop1_simple[cffs]) || isnan(*reg_cop1_simple[cfft])) 1389 { 1390 DebugMessage(M64MSG_ERROR, "Invalid operation exception in C opcode"); 1391 stop=1; 1392 } 1393 c_ngt_s(reg_cop1_simple[cffs], reg_cop1_simple[cfft]); 1394 ADD_TO_PC(1); 1395} 1396 1397// COP1_W 1398DECLARE_INSTRUCTION(CVT_S_W) 1399{ 1400 if (check_cop1_unusable()) return; 1401 cvt_s_w((int32_t*) reg_cop1_simple[cffs], reg_cop1_simple[cffd]); 1402 ADD_TO_PC(1); 1403} 1404 1405DECLARE_INSTRUCTION(CVT_D_W) 1406{ 1407 if (check_cop1_unusable()) return; 1408 cvt_d_w((int32_t*) reg_cop1_simple[cffs], reg_cop1_double[cffd]); 1409 ADD_TO_PC(1); 1410} 1411 1412/* regimm */ 1413DECLARE_JUMP(BLTZ, PCADDR + (iimmediate+1)*4, irs < 0, ®[0], 0, 0) 1414DECLARE_JUMP(BGEZ, PCADDR + (iimmediate+1)*4, irs >= 0, ®[0], 0, 0) 1415DECLARE_JUMP(BLTZL, PCADDR + (iimmediate+1)*4, irs < 0, ®[0], 1, 0) 1416DECLARE_JUMP(BGEZL, PCADDR + (iimmediate+1)*4, irs >= 0, ®[0], 1, 0) 1417DECLARE_JUMP(BLTZAL, PCADDR + (iimmediate+1)*4, irs < 0, ®[31], 0, 0) 1418DECLARE_JUMP(BGEZAL, PCADDR + (iimmediate+1)*4, irs >= 0, ®[31], 0, 0) 1419DECLARE_JUMP(BLTZALL, PCADDR + (iimmediate+1)*4, irs < 0, ®[31], 1, 0) 1420DECLARE_JUMP(BGEZALL, PCADDR + (iimmediate+1)*4, irs >= 0, ®[31], 1, 0) 1421 1422/* special */ 1423DECLARE_INSTRUCTION(NOP) 1424{ 1425 ADD_TO_PC(1); 1426} 1427 1428DECLARE_INSTRUCTION(SLL) 1429{ 1430 rrd = SE32((uint32_t) rrt32 << rsa); 1431 ADD_TO_PC(1); 1432} 1433 1434DECLARE_INSTRUCTION(SRL) 1435{ 1436 rrd = SE32((uint32_t) rrt32 >> rsa); 1437 ADD_TO_PC(1); 1438} 1439 1440DECLARE_INSTRUCTION(SRA) 1441{ 1442 rrd = SE32((int32_t) rrt32 >> rsa); 1443 ADD_TO_PC(1); 1444} 1445 1446DECLARE_INSTRUCTION(SLLV) 1447{ 1448 rrd = SE32((uint32_t) rrt32 << (rrs32 & 0x1F)); 1449 ADD_TO_PC(1); 1450} 1451 1452DECLARE_INSTRUCTION(SRLV) 1453{ 1454 rrd = SE32((uint32_t) rrt32 >> (rrs32 & 0x1F)); 1455 ADD_TO_PC(1); 1456} 1457 1458DECLARE_INSTRUCTION(SRAV) 1459{ 1460 rrd = SE32((int32_t) rrt32 >> (rrs32 & 0x1F)); 1461 ADD_TO_PC(1); 1462} 1463 1464DECLARE_JUMP(JR, irs32, 1, ®[0], 0, 0) 1465DECLARE_JUMP(JALR, irs32, 1, &rrd, 0, 0) 1466 1467DECLARE_INSTRUCTION(SYSCALL) 1468{ 1469 g_cp0_regs[CP0_CAUSE_REG] = CP0_CAUSE_EXCCODE_SYS; 1470 exception_general(); 1471} 1472 1473DECLARE_INSTRUCTION(SYNC) 1474{ 1475 ADD_TO_PC(1); 1476} 1477 1478DECLARE_INSTRUCTION(MFHI) 1479{ 1480 rrd = hi; 1481 ADD_TO_PC(1); 1482} 1483 1484DECLARE_INSTRUCTION(MTHI) 1485{ 1486 hi = rrs; 1487 ADD_TO_PC(1); 1488} 1489 1490DECLARE_INSTRUCTION(MFLO) 1491{ 1492 rrd = lo; 1493 ADD_TO_PC(1); 1494} 1495 1496DECLARE_INSTRUCTION(MTLO) 1497{ 1498 lo = rrs; 1499 ADD_TO_PC(1); 1500} 1501 1502DECLARE_INSTRUCTION(DSLLV) 1503{ 1504 rrd = rrt << (rrs32 & 0x3F); 1505 ADD_TO_PC(1); 1506} 1507 1508DECLARE_INSTRUCTION(DSRLV) 1509{ 1510 rrd = (uint64_t) rrt >> (rrs32 & 0x3F); 1511 ADD_TO_PC(1); 1512} 1513 1514DECLARE_INSTRUCTION(DSRAV) 1515{ 1516 rrd = (int64_t) rrt >> (rrs32 & 0x3F); 1517 ADD_TO_PC(1); 1518} 1519 1520DECLARE_INSTRUCTION(MULT) 1521{ 1522 int64_t temp; 1523 temp = rrs * rrt; 1524 hi = temp >> 32; 1525 lo = SE32(temp); 1526 ADD_TO_PC(1); 1527} 1528 1529DECLARE_INSTRUCTION(MULTU) 1530{ 1531 uint64_t temp; 1532 temp = (uint32_t) rrs * (uint64_t) ((uint32_t) rrt); 1533 hi = (int64_t) temp >> 32; 1534 lo = SE32(temp); 1535 ADD_TO_PC(1); 1536} 1537 1538DECLARE_INSTRUCTION(DIV) 1539{ 1540 if (rrt32) 1541 { 1542 lo = SE32(rrs32 / rrt32); 1543 hi = SE32(rrs32 % rrt32); 1544 } 1545 else DebugMessage(M64MSG_ERROR, "DIV: divide by 0"); 1546 ADD_TO_PC(1); 1547} 1548 1549DECLARE_INSTRUCTION(DIVU) 1550{ 1551 if (rrt32) 1552 { 1553 lo = SE32((uint32_t) rrs32 / (uint32_t) rrt32); 1554 hi = SE32((uint32_t) rrs32 % (uint32_t) rrt32); 1555 } 1556 else DebugMessage(M64MSG_ERROR, "DIVU: divide by 0"); 1557 ADD_TO_PC(1); 1558} 1559 1560DECLARE_INSTRUCTION(DMULT) 1561{ 1562 uint64_t op1, op2, op3, op4; 1563 uint64_t result1, result2, result3, result4; 1564 uint64_t temp1, temp2, temp3, temp4; 1565 int sign = 0; 1566 1567 if (rrs < 0) 1568 { 1569 op2 = -rrs; 1570 sign = 1 - sign; 1571 } 1572 else op2 = rrs; 1573 if (rrt < 0) 1574 { 1575 op4 = -rrt; 1576 sign = 1 - sign; 1577 } 1578 else op4 = rrt; 1579 1580 op1 = op2 & UINT64_C(0xFFFFFFFF); 1581 op2 = (op2 >> 32) & UINT64_C(0xFFFFFFFF); 1582 op3 = op4 & UINT64_C(0xFFFFFFFF); 1583 op4 = (op4 >> 32) & UINT64_C(0xFFFFFFFF); 1584 1585 temp1 = op1 * op3; 1586 temp2 = (temp1 >> 32) + op1 * op4; 1587 temp3 = op2 * op3; 1588 temp4 = (temp3 >> 32) + op2 * op4; 1589 1590 result1 = temp1 & UINT64_C(0xFFFFFFFF); 1591 result2 = temp2 + (temp3 & UINT64_C(0xFFFFFFFF)); 1592 result3 = (result2 >> 32) + temp4; 1593 result4 = (result3 >> 32); 1594 1595 lo = result1 | (result2 << 32); 1596 hi = (result3 & UINT64_C(0xFFFFFFFF)) | (result4 << 32); 1597 if (sign) 1598 { 1599 hi = ~hi; 1600 if (!lo) hi++; 1601 else lo = ~lo + 1; 1602 } 1603 ADD_TO_PC(1); 1604} 1605 1606DECLARE_INSTRUCTION(DMULTU) 1607{ 1608 uint64_t op1, op2, op3, op4; 1609 uint64_t result1, result2, result3, result4; 1610 uint64_t temp1, temp2, temp3, temp4; 1611 1612 op1 = rrs & UINT64_C(0xFFFFFFFF); 1613 op2 = (rrs >> 32) & UINT64_C(0xFFFFFFFF); 1614 op3 = rrt & UINT64_C(0xFFFFFFFF); 1615 op4 = (rrt >> 32) & UINT64_C(0xFFFFFFFF); 1616 1617 temp1 = op1 * op3; 1618 temp2 = (temp1 >> 32) + op1 * op4; 1619 temp3 = op2 * op3; 1620 temp4 = (temp3 >> 32) + op2 * op4; 1621 1622 result1 = temp1 & UINT64_C(0xFFFFFFFF); 1623 result2 = temp2 + (temp3 & UINT64_C(0xFFFFFFFF)); 1624 result3 = (result2 >> 32) + temp4; 1625 result4 = (result3 >> 32); 1626 1627 lo = result1 | (result2 << 32); 1628 hi = (result3 & UINT64_C(0xFFFFFFFF)) | (result4 << 32); 1629 1630 ADD_TO_PC(1); 1631} 1632 1633DECLARE_INSTRUCTION(DDIV) 1634{ 1635 if (rrt) 1636 { 1637 lo = rrs / rrt; 1638 hi = rrs % rrt; 1639 } 1640 else DebugMessage(M64MSG_ERROR, "DDIV: divide by 0"); 1641 ADD_TO_PC(1); 1642} 1643 1644DECLARE_INSTRUCTION(DDIVU) 1645{ 1646 if (rrt) 1647 { 1648 lo = (uint64_t) rrs / (uint64_t) rrt; 1649 hi = (uint64_t) rrs % (uint64_t) rrt; 1650 } 1651 else DebugMessage(M64MSG_ERROR, "DDIVU: divide by 0"); 1652 ADD_TO_PC(1); 1653} 1654 1655DECLARE_INSTRUCTION(ADD) 1656{ 1657 rrd = SE32(rrs32 + rrt32); 1658 ADD_TO_PC(1); 1659} 1660 1661DECLARE_INSTRUCTION(ADDU) 1662{ 1663 rrd = SE32(rrs32 + rrt32); 1664 ADD_TO_PC(1); 1665} 1666 1667DECLARE_INSTRUCTION(SUB) 1668{ 1669 rrd = SE32(rrs32 - rrt32); 1670 ADD_TO_PC(1); 1671} 1672 1673DECLARE_INSTRUCTION(SUBU) 1674{ 1675 rrd = SE32(rrs32 - rrt32); 1676 ADD_TO_PC(1); 1677} 1678 1679DECLARE_INSTRUCTION(AND) 1680{ 1681 rrd = rrs & rrt; 1682 ADD_TO_PC(1); 1683} 1684 1685DECLARE_INSTRUCTION(OR) 1686{ 1687 rrd = rrs | rrt; 1688 ADD_TO_PC(1); 1689} 1690 1691DECLARE_INSTRUCTION(XOR) 1692{ 1693 rrd = rrs ^ rrt; 1694 ADD_TO_PC(1); 1695} 1696 1697DECLARE_INSTRUCTION(NOR) 1698{ 1699 rrd = ~(rrs | rrt); 1700 ADD_TO_PC(1); 1701} 1702 1703DECLARE_INSTRUCTION(SLT) 1704{ 1705 if (rrs < rrt) rrd = 1; 1706 else rrd = 0; 1707 ADD_TO_PC(1); 1708} 1709 1710DECLARE_INSTRUCTION(SLTU) 1711{ 1712 if ((uint64_t) rrs < (uint64_t) rrt) 1713 rrd = 1; 1714 else rrd = 0; 1715 ADD_TO_PC(1); 1716} 1717 1718DECLARE_INSTRUCTION(DADD) 1719{ 1720 rrd = (uint64_t) rrs + (uint64_t) rrt; 1721 ADD_TO_PC(1); 1722} 1723 1724DECLARE_INSTRUCTION(DADDU) 1725{ 1726 rrd = (uint64_t) rrs + (uint64_t) rrt; 1727 ADD_TO_PC(1); 1728} 1729 1730DECLARE_INSTRUCTION(DSUB) 1731{ 1732 rrd = rrs - rrt; 1733 ADD_TO_PC(1); 1734} 1735 1736DECLARE_INSTRUCTION(DSUBU) 1737{ 1738 rrd = rrs - rrt; 1739 ADD_TO_PC(1); 1740} 1741 1742DECLARE_INSTRUCTION(TEQ) 1743{ 1744 if (rrs == rrt) 1745 { 1746 DebugMessage(M64MSG_ERROR, "trap exception in TEQ"); 1747 stop=1; 1748 } 1749 ADD_TO_PC(1); 1750} 1751 1752DECLARE_INSTRUCTION(DSLL) 1753{ 1754 rrd = rrt << rsa; 1755 ADD_TO_PC(1); 1756} 1757 1758DECLARE_INSTRUCTION(DSRL) 1759{ 1760 rrd = (uint64_t) rrt >> rsa; 1761 ADD_TO_PC(1); 1762} 1763 1764DECLARE_INSTRUCTION(DSRA) 1765{ 1766 rrd = rrt >> rsa; 1767 ADD_TO_PC(1); 1768} 1769 1770DECLARE_INSTRUCTION(DSLL32) 1771{ 1772 rrd = rrt << (32 + rsa); 1773 ADD_TO_PC(1); 1774} 1775 1776DECLARE_INSTRUCTION(DSRL32) 1777{ 1778 rrd = (uint64_t) rrt >> (32 + rsa); 1779 ADD_TO_PC(1); 1780} 1781 1782DECLARE_INSTRUCTION(DSRA32) 1783{ 1784 rrd = (int64_t) rrt >> (32 + rsa); 1785 ADD_TO_PC(1); 1786} 1787 1788/* TLB */ 1789#include <encodings/crc32.h> 1790 1791DECLARE_INSTRUCTION(TLBR) 1792{ 1793 int index; 1794 index = g_cp0_regs[CP0_INDEX_REG] & UINT32_C(0x1F); 1795 g_cp0_regs[CP0_PAGEMASK_REG] = tlb_e[index].mask << 13; 1796 g_cp0_regs[CP0_ENTRYHI_REG] = ((tlb_e[index].vpn2 << 13) | tlb_e[index].asid); 1797 g_cp0_regs[CP0_ENTRYLO0_REG] = (tlb_e[index].pfn_even << 6) | (tlb_e[index].c_even << 3) 1798 | (tlb_e[index].d_even << 2) | (tlb_e[index].v_even << 1) 1799 | tlb_e[index].g; 1800 g_cp0_regs[CP0_ENTRYLO1_REG] = (tlb_e[index].pfn_odd << 6) | (tlb_e[index].c_odd << 3) 1801 | (tlb_e[index].d_odd << 2) | (tlb_e[index].v_odd << 1) 1802 | tlb_e[index].g; 1803 ADD_TO_PC(1); 1804} 1805 1806static void TLBWrite(unsigned int idx) 1807{ 1808 struct r4300_core* r4300 = &g_dev.r4300; 1809 uint32_t pc_addr = *r4300_pc(); 1810 1811 if (pc_addr >= tlb_e[idx].start_even && pc_addr < tlb_e[idx].end_even && tlb_e[idx].v_even) 1812 return; 1813 if (pc_addr >= tlb_e[idx].start_odd && pc_addr < tlb_e[idx].end_odd && tlb_e[idx].v_odd) 1814 return; 1815 1816 if (r4300emu != CORE_PURE_INTERPRETER) 1817 { 1818 unsigned int i; 1819 if (tlb_e[idx].v_even) 1820 { 1821 for (i=tlb_e[idx].start_even>>12; i<=tlb_e[idx].end_even>>12; i++) 1822 { 1823 if(!invalid_code[i] &&(invalid_code[tlb_LUT_r[i]>>12] || 1824 invalid_code[(tlb_LUT_r[i]>>12)+0x20000])) 1825 invalid_code[i] = 1; 1826 if (!invalid_code[i]) 1827 { 1828 /*int j; 1829 md5_state_t state; 1830 md5_byte_t digest[16]; 1831 md5_init(&state); 1832 md5_append(&state, 1833 (const md5_byte_t*)&g_dev.ri.rdram.dram[(tlb_LUT_r[i]&0x7FF000)/4], 1834 0x1000); 1835 md5_finish(&state, digest); 1836 for (j=0; j<16; j++) blocks[i]->md5[j] = digest[j];*/ 1837 1838 blocks[i]->adler32 = encoding_crc32(0, (void*)&g_dev.ri.rdram.dram[(tlb_LUT_r[i]&0x7FF000)/4], 0x1000); 1839 1840 invalid_code[i] = 1; 1841 } 1842 else if (blocks[i]) 1843 { 1844 /*int j; 1845 for (j=0; j<16; j++) blocks[i]->md5[j] = 0;*/ 1846 blocks[i]->adler32 = 0; 1847 } 1848 } 1849 } 1850 if (tlb_e[idx].v_odd) 1851 { 1852 for (i=tlb_e[idx].start_odd>>12; i<=tlb_e[idx].end_odd>>12; i++) 1853 { 1854 if(!invalid_code[i] &&(invalid_code[tlb_LUT_r[i]>>12] || 1855 invalid_code[(tlb_LUT_r[i]>>12)+0x20000])) 1856 invalid_code[i] = 1; 1857 if (!invalid_code[i]) 1858 { 1859 /*int j; 1860 md5_state_t state; 1861 md5_byte_t digest[16]; 1862 md5_init(&state); 1863 md5_append(&state, 1864 (const md5_byte_t*)&g_dev.ri.rdram.dram[(tlb_LUT_r[i]&0x7FF000)/4], 1865 0x1000); 1866 md5_finish(&state, digest); 1867 for (j=0; j<16; j++) blocks[i]->md5[j] = digest[j];*/ 1868 1869 blocks[i]->adler32 = encoding_crc32(0, (void*)&g_dev.ri.rdram.dram[(tlb_LUT_r[i]&0x7FF000)/4], 0x1000); 1870 1871 invalid_code[i] = 1; 1872 } 1873 else if (blocks[i]) 1874 { 1875 /*int j; 1876 for (j=0; j<16; j++) blocks[i]->md5[j] = 0;*/ 1877 blocks[i]->adler32 = 0; 1878 } 1879 } 1880 } 1881 } 1882 1883 tlb_unmap(&tlb_e[idx]); 1884 1885 tlb_e[idx].g = (g_cp0_regs[CP0_ENTRYLO0_REG] & g_cp0_regs[CP0_ENTRYLO1_REG] & 1); 1886 tlb_e[idx].pfn_even = (g_cp0_regs[CP0_ENTRYLO0_REG] & UINT32_C(0x3FFFFFC0)) >> 6; 1887 tlb_e[idx].pfn_odd = (g_cp0_regs[CP0_ENTRYLO1_REG] & UINT32_C(0x3FFFFFC0)) >> 6; 1888 tlb_e[idx].c_even = (g_cp0_regs[CP0_ENTRYLO0_REG] & UINT32_C(0x38)) >> 3; 1889 tlb_e[idx].c_odd = (g_cp0_regs[CP0_ENTRYLO1_REG] & UINT32_C(0x38)) >> 3; 1890 tlb_e[idx].d_even = (g_cp0_regs[CP0_ENTRYLO0_REG] & UINT32_C(0x4)) >> 2; 1891 tlb_e[idx].d_odd = (g_cp0_regs[CP0_ENTRYLO1_REG] & UINT32_C(0x4)) >> 2; 1892 tlb_e[idx].v_even = (g_cp0_regs[CP0_ENTRYLO0_REG] & UINT32_C(0x2)) >> 1; 1893 tlb_e[idx].v_odd = (g_cp0_regs[CP0_ENTRYLO1_REG] & UINT32_C(0x2)) >> 1; 1894 tlb_e[idx].asid = (g_cp0_regs[CP0_ENTRYHI_REG] & UINT32_C(0xFF)); 1895 tlb_e[idx].vpn2 = (g_cp0_regs[CP0_ENTRYHI_REG] & UINT32_C(0xFFFFE000)) >> 13; 1896 //tlb_e[idx].r = (g_cp0_regs[CP0_ENTRYHI_REG] & 0xC000000000000000LL) >> 62; 1897 tlb_e[idx].mask = (g_cp0_regs[CP0_PAGEMASK_REG] & UINT32_C(0x1FFE000)) >> 13; 1898 1899 tlb_e[idx].start_even = tlb_e[idx].vpn2 << 13; 1900 tlb_e[idx].end_even = tlb_e[idx].start_even+ 1901 (tlb_e[idx].mask << 12) + UINT32_C(0xFFF); 1902 tlb_e[idx].phys_even = tlb_e[idx].pfn_even << 12; 1903 1904 1905 tlb_e[idx].start_odd = tlb_e[idx].end_even+1; 1906 tlb_e[idx].end_odd = tlb_e[idx].start_odd+ 1907 (tlb_e[idx].mask << 12) + UINT32_C(0xFFF); 1908 tlb_e[idx].phys_odd = tlb_e[idx].pfn_odd << 12; 1909 1910 tlb_map(&tlb_e[idx]); 1911 1912 if (r4300emu != CORE_PURE_INTERPRETER) 1913 { 1914 unsigned int i; 1915 if (tlb_e[idx].v_even) 1916 { 1917 for (i=tlb_e[idx].start_even>>12; i<=tlb_e[idx].end_even>>12; i++) 1918 { 1919 /*if (blocks[i] && (blocks[i]->md5[0] || blocks[i]->md5[1] || 1920 blocks[i]->md5[2] || blocks[i]->md5[3])) 1921 { 1922 int j; 1923 int equal = 1; 1924 md5_state_t state; 1925 md5_byte_t digest[16]; 1926 md5_init(&state); 1927 md5_append(&state, 1928 (const md5_byte_t*)&g_dev.ri.rdram.dram[(tlb_LUT_r[i]&0x7FF000)/4], 1929 0x1000); 1930 md5_finish(&state, digest); 1931 for (j=0; j<16; j++) 1932 if (digest[j] != blocks[i]->md5[j]) 1933 equal = 0; 1934 if (equal) invalid_code[i] = 0; 1935 }*/ 1936 if(blocks[i] && blocks[i]->adler32) 1937 { 1938 if(blocks[i]->adler32 == encoding_crc32(0,(void*)&g_dev.ri.rdram.dram[(tlb_LUT_r[i]&0x7FF000)/4],0x1000)) 1939 invalid_code[i] = 0; 1940 } 1941 } 1942 } 1943 1944 if (tlb_e[idx].v_odd) 1945 { 1946 for (i=tlb_e[idx].start_odd>>12; i<=tlb_e[idx].end_odd>>12; i++) 1947 { 1948 /*if (blocks[i] && (blocks[i]->md5[0] || blocks[i]->md5[1] || 1949 blocks[i]->md5[2] || blocks[i]->md5[3])) 1950 { 1951 int j; 1952 int equal = 1; 1953 md5_state_t state; 1954 md5_byte_t digest[16]; 1955 md5_init(&state); 1956 md5_append(&state, 1957 (const md5_byte_t*)&g_dev.ri.rdram.dram[(tlb_LUT_r[i]&0x7FF000)/4], 1958 0x1000); 1959 md5_finish(&state, digest); 1960 for (j=0; j<16; j++) 1961 if (digest[j] != blocks[i]->md5[j]) 1962 equal = 0; 1963 if (equal) invalid_code[i] = 0; 1964 }*/ 1965 if(blocks[i] && blocks[i]->adler32) 1966 { 1967 if(blocks[i]->adler32 == encoding_crc32(0,(void*)&g_dev.ri.rdram.dram[(tlb_LUT_r[i]&0x7FF000)/4],0x1000)) 1968 invalid_code[i] = 0; 1969 } 1970 } 1971 } 1972 } 1973} 1974 1975DECLARE_INSTRUCTION(TLBWI) 1976{ 1977 TLBWrite(g_cp0_regs[CP0_INDEX_REG] & UINT32_C(0x3F)); 1978 ADD_TO_PC(1); 1979} 1980 1981DECLARE_INSTRUCTION(TLBWR) 1982{ 1983 cp0_update_count(); 1984 g_cp0_regs[CP0_RANDOM_REG] = (g_cp0_regs[CP0_COUNT_REG]/2 % (32 - g_cp0_regs[CP0_WIRED_REG])) 1985 + g_cp0_regs[CP0_WIRED_REG]; 1986 TLBWrite(g_cp0_regs[CP0_RANDOM_REG]); 1987 ADD_TO_PC(1); 1988} 1989 1990DECLARE_INSTRUCTION(TLBP) 1991{ 1992 int i; 1993 g_cp0_regs[CP0_INDEX_REG] |= UINT32_C(0x80000000); 1994 for (i=0; i<32; i++) 1995 { 1996 if (((tlb_e[i].vpn2 & (~tlb_e[i].mask)) == 1997 (((g_cp0_regs[CP0_ENTRYHI_REG] & UINT32_C(0xFFFFE000)) >> 13) & (~tlb_e[i].mask))) && 1998 ((tlb_e[i].g) || 1999 (tlb_e[i].asid == (g_cp0_regs[CP0_ENTRYHI_REG] & UINT32_C(0xFF))))) 2000 { 2001 g_cp0_regs[CP0_INDEX_REG] = i; 2002 break; 2003 } 2004 } 2005 ADD_TO_PC(1); 2006} 2007 2008DECLARE_INSTRUCTION(ERET) 2009{ 2010 cp0_update_count(); 2011 if (g_cp0_regs[CP0_STATUS_REG] & CP0_STATUS_ERL) 2012 { 2013 DebugMessage(M64MSG_ERROR, "error in ERET"); 2014 stop=1; 2015 } 2016 else 2017 { 2018 g_cp0_regs[CP0_STATUS_REG] &= ~CP0_STATUS_EXL; 2019 generic_jump_to(g_cp0_regs[CP0_EPC_REG]); 2020 } 2021 llbit = 0; 2022 check_interrupt(); 2023 last_addr = PCADDR; 2024 if (next_interrupt <= g_cp0_regs[CP0_COUNT_REG]) gen_interrupt(); 2025} 2026 2027