mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	Merge pull request #472 from lioncash/overflow
dyncom: Fix some more V-flag setting ops. Plus some cleanup.
This commit is contained in:
		
						commit
						f3a7b66267
					
				
					 3 changed files with 175 additions and 147 deletions
				
			
		|  | @ -3967,16 +3967,12 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|         &&INIT_INST_LENGTH,&&END | ||||
|         }; | ||||
| #endif | ||||
|     arm_inst * inst_base; | ||||
|     unsigned int lop, rop, dst; | ||||
|     arm_inst* inst_base; | ||||
|     unsigned int addr; | ||||
|     unsigned int phys_addr; | ||||
|     unsigned int last_pc = 0; | ||||
|     unsigned int num_instrs = 0; | ||||
| 
 | ||||
|     static unsigned int last_physical_base = 0, last_logical_base = 0; | ||||
|     int ptr; | ||||
|     bool single_step = (cpu->NumInstrsToExecute == 1); | ||||
| 
 | ||||
|     LOAD_NZCVT; | ||||
|     DISPATCH: | ||||
|  | @ -4003,16 +3999,13 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|     } | ||||
|     ADC_INST: | ||||
|     { | ||||
|         adc_inst *inst_cream = (adc_inst *)inst_base->component; | ||||
|         if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||||
|             u32 left = RN; | ||||
|             u32 right = SHIFTER_OPERAND; | ||||
|         if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||||
|             adc_inst* const inst_cream = (adc_inst*)inst_base->component; | ||||
| 
 | ||||
|             u64 unsigned_sum = (left + right + cpu->CFlag); | ||||
|             s64 signed_sum = (s64)(s32)left + (s64)(s32)right + (s64)cpu->CFlag; | ||||
|             u32 result = (unsigned_sum & 0xFFFFFFFF); | ||||
|             bool carry; | ||||
|             bool overflow; | ||||
|             RD = AddWithCarry(RN, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); | ||||
| 
 | ||||
|             RD = result; | ||||
|             if (inst_cream->S && (inst_cream->Rd == 15)) { | ||||
|                 if (CurrentModeHasSPSR) { | ||||
|                     cpu->Cpsr = cpu->Spsr_copy; | ||||
|  | @ -4020,10 +4013,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|                     LOAD_NZCVT; | ||||
|                 } | ||||
|             } else if (inst_cream->S) { | ||||
|                 UPDATE_NFLAG(result); | ||||
|                 UPDATE_ZFLAG(result); | ||||
|                 UPDATE_CFLAG_CARRY_FROM_ADD(left, right, cpu->CFlag); | ||||
|                 cpu->VFlag = ((s64)(s32)result != signed_sum); | ||||
|                 UPDATE_NFLAG(RD); | ||||
|                 UPDATE_ZFLAG(RD); | ||||
|                 cpu->CFlag = carry; | ||||
|                 cpu->VFlag = overflow; | ||||
|             } | ||||
|             if (inst_cream->Rd == 15) { | ||||
|                 INC_PC(sizeof(adc_inst)); | ||||
|  | @ -4037,14 +4030,17 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|     } | ||||
|     ADD_INST: | ||||
|     { | ||||
|         add_inst *inst_cream = (add_inst *)inst_base->component; | ||||
|         if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||||
|             lop = RN; | ||||
|             if (inst_cream->Rn == 15) { | ||||
|                 lop += 2 * GET_INST_SIZE(cpu); | ||||
|             } | ||||
|             rop = SHIFTER_OPERAND; | ||||
|             RD = dst = lop + rop; | ||||
|         if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||||
|             add_inst* const inst_cream = (add_inst*)inst_base->component; | ||||
| 
 | ||||
|             u32 rn_val = RN; | ||||
|             if (inst_cream->Rn == 15) | ||||
|                 rn_val += 2 * GET_INST_SIZE(cpu); | ||||
| 
 | ||||
|             bool carry; | ||||
|             bool overflow; | ||||
|             RD = AddWithCarry(rn_val, SHIFTER_OPERAND, 0, &carry, &overflow); | ||||
| 
 | ||||
|             if (inst_cream->S && (inst_cream->Rd == 15)) { | ||||
|                 if (CurrentModeHasSPSR) { | ||||
|                     cpu->Cpsr = cpu->Spsr_copy; | ||||
|  | @ -4052,10 +4048,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|                     LOAD_NZCVT; | ||||
|                 } | ||||
|             } else if (inst_cream->S) { | ||||
|                 UPDATE_NFLAG(dst); | ||||
|                 UPDATE_ZFLAG(dst); | ||||
|                 UPDATE_CFLAG(dst, lop, rop); | ||||
|                 UPDATE_VFLAG((int)dst, (int)lop, (int)rop); | ||||
|                 UPDATE_NFLAG(RD); | ||||
|                 UPDATE_ZFLAG(RD); | ||||
|                 cpu->CFlag = carry; | ||||
|                 cpu->VFlag = overflow; | ||||
|             } | ||||
|             if (inst_cream->Rd == 15) { | ||||
|                 INC_PC(sizeof(add_inst)); | ||||
|  | @ -4071,9 +4067,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|     { | ||||
|         and_inst *inst_cream = (and_inst *)inst_base->component; | ||||
|         if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||||
|             lop = RN; | ||||
|             rop = SHIFTER_OPERAND; | ||||
|             RD = dst = lop & rop; | ||||
|             u32 lop = RN; | ||||
|             u32 rop = SHIFTER_OPERAND; | ||||
|             RD = lop & rop; | ||||
|             if (inst_cream->S && (inst_cream->Rd == 15)) { | ||||
|                 if (CurrentModeHasSPSR) { | ||||
|                     cpu->Cpsr = cpu->Spsr_copy; | ||||
|  | @ -4081,8 +4077,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|                     LOAD_NZCVT; | ||||
|                 } | ||||
|             } else if (inst_cream->S) { | ||||
|                 UPDATE_NFLAG(dst); | ||||
|                 UPDATE_ZFLAG(dst); | ||||
|                 UPDATE_NFLAG(RD); | ||||
|                 UPDATE_ZFLAG(RD); | ||||
|                 UPDATE_CFLAG_WITH_SC; | ||||
|             } | ||||
|             if (inst_cream->Rd == 15) { | ||||
|  | @ -4114,12 +4110,12 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|     { | ||||
|         bic_inst *inst_cream = (bic_inst *)inst_base->component; | ||||
|         if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||||
|             lop = RN; | ||||
|             u32 lop = RN; | ||||
|             if (inst_cream->Rn == 15) { | ||||
|                 lop += 2 * GET_INST_SIZE(cpu); | ||||
|             } | ||||
|             rop = SHIFTER_OPERAND; | ||||
|             RD = dst = lop & (~rop); | ||||
|             u32 rop = SHIFTER_OPERAND; | ||||
|             RD = lop & (~rop); | ||||
|             if ((inst_cream->S) && (inst_cream->Rd == 15)) { | ||||
|                 if (CurrentModeHasSPSR) { | ||||
|                     cpu->Cpsr = cpu->Spsr_copy; | ||||
|  | @ -4127,8 +4123,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|                     LOAD_NZCVT; | ||||
|                 } | ||||
|             } else if (inst_cream->S) { | ||||
|                 UPDATE_NFLAG(dst); | ||||
|                 UPDATE_ZFLAG(dst); | ||||
|                 UPDATE_NFLAG(RD); | ||||
|                 UPDATE_ZFLAG(RD); | ||||
|                 UPDATE_CFLAG_WITH_SC; | ||||
|             } | ||||
|             if (inst_cream->Rd == 15) { | ||||
|  | @ -4234,15 +4230,17 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|     } | ||||
|     CMN_INST: | ||||
|     { | ||||
|         cmn_inst *inst_cream = (cmn_inst *)inst_base->component; | ||||
|         if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||||
|             lop = RN; | ||||
|             rop = SHIFTER_OPERAND; | ||||
|             dst = lop + rop; | ||||
|             UPDATE_NFLAG(dst); | ||||
|             UPDATE_ZFLAG(dst); | ||||
|             UPDATE_CFLAG(dst, lop, rop); | ||||
|             UPDATE_VFLAG((int)dst, (int)lop, (int)rop); | ||||
|         if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||||
|             cmn_inst* const inst_cream = (cmn_inst*)inst_base->component; | ||||
| 
 | ||||
|             bool carry; | ||||
|             bool overflow; | ||||
|             u32 result = AddWithCarry(RN, SHIFTER_OPERAND, 0, &carry, &overflow); | ||||
| 
 | ||||
|             UPDATE_NFLAG(result); | ||||
|             UPDATE_ZFLAG(result); | ||||
|             cpu->CFlag = carry; | ||||
|             cpu->VFlag = overflow; | ||||
|         } | ||||
|         cpu->Reg[15] += GET_INST_SIZE(cpu); | ||||
|         INC_PC(sizeof(cmn_inst)); | ||||
|  | @ -4251,19 +4249,21 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|     } | ||||
|     CMP_INST: | ||||
|     { | ||||
|         if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||||
|             cmp_inst *inst_cream = (cmp_inst *)inst_base->component; | ||||
|             lop = RN; | ||||
|             if (inst_cream->Rn == 15) { | ||||
|                 lop += 2 * GET_INST_SIZE(cpu); | ||||
|             } | ||||
|             rop = SHIFTER_OPERAND; | ||||
|             dst = lop - rop; | ||||
|         if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||||
|             cmp_inst* const inst_cream = (cmp_inst*)inst_base->component; | ||||
| 
 | ||||
|             UPDATE_NFLAG(dst); | ||||
|             UPDATE_ZFLAG(dst); | ||||
|             UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); | ||||
|             UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); | ||||
|             u32 rn_val = RN; | ||||
|             if (inst_cream->Rn == 15) | ||||
|                 rn_val += 2 * GET_INST_SIZE(cpu); | ||||
| 
 | ||||
|             bool carry; | ||||
|             bool overflow; | ||||
|             u32 result = AddWithCarry(rn_val, ~SHIFTER_OPERAND, 1, &carry, &overflow); | ||||
| 
 | ||||
|             UPDATE_NFLAG(result); | ||||
|             UPDATE_ZFLAG(result); | ||||
|             cpu->CFlag = carry; | ||||
|             cpu->VFlag = overflow; | ||||
|         } | ||||
|         cpu->Reg[15] += GET_INST_SIZE(cpu); | ||||
|         INC_PC(sizeof(cmp_inst)); | ||||
|  | @ -4321,12 +4321,12 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|     { | ||||
|         eor_inst *inst_cream = (eor_inst *)inst_base->component; | ||||
|         if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||||
|             lop = RN; | ||||
|             u32 lop = RN; | ||||
|             if (inst_cream->Rn == 15) { | ||||
|                 lop += 2 * GET_INST_SIZE(cpu); | ||||
|             } | ||||
|             rop = SHIFTER_OPERAND; | ||||
|             RD = dst = lop ^ rop; | ||||
|             u32 rop = SHIFTER_OPERAND; | ||||
|             RD = lop ^ rop; | ||||
|             if (inst_cream->S && (inst_cream->Rd == 15)) { | ||||
|                 if (CurrentModeHasSPSR) { | ||||
|                     cpu->Cpsr = cpu->Spsr_copy; | ||||
|  | @ -4334,8 +4334,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|                     LOAD_NZCVT; | ||||
|                 } | ||||
|             } else if (inst_cream->S) { | ||||
|                 UPDATE_NFLAG(dst); | ||||
|                 UPDATE_ZFLAG(dst); | ||||
|                 UPDATE_NFLAG(RD); | ||||
|                 UPDATE_ZFLAG(RD); | ||||
|                 UPDATE_CFLAG_WITH_SC; | ||||
|             } | ||||
|             if (inst_cream->Rd == 15) { | ||||
|  | @ -4852,10 +4852,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|                 LOG_ERROR(Core_ARM11, "invalid operands for MLA"); | ||||
|                 CITRA_IGNORE_EXIT(-1); | ||||
|             } | ||||
|             RD = dst = static_cast<uint32_t>((rm * rs + rn) & 0xffffffff); | ||||
|             RD = static_cast<uint32_t>((rm * rs + rn) & 0xffffffff); | ||||
|             if (inst_cream->S) { | ||||
|                 UPDATE_NFLAG(dst); | ||||
|                 UPDATE_ZFLAG(dst); | ||||
|                 UPDATE_NFLAG(RD); | ||||
|                 UPDATE_ZFLAG(RD); | ||||
|             } | ||||
|             if (inst_cream->Rd == 15) { | ||||
|                 INC_PC(sizeof(mla_inst)); | ||||
|  | @ -4871,7 +4871,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|     { | ||||
|         mov_inst *inst_cream = (mov_inst *)inst_base->component; | ||||
|         if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||||
|             RD = dst = SHIFTER_OPERAND; | ||||
|             RD = SHIFTER_OPERAND; | ||||
|             if (inst_cream->S && (inst_cream->Rd == 15)) { | ||||
|                 if (CurrentModeHasSPSR) { | ||||
|                     cpu->Cpsr = cpu->Spsr_copy; | ||||
|  | @ -4879,8 +4879,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|                     LOAD_NZCVT; | ||||
|                 } | ||||
|             } else if (inst_cream->S) { | ||||
|                 UPDATE_NFLAG(dst); | ||||
|                 UPDATE_ZFLAG(dst); | ||||
|                 UPDATE_NFLAG(RD); | ||||
|                 UPDATE_ZFLAG(RD); | ||||
|                 UPDATE_CFLAG_WITH_SC; | ||||
|             } | ||||
|             if (inst_cream->Rd == 15) { | ||||
|  | @ -5016,10 +5016,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|         if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||||
|             uint64_t rm = RM; | ||||
|             uint64_t rs = RS; | ||||
|             RD = dst = static_cast<uint32_t>((rm * rs) & 0xffffffff); | ||||
|             RD = static_cast<uint32_t>((rm * rs) & 0xffffffff); | ||||
|             if (inst_cream->S) { | ||||
|                 UPDATE_NFLAG(dst); | ||||
|                 UPDATE_ZFLAG(dst); | ||||
|                 UPDATE_NFLAG(RD); | ||||
|                 UPDATE_ZFLAG(RD); | ||||
|             } | ||||
|             if (inst_cream->Rd == 15) { | ||||
|                 INC_PC(sizeof(mul_inst)); | ||||
|  | @ -5033,9 +5033,11 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|     } | ||||
|     MVN_INST: | ||||
|     { | ||||
|         mvn_inst *inst_cream = (mvn_inst *)inst_base->component; | ||||
|         if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||||
|             RD = dst = ~SHIFTER_OPERAND; | ||||
|         if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||||
|             mvn_inst* const inst_cream = (mvn_inst*)inst_base->component; | ||||
| 
 | ||||
|             RD = ~SHIFTER_OPERAND; | ||||
| 
 | ||||
|             if (inst_cream->S && (inst_cream->Rd == 15)) { | ||||
|                 if (CurrentModeHasSPSR) { | ||||
|                     cpu->Cpsr = cpu->Spsr_copy; | ||||
|  | @ -5043,8 +5045,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|                     LOAD_NZCVT; | ||||
|                 } | ||||
|             } else if (inst_cream->S) { | ||||
|                 UPDATE_NFLAG(dst); | ||||
|                 UPDATE_ZFLAG(dst); | ||||
|                 UPDATE_NFLAG(RD); | ||||
|                 UPDATE_ZFLAG(RD); | ||||
|                 UPDATE_CFLAG_WITH_SC; | ||||
|             } | ||||
|             if (inst_cream->Rd == 15) { | ||||
|  | @ -5059,11 +5061,13 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|     } | ||||
|     ORR_INST: | ||||
|     { | ||||
|         orr_inst *inst_cream = (orr_inst *)inst_base->component; | ||||
|         if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||||
|             lop = RN; | ||||
|             rop = SHIFTER_OPERAND; | ||||
|             RD = dst = lop | rop; | ||||
|         if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||||
|             orr_inst* const inst_cream = (orr_inst*)inst_base->component; | ||||
| 
 | ||||
|             u32 lop = RN; | ||||
|             u32 rop = SHIFTER_OPERAND; | ||||
|             RD = lop | rop; | ||||
| 
 | ||||
|             if (inst_cream->S && (inst_cream->Rd == 15)) { | ||||
|                 if (CurrentModeHasSPSR) { | ||||
|                     cpu->Cpsr = cpu->Spsr_copy; | ||||
|  | @ -5071,8 +5075,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|                     LOAD_NZCVT; | ||||
|                 } | ||||
|             } else if (inst_cream->S) { | ||||
|                 UPDATE_NFLAG(dst); | ||||
|                 UPDATE_ZFLAG(dst); | ||||
|                 UPDATE_NFLAG(RD); | ||||
|                 UPDATE_ZFLAG(RD); | ||||
|                 UPDATE_CFLAG_WITH_SC; | ||||
|             } | ||||
|             if (inst_cream->Rd == 15) { | ||||
|  | @ -5292,14 +5296,17 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|     RFE_INST: | ||||
|     RSB_INST: | ||||
|     { | ||||
|         rsb_inst *inst_cream = (rsb_inst *)inst_base->component; | ||||
|         if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||||
|             rop = RN; | ||||
|             lop = SHIFTER_OPERAND; | ||||
|             if (inst_cream->Rn == 15) { | ||||
|                 rop += 2 * GET_INST_SIZE(cpu);; | ||||
|             } | ||||
|             RD = dst = lop - rop; | ||||
|         if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||||
|             rsb_inst* const inst_cream = (rsb_inst*)inst_base->component; | ||||
| 
 | ||||
|             u32 rn_val = RN; | ||||
|             if (inst_cream->Rn == 15) | ||||
|                 rn_val += 2 * GET_INST_SIZE(cpu); | ||||
| 
 | ||||
|             bool carry; | ||||
|             bool overflow; | ||||
|             RD = AddWithCarry(~rn_val, SHIFTER_OPERAND, 1, &carry, &overflow); | ||||
| 
 | ||||
|             if (inst_cream->S && (inst_cream->Rd == 15)) { | ||||
|                 if (CurrentModeHasSPSR) { | ||||
|                     cpu->Cpsr = cpu->Spsr_copy; | ||||
|  | @ -5307,10 +5314,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|                     LOAD_NZCVT; | ||||
|                 } | ||||
|             } else if (inst_cream->S) { | ||||
|                 UPDATE_NFLAG(dst); | ||||
|                 UPDATE_ZFLAG(dst); | ||||
|                 UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); | ||||
|                 UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); | ||||
|                 UPDATE_NFLAG(RD); | ||||
|                 UPDATE_ZFLAG(RD); | ||||
|                 cpu->CFlag = carry; | ||||
|                 cpu->VFlag = overflow; | ||||
|             } | ||||
|             if (inst_cream->Rd == 15) { | ||||
|                 INC_PC(sizeof(rsb_inst)); | ||||
|  | @ -5324,11 +5331,13 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|     } | ||||
|     RSC_INST: | ||||
|     { | ||||
|         rsc_inst *inst_cream = (rsc_inst *)inst_base->component; | ||||
|         if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||||
|             lop = RN; | ||||
|             rop = SHIFTER_OPERAND; | ||||
|             RD = dst = rop - lop - !cpu->CFlag; | ||||
|         if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||||
|             rsc_inst* const inst_cream = (rsc_inst*)inst_base->component; | ||||
| 
 | ||||
|             bool carry; | ||||
|             bool overflow; | ||||
|             RD = AddWithCarry(~RN, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); | ||||
| 
 | ||||
|             if (inst_cream->S && (inst_cream->Rd == 15)) { | ||||
|                 if (CurrentModeHasSPSR) { | ||||
|                     cpu->Cpsr = cpu->Spsr_copy; | ||||
|  | @ -5336,10 +5345,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|                     LOAD_NZCVT; | ||||
|                 } | ||||
|             } else if (inst_cream->S) { | ||||
|                 UPDATE_NFLAG(dst); | ||||
|                 UPDATE_ZFLAG(dst); | ||||
|                 UPDATE_CFLAG_NOT_BORROW_FROM_FLAG(rop, lop, !cpu->CFlag); | ||||
|                 UPDATE_VFLAG_OVERFLOW_FROM((int)dst, (int)rop, (int)lop); | ||||
|                 UPDATE_NFLAG(RD); | ||||
|                 UPDATE_ZFLAG(RD); | ||||
|                 cpu->CFlag = carry; | ||||
|                 cpu->VFlag = overflow; | ||||
|             } | ||||
|             if (inst_cream->Rd == 15) { | ||||
|                 INC_PC(sizeof(rsc_inst)); | ||||
|  | @ -5462,11 +5471,13 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 
 | ||||
|     SBC_INST: | ||||
|     { | ||||
|         sbc_inst *inst_cream = (sbc_inst *)inst_base->component; | ||||
|         if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||||
|             lop = SHIFTER_OPERAND + !cpu->CFlag; | ||||
|             rop = RN; | ||||
|             RD = dst = rop - lop; | ||||
|         if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||||
|             sbc_inst* const inst_cream = (sbc_inst*)inst_base->component; | ||||
| 
 | ||||
|             bool carry; | ||||
|             bool overflow; | ||||
|             RD = AddWithCarry(RN, ~SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); | ||||
| 
 | ||||
|             if (inst_cream->S && (inst_cream->Rd == 15)) { | ||||
|                 if (CurrentModeHasSPSR) { | ||||
|                     cpu->Cpsr = cpu->Spsr_copy; | ||||
|  | @ -5474,15 +5485,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|                     LOAD_NZCVT; | ||||
|                 } | ||||
|             } else if (inst_cream->S) { | ||||
|                 UPDATE_NFLAG(dst); | ||||
|                 UPDATE_ZFLAG(dst); | ||||
| 
 | ||||
|                 if(rop >= !cpu->CFlag) | ||||
|                     UPDATE_CFLAG_NOT_BORROW_FROM(rop - !cpu->CFlag, SHIFTER_OPERAND); | ||||
|                 else | ||||
|                     UPDATE_CFLAG_NOT_BORROW_FROM(rop, !cpu->CFlag); | ||||
| 
 | ||||
|                 UPDATE_VFLAG_OVERFLOW_FROM(dst, rop, lop); | ||||
|                 UPDATE_NFLAG(RD); | ||||
|                 UPDATE_ZFLAG(RD); | ||||
|                 cpu->CFlag = carry; | ||||
|                 cpu->VFlag = overflow; | ||||
|             } | ||||
|             if (inst_cream->Rd == 15) { | ||||
|                 INC_PC(sizeof(sbc_inst)); | ||||
|  | @ -6260,14 +6266,17 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|     } | ||||
|     SUB_INST: | ||||
|     { | ||||
|         sub_inst *inst_cream = (sub_inst *)inst_base->component; | ||||
|         if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||||
|             lop = RN; | ||||
|             if (inst_cream->Rn == 15) { | ||||
|                 lop += 8; | ||||
|             } | ||||
|             rop = SHIFTER_OPERAND; | ||||
|             RD = dst = lop - rop; | ||||
|         if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||||
|             sub_inst* const inst_cream = (sub_inst*)inst_base->component; | ||||
| 
 | ||||
|             u32 rn_val = RN; | ||||
|             if (inst_cream->Rn == 15) | ||||
|                 rn_val += 8; | ||||
| 
 | ||||
|             bool carry; | ||||
|             bool overflow; | ||||
|             RD = AddWithCarry(rn_val, ~SHIFTER_OPERAND, 1, &carry, &overflow); | ||||
| 
 | ||||
|             if (inst_cream->S && (inst_cream->Rd == 15)) { | ||||
|                 if (CurrentModeHasSPSR) { | ||||
|                     cpu->Cpsr = cpu->Spsr_copy; | ||||
|  | @ -6275,10 +6284,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|                     LOAD_NZCVT; | ||||
|                 } | ||||
|             } else if (inst_cream->S) { | ||||
|                 UPDATE_NFLAG(dst); | ||||
|                 UPDATE_ZFLAG(dst); | ||||
|                 UPDATE_CFLAG_NOT_BORROW_FROM(lop, rop); | ||||
|                 UPDATE_VFLAG_OVERFLOW_FROM(dst, lop, rop); | ||||
|                 UPDATE_NFLAG(RD); | ||||
|                 UPDATE_ZFLAG(RD); | ||||
|                 cpu->CFlag = carry; | ||||
|                 cpu->VFlag = overflow; | ||||
|             } | ||||
|             if (inst_cream->Rd == 15) { | ||||
|                 INC_PC(sizeof(sub_inst)); | ||||
|  | @ -6406,18 +6415,19 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 
 | ||||
|     TEQ_INST: | ||||
|     { | ||||
|         if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||||
|             teq_inst *inst_cream = (teq_inst *)inst_base->component; | ||||
|             lop = RN; | ||||
|         if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||||
|             teq_inst* const inst_cream = (teq_inst*)inst_base->component; | ||||
| 
 | ||||
|             u32 lop = RN; | ||||
|             u32 rop = SHIFTER_OPERAND; | ||||
| 
 | ||||
|             if (inst_cream->Rn == 15) | ||||
|                 lop += GET_INST_SIZE(cpu) * 2; | ||||
| 
 | ||||
|             rop = SHIFTER_OPERAND; | ||||
|             dst = lop ^ rop; | ||||
|             u32 result = lop ^ rop; | ||||
| 
 | ||||
|             UPDATE_NFLAG(dst); | ||||
|             UPDATE_ZFLAG(dst); | ||||
|             UPDATE_NFLAG(result); | ||||
|             UPDATE_ZFLAG(result); | ||||
|             UPDATE_CFLAG_WITH_SC; | ||||
|         } | ||||
|         cpu->Reg[15] += GET_INST_SIZE(cpu); | ||||
|  | @ -6427,18 +6437,19 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
|     } | ||||
|     TST_INST: | ||||
|     { | ||||
|         if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||||
|             tst_inst *inst_cream = (tst_inst *)inst_base->component; | ||||
|             lop = RN; | ||||
|         if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||||
|             tst_inst* const inst_cream = (tst_inst*)inst_base->component; | ||||
| 
 | ||||
|             u32 lop = RN; | ||||
|             u32 rop = SHIFTER_OPERAND; | ||||
| 
 | ||||
|             if (inst_cream->Rn == 15) | ||||
|                 lop += GET_INST_SIZE(cpu) * 2; | ||||
| 
 | ||||
|             rop = SHIFTER_OPERAND; | ||||
|             dst = lop & rop; | ||||
|             u32 result = lop & rop; | ||||
| 
 | ||||
|             UPDATE_NFLAG(dst); | ||||
|             UPDATE_ZFLAG(dst); | ||||
|             UPDATE_NFLAG(result); | ||||
|             UPDATE_ZFLAG(result); | ||||
|             UPDATE_CFLAG_WITH_SC; | ||||
|         } | ||||
|         cpu->Reg[15] += GET_INST_SIZE(cpu); | ||||
|  |  | |||
|  | @ -418,6 +418,22 @@ ARMul_NegZero (ARMul_State * state, ARMword result) | |||
|     } | ||||
| } | ||||
| 
 | ||||
| // Add with carry, indicates if a carry-out or signed overflow occurred.
 | ||||
| u32 AddWithCarry(u32 left, u32 right, u32 carry_in, bool* carry_out_occurred, bool* overflow_occurred) | ||||
| { | ||||
|     u64 unsigned_sum = (u64)left + (u64)right + (u64)carry_in; | ||||
|     s64 signed_sum = (s64)(s32)left + (s64)(s32)right + (s64)carry_in; | ||||
|     u64 result = (unsigned_sum & 0xFFFFFFFF); | ||||
| 
 | ||||
|     if (carry_out_occurred) | ||||
|         *carry_out_occurred = (result != unsigned_sum); | ||||
| 
 | ||||
|     if (overflow_occurred) | ||||
|         *overflow_occurred = ((s64)(s32)result != signed_sum); | ||||
| 
 | ||||
|     return (u32)result; | ||||
| } | ||||
| 
 | ||||
| // Compute whether an addition of A and B, giving RESULT, overflowed.
 | ||||
| bool AddOverflow(ARMword a, ARMword b, ARMword result) | ||||
| { | ||||
|  |  | |||
|  | @ -795,6 +795,7 @@ extern void ARMul_FixSPSR(ARMul_State*, ARMword, ARMword); | |||
| extern void ARMul_ConsolePrint(ARMul_State*, const char*, ...); | ||||
| extern void ARMul_SelectProcessor(ARMul_State*, unsigned); | ||||
| 
 | ||||
| extern u32 AddWithCarry(u32, u32, u32, bool*, bool*); | ||||
| extern bool ARMul_AddOverflowQ(ARMword, ARMword); | ||||
| 
 | ||||
| extern u8 ARMul_SignedSaturatedAdd8(u8, u8); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue