summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Lioncash2015-01-12 00:43:12 -0500
committerGravatar Lioncash2015-01-12 01:03:58 -0500
commit3ace75a49f54d73a1d3ba876ef8dc0b03adc677f (patch)
tree19d25fb8240bdb0759e3e61364a26aa37e2af03b /src
parentdyncom: Add a helper function for addition with a carry (diff)
downloadyuzu-3ace75a49f54d73a1d3ba876ef8dc0b03adc677f.tar.gz
yuzu-3ace75a49f54d73a1d3ba876ef8dc0b03adc677f.tar.xz
yuzu-3ace75a49f54d73a1d3ba876ef8dc0b03adc677f.zip
dyncom: Fix overflow flag setting for ADD/RSB/RSC/SUB/SBC
Also cleans up CMN, and CMP.
Diffstat (limited to 'src')
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp79
1 files changed, 41 insertions, 38 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index 4c0a8f5cb..88982d5fb 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -4034,14 +4034,17 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
4034 } 4034 }
4035 ADD_INST: 4035 ADD_INST:
4036 { 4036 {
4037 add_inst *inst_cream = (add_inst *)inst_base->component; 4037 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
4038 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4038 add_inst* const inst_cream = (add_inst*)inst_base->component;
4039 lop = RN; 4039
4040 if (inst_cream->Rn == 15) { 4040 u32 rn_val = RN;
4041 lop += 2 * GET_INST_SIZE(cpu); 4041 if (inst_cream->Rn == 15)
4042 } 4042 rn_val += 2 * GET_INST_SIZE(cpu);
4043 rop = SHIFTER_OPERAND; 4043
4044 RD = dst = lop + rop; 4044 bool carry;
4045 bool overflow;
4046 RD = AddWithCarry(rn_val, SHIFTER_OPERAND, 0, &carry, &overflow);
4047
4045 if (inst_cream->S && (inst_cream->Rd == 15)) { 4048 if (inst_cream->S && (inst_cream->Rd == 15)) {
4046 if (CurrentModeHasSPSR) { 4049 if (CurrentModeHasSPSR) {
4047 cpu->Cpsr = cpu->Spsr_copy; 4050 cpu->Cpsr = cpu->Spsr_copy;
@@ -4049,10 +4052,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
4049 LOAD_NZCVT; 4052 LOAD_NZCVT;
4050 } 4053 }
4051 } else if (inst_cream->S) { 4054 } else if (inst_cream->S) {
4052 UPDATE_NFLAG(dst); 4055 UPDATE_NFLAG(RD);
4053 UPDATE_ZFLAG(dst); 4056 UPDATE_ZFLAG(RD);
4054 UPDATE_CFLAG(dst, lop, rop); 4057 cpu->CFlag = carry;
4055 UPDATE_VFLAG((int)dst, (int)lop, (int)rop); 4058 cpu->VFlag = overflow;
4056 } 4059 }
4057 if (inst_cream->Rd == 15) { 4060 if (inst_cream->Rd == 15) {
4058 INC_PC(sizeof(add_inst)); 4061 INC_PC(sizeof(add_inst));
@@ -5459,11 +5462,13 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
5459 5462
5460 SBC_INST: 5463 SBC_INST:
5461 { 5464 {
5462 sbc_inst *inst_cream = (sbc_inst *)inst_base->component; 5465 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
5463 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 5466 sbc_inst* const inst_cream = (sbc_inst*)inst_base->component;
5464 lop = SHIFTER_OPERAND + !cpu->CFlag; 5467
5465 rop = RN; 5468 bool carry;
5466 RD = dst = rop - lop; 5469 bool overflow;
5470 RD = AddWithCarry(RN, ~SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
5471
5467 if (inst_cream->S && (inst_cream->Rd == 15)) { 5472 if (inst_cream->S && (inst_cream->Rd == 15)) {
5468 if (CurrentModeHasSPSR) { 5473 if (CurrentModeHasSPSR) {
5469 cpu->Cpsr = cpu->Spsr_copy; 5474 cpu->Cpsr = cpu->Spsr_copy;
@@ -5471,15 +5476,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
5471 LOAD_NZCVT; 5476 LOAD_NZCVT;
5472 } 5477 }
5473 } else if (inst_cream->S) { 5478 } else if (inst_cream->S) {
5474 UPDATE_NFLAG(dst); 5479 UPDATE_NFLAG(RD);
5475 UPDATE_ZFLAG(dst); 5480 UPDATE_ZFLAG(RD);
5476 5481 cpu->CFlag = carry;
5477 if(rop >= !cpu->CFlag) 5482 cpu->VFlag = overflow;
5478 UPDATE_CFLAG_NOT_BORROW_FROM(rop - !cpu->CFlag, SHIFTER_OPERAND);
5479 else
5480 UPDATE_CFLAG_NOT_BORROW_FROM(rop, !cpu->CFlag);
5481
5482 UPDATE_VFLAG_OVERFLOW_FROM(dst, rop, lop);
5483 } 5483 }
5484 if (inst_cream->Rd == 15) { 5484 if (inst_cream->Rd == 15) {
5485 INC_PC(sizeof(sbc_inst)); 5485 INC_PC(sizeof(sbc_inst));
@@ -6257,14 +6257,17 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
6257 } 6257 }
6258 SUB_INST: 6258 SUB_INST:
6259 { 6259 {
6260 sub_inst *inst_cream = (sub_inst *)inst_base->component; 6260 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
6261 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 6261 sub_inst* const inst_cream = (sub_inst*)inst_base->component;
6262 lop = RN; 6262
6263 if (inst_cream->Rn == 15) { 6263 u32 rn_val = RN;
6264 lop += 8; 6264 if (inst_cream->Rn == 15)
6265 } 6265 rn_val += 8;
6266 rop = SHIFTER_OPERAND; 6266
6267 RD = dst = lop - rop; 6267 bool carry;
6268 bool overflow;
6269 RD = AddWithCarry(rn_val, ~SHIFTER_OPERAND, 1, &carry, &overflow);
6270
6268 if (inst_cream->S && (inst_cream->Rd == 15)) { 6271 if (inst_cream->S && (inst_cream->Rd == 15)) {
6269 if (CurrentModeHasSPSR) { 6272 if (CurrentModeHasSPSR) {
6270 cpu->Cpsr = cpu->Spsr_copy; 6273 cpu->Cpsr = cpu->Spsr_copy;
@@ -6272,10 +6275,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
6272 LOAD_NZCVT; 6275 LOAD_NZCVT;
6273 } 6276 }
6274 } else if (inst_cream->S) { 6277 } else if (inst_cream->S) {
6275 UPDATE_NFLAG(dst); 6278 UPDATE_NFLAG(RD);
6276 UPDATE_ZFLAG(dst); 6279 UPDATE_ZFLAG(RD);
6277 UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); 6280 cpu->CFlag = carry;
6278 UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); 6281 cpu->VFlag = overflow;
6279 } 6282 }
6280 if (inst_cream->Rd == 15) { 6283 if (inst_cream->Rd == 15) {
6281 INC_PC(sizeof(sub_inst)); 6284 INC_PC(sizeof(sub_inst));