summaryrefslogtreecommitdiff
path: root/src/core/arm/interpreter/armsupp.cpp
diff options
context:
space:
mode:
authorGravatar darkf2014-12-29 19:47:41 -0800
committerGravatar darkf2014-12-29 19:47:41 -0800
commit8ba9ac0f74abb0408a26207a76a0c1808bad8de0 (patch)
treef1c7c3393fa726435b5b90bf335567c93e528ef1 /src/core/arm/interpreter/armsupp.cpp
parentAdd comment regarding __WIN32__ in SkyEye code (diff)
parentMerge pull request #367 from bunnei/usat_ssat (diff)
downloadyuzu-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.cpp166
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 */
396u8 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
396void 406void
@@ -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 */
457void 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
448void 466void
@@ -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 */
482u8 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 */
497u8 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 */
512u16 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 */
527u16 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 */
542u8 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 */
553u16 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 */
564u8 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 */
573u16 ARMul_UnsignedSaturatedSub16(u16 left, u16 right)
574{
575 if (left <= right)
576 return 0;
577
578 return left - right;
579}
580
581// Signed saturation.
582u32 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
601u32 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
865ARMul_UndefInstr (ARMul_State * state, ARMword instr) 1019ARMul_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