diff options
| author | 2014-12-29 19:47:41 -0800 | |
|---|---|---|
| committer | 2014-12-29 19:47:41 -0800 | |
| commit | 8ba9ac0f74abb0408a26207a76a0c1808bad8de0 (patch) | |
| tree | f1c7c3393fa726435b5b90bf335567c93e528ef1 /src/core/arm/interpreter/armsupp.cpp | |
| parent | Add comment regarding __WIN32__ in SkyEye code (diff) | |
| parent | Merge pull request #367 from bunnei/usat_ssat (diff) | |
| download | yuzu-8ba9ac0f74abb0408a26207a76a0c1808bad8de0.tar.gz yuzu-8ba9ac0f74abb0408a26207a76a0c1808bad8de0.tar.xz yuzu-8ba9ac0f74abb0408a26207a76a0c1808bad8de0.zip | |
Fix merge conflicts
Diffstat (limited to 'src/core/arm/interpreter/armsupp.cpp')
| -rw-r--r-- | src/core/arm/interpreter/armsupp.cpp | 166 |
1 files changed, 160 insertions, 6 deletions
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp index 2568b93ef..426b67831 100644 --- a/src/core/arm/interpreter/armsupp.cpp +++ b/src/core/arm/interpreter/armsupp.cpp | |||
| @@ -227,8 +227,9 @@ ARMul_CPSRAltered (ARMul_State * state) | |||
| 227 | //state->Cpsr &= ~CBIT; | 227 | //state->Cpsr &= ~CBIT; |
| 228 | ASSIGNV ((state->Cpsr & VBIT) != 0); | 228 | ASSIGNV ((state->Cpsr & VBIT) != 0); |
| 229 | //state->Cpsr &= ~VBIT; | 229 | //state->Cpsr &= ~VBIT; |
| 230 | ASSIGNS ((state->Cpsr & SBIT) != 0); | 230 | ASSIGNQ ((state->Cpsr & QBIT) != 0); |
| 231 | //state->Cpsr &= ~SBIT; | 231 | //state->Cpsr &= ~QBIT; |
| 232 | state->GEFlag = (state->Cpsr & 0x000F0000); | ||
| 232 | #ifdef MODET | 233 | #ifdef MODET |
| 233 | ASSIGNT ((state->Cpsr & TBIT) != 0); | 234 | ASSIGNT ((state->Cpsr & TBIT) != 0); |
| 234 | //state->Cpsr &= ~TBIT; | 235 | //state->Cpsr &= ~TBIT; |
| @@ -391,6 +392,15 @@ ARMul_NthReg (ARMword instr, unsigned number) | |||
| 391 | return (bit - 1); | 392 | return (bit - 1); |
| 392 | } | 393 | } |
| 393 | 394 | ||
| 395 | /* Unsigned sum of absolute difference */ | ||
| 396 | u8 ARMul_UnsignedAbsoluteDifference(u8 left, u8 right) | ||
| 397 | { | ||
| 398 | if (left > right) | ||
| 399 | return left - right; | ||
| 400 | |||
| 401 | return right - left; | ||
| 402 | } | ||
| 403 | |||
| 394 | /* Assigns the N and Z flags depending on the value of result. */ | 404 | /* Assigns the N and Z flags depending on the value of result. */ |
| 395 | 405 | ||
| 396 | void | 406 | void |
| @@ -443,6 +453,14 @@ ARMul_AddOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result) | |||
| 443 | ASSIGNV (AddOverflow (a, b, result)); | 453 | ASSIGNV (AddOverflow (a, b, result)); |
| 444 | } | 454 | } |
| 445 | 455 | ||
| 456 | /* Assigns the Q flag if the given result is considered an overflow from the addition of a and b */ | ||
| 457 | void ARMul_AddOverflowQ(ARMul_State* state, ARMword a, ARMword b) | ||
| 458 | { | ||
| 459 | u32 result = a + b; | ||
| 460 | if (((result ^ a) & (u32)0x80000000) && ((a ^ b) & (u32)0x80000000) == 0) | ||
| 461 | SETQ; | ||
| 462 | } | ||
| 463 | |||
| 446 | /* Assigns the C flag after an subtraction of a and b to give result. */ | 464 | /* Assigns the C flag after an subtraction of a and b to give result. */ |
| 447 | 465 | ||
| 448 | void | 466 | void |
| @@ -460,6 +478,142 @@ ARMul_SubOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result) | |||
| 460 | ASSIGNV (SubOverflow (a, b, result)); | 478 | ASSIGNV (SubOverflow (a, b, result)); |
| 461 | } | 479 | } |
| 462 | 480 | ||
| 481 | /* 8-bit signed saturated addition */ | ||
| 482 | u8 ARMul_SignedSaturatedAdd8(u8 left, u8 right) | ||
| 483 | { | ||
| 484 | u8 result = left + right; | ||
| 485 | |||
| 486 | if (((result ^ left) & 0x80) && ((left ^ right) & 0x80) == 0) { | ||
| 487 | if (left & 0x80) | ||
| 488 | result = 0x80; | ||
| 489 | else | ||
| 490 | result = 0x7F; | ||
| 491 | } | ||
| 492 | |||
| 493 | return result; | ||
| 494 | } | ||
| 495 | |||
| 496 | /* 8-bit signed saturated subtraction */ | ||
| 497 | u8 ARMul_SignedSaturatedSub8(u8 left, u8 right) | ||
| 498 | { | ||
| 499 | u8 result = left - right; | ||
| 500 | |||
| 501 | if (((result ^ left) & 0x80) && ((left ^ right) & 0x80) != 0) { | ||
| 502 | if (left & 0x80) | ||
| 503 | result = 0x80; | ||
| 504 | else | ||
| 505 | result = 0x7F; | ||
| 506 | } | ||
| 507 | |||
| 508 | return result; | ||
| 509 | } | ||
| 510 | |||
| 511 | /* 16-bit signed saturated addition */ | ||
| 512 | u16 ARMul_SignedSaturatedAdd16(u16 left, u16 right) | ||
| 513 | { | ||
| 514 | u16 result = left + right; | ||
| 515 | |||
| 516 | if (((result ^ left) & 0x8000) && ((left ^ right) & 0x8000) == 0) { | ||
| 517 | if (left & 0x8000) | ||
| 518 | result = 0x8000; | ||
| 519 | else | ||
| 520 | result = 0x7FFF; | ||
| 521 | } | ||
| 522 | |||
| 523 | return result; | ||
| 524 | } | ||
| 525 | |||
| 526 | /* 16-bit signed saturated subtraction */ | ||
| 527 | u16 ARMul_SignedSaturatedSub16(u16 left, u16 right) | ||
| 528 | { | ||
| 529 | u16 result = left - right; | ||
| 530 | |||
| 531 | if (((result ^ left) & 0x8000) && ((left ^ right) & 0x8000) != 0) { | ||
| 532 | if (left & 0x8000) | ||
| 533 | result = 0x8000; | ||
| 534 | else | ||
| 535 | result = 0x7FFF; | ||
| 536 | } | ||
| 537 | |||
| 538 | return result; | ||
| 539 | } | ||
| 540 | |||
| 541 | /* 8-bit unsigned saturated addition */ | ||
| 542 | u8 ARMul_UnsignedSaturatedAdd8(u8 left, u8 right) | ||
| 543 | { | ||
| 544 | u8 result = left + right; | ||
| 545 | |||
| 546 | if (result < left) | ||
| 547 | result = 0xFF; | ||
| 548 | |||
| 549 | return result; | ||
| 550 | } | ||
| 551 | |||
| 552 | /* 16-bit unsigned saturated addition */ | ||
| 553 | u16 ARMul_UnsignedSaturatedAdd16(u16 left, u16 right) | ||
| 554 | { | ||
| 555 | u16 result = left + right; | ||
| 556 | |||
| 557 | if (result < left) | ||
| 558 | result = 0xFFFF; | ||
| 559 | |||
| 560 | return result; | ||
| 561 | } | ||
| 562 | |||
| 563 | /* 8-bit unsigned saturated subtraction */ | ||
| 564 | u8 ARMul_UnsignedSaturatedSub8(u8 left, u8 right) | ||
| 565 | { | ||
| 566 | if (left <= right) | ||
| 567 | return 0; | ||
| 568 | |||
| 569 | return left - right; | ||
| 570 | } | ||
| 571 | |||
| 572 | /* 16-bit unsigned saturated subtraction */ | ||
| 573 | u16 ARMul_UnsignedSaturatedSub16(u16 left, u16 right) | ||
| 574 | { | ||
| 575 | if (left <= right) | ||
| 576 | return 0; | ||
| 577 | |||
| 578 | return left - right; | ||
| 579 | } | ||
| 580 | |||
| 581 | // Signed saturation. | ||
| 582 | u32 ARMul_SignedSatQ(s32 value, u8 shift, bool* saturation_occurred) | ||
| 583 | { | ||
| 584 | const u32 max = (1 << shift) - 1; | ||
| 585 | const s32 top = (value >> shift); | ||
| 586 | |||
| 587 | if (top > 0) { | ||
| 588 | *saturation_occurred = true; | ||
| 589 | return max; | ||
| 590 | } | ||
| 591 | else if (top < -1) { | ||
| 592 | *saturation_occurred = true; | ||
| 593 | return ~max; | ||
| 594 | } | ||
| 595 | |||
| 596 | *saturation_occurred = false; | ||
| 597 | return (u32)value; | ||
| 598 | } | ||
| 599 | |||
| 600 | // Unsigned saturation | ||
| 601 | u32 ARMul_UnsignedSatQ(s32 value, u8 shift, bool* saturation_occurred) | ||
| 602 | { | ||
| 603 | const u32 max = (1 << shift) - 1; | ||
| 604 | |||
| 605 | if (value < 0) { | ||
| 606 | *saturation_occurred = true; | ||
| 607 | return 0; | ||
| 608 | } else if ((u32)value > max) { | ||
| 609 | *saturation_occurred = true; | ||
| 610 | return max; | ||
| 611 | } | ||
| 612 | |||
| 613 | *saturation_occurred = false; | ||
| 614 | return (u32)value; | ||
| 615 | } | ||
| 616 | |||
| 463 | /* This function does the work of generating the addresses used in an | 617 | /* This function does the work of generating the addresses used in an |
| 464 | LDC instruction. The code here is always post-indexed, it's up to the | 618 | LDC instruction. The code here is always post-indexed, it's up to the |
| 465 | caller to get the input address correct and to handle base register | 619 | caller to get the input address correct and to handle base register |
| @@ -665,7 +819,7 @@ ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source) | |||
| 665 | //if (!CP_ACCESS_ALLOWED (state, CPNum)) { | 819 | //if (!CP_ACCESS_ALLOWED (state, CPNum)) { |
| 666 | if (!state->MCR[CPNum]) { | 820 | if (!state->MCR[CPNum]) { |
| 667 | //chy 2004-07-19 should fix in the future ????!!!! | 821 | //chy 2004-07-19 should fix in the future ????!!!! |
| 668 | DEBUG("SKYEYE ARMul_MCR, ACCESS_not ALLOWed, UndefinedInstr CPnum is %x, source %x\n",CPNum, source); | 822 | LOG_ERROR(Core_ARM11, "SKYEYE ARMul_MCR, ACCESS_not ALLOWed, UndefinedInstr CPnum is %x, source %x",CPNum, source); |
| 669 | ARMul_UndefInstr (state, instr); | 823 | ARMul_UndefInstr (state, instr); |
| 670 | return; | 824 | return; |
| 671 | } | 825 | } |
| @@ -690,7 +844,7 @@ ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source) | |||
| 690 | } | 844 | } |
| 691 | 845 | ||
| 692 | if (cpab == ARMul_CANT) { | 846 | if (cpab == ARMul_CANT) { |
| 693 | DEBUG("SKYEYE ARMul_MCR, CANT, UndefinedInstr %x CPnum is %x, source %x\n", instr, CPNum, source); //ichfly todo | 847 | LOG_ERROR(Core_ARM11, "SKYEYE ARMul_MCR, CANT, UndefinedInstr %x CPnum is %x, source %x", instr, CPNum, source); //ichfly todo |
| 694 | //ARMul_Abort (state, ARMul_UndefinedInstrV); | 848 | //ARMul_Abort (state, ARMul_UndefinedInstrV); |
| 695 | } else { | 849 | } else { |
| 696 | BUSUSEDINCPCN; | 850 | BUSUSEDINCPCN; |
| @@ -762,7 +916,7 @@ ARMword ARMul_MRC (ARMul_State * state, ARMword instr) | |||
| 762 | //if (!CP_ACCESS_ALLOWED (state, CPNum)) { | 916 | //if (!CP_ACCESS_ALLOWED (state, CPNum)) { |
| 763 | if (!state->MRC[CPNum]) { | 917 | if (!state->MRC[CPNum]) { |
| 764 | //chy 2004-07-19 should fix in the future????!!!! | 918 | //chy 2004-07-19 should fix in the future????!!!! |
| 765 | DEBUG("SKYEYE ARMul_MRC,NOT ALLOWed UndefInstr CPnum is %x, instr %x\n", CPNum, instr); | 919 | LOG_ERROR(Core_ARM11, "SKYEYE ARMul_MRC,NOT ALLOWed UndefInstr CPnum is %x, instr %x", CPNum, instr); |
| 766 | ARMul_UndefInstr (state, instr); | 920 | ARMul_UndefInstr (state, instr); |
| 767 | return -1; | 921 | return -1; |
| 768 | } | 922 | } |
| @@ -865,7 +1019,7 @@ void | |||
| 865 | ARMul_UndefInstr (ARMul_State * state, ARMword instr) | 1019 | ARMul_UndefInstr (ARMul_State * state, ARMword instr) |
| 866 | { | 1020 | { |
| 867 | std::string disasm = ARM_Disasm::Disassemble(state->pc, instr); | 1021 | std::string disasm = ARM_Disasm::Disassemble(state->pc, instr); |
| 868 | ERROR_LOG(ARM11, "Undefined instruction!! Disasm: %s Opcode: 0x%x", disasm.c_str(), instr); | 1022 | LOG_ERROR(Core_ARM11, "Undefined instruction!! Disasm: %s Opcode: 0x%x", disasm.c_str(), instr); |
| 869 | ARMul_Abort (state, ARMul_UndefinedInstrV); | 1023 | ARMul_Abort (state, ARMul_UndefinedInstrV); |
| 870 | } | 1024 | } |
| 871 | 1025 | ||