mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	Merge pull request #418 from lioncash/qd
dyncom: Implement QADD/QSUB/QDADD/QDSUB
This commit is contained in:
		
						commit
						8b1ec1a82a
					
				@ -2053,7 +2053,37 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    return inst_base;
 | 
					    return inst_base;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index)     { UNIMPLEMENTED_INSTRUCTION("QADD"); }
 | 
					
 | 
				
			||||||
 | 
					ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
 | 
				
			||||||
 | 
					    generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inst_base->cond     = BITS(inst, 28, 31);
 | 
				
			||||||
 | 
					    inst_base->idx      = index;
 | 
				
			||||||
 | 
					    inst_base->br       = NON_BRANCH;
 | 
				
			||||||
 | 
					    inst_base->load_r15 = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inst_cream->op1 = BITS(inst, 21, 22);
 | 
				
			||||||
 | 
					    inst_cream->Rm  = BITS(inst, 0, 3);
 | 
				
			||||||
 | 
					    inst_cream->Rn  = BITS(inst, 16, 19);
 | 
				
			||||||
 | 
					    inst_cream->Rd  = BITS(inst, 12, 15);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return inst_base;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return INTERPRETER_TRANSLATE(qadd)(inst, index);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return INTERPRETER_TRANSLATE(qadd)(inst, index);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return INTERPRETER_TRANSLATE(qadd)(inst, index);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index)
 | 
					ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
 | 
					    arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
 | 
				
			||||||
@ -2080,9 +2110,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    return INTERPRETER_TRANSLATE(qadd8)(inst, index);
 | 
					    return INTERPRETER_TRANSLATE(qadd8)(inst, index);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index)    { UNIMPLEMENTED_INSTRUCTION("QDADD"); }
 | 
					 | 
				
			||||||
ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index)    { UNIMPLEMENTED_INSTRUCTION("QDSUB"); }
 | 
					 | 
				
			||||||
ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index)     { UNIMPLEMENTED_INSTRUCTION("QSUB"); }
 | 
					 | 
				
			||||||
ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index)
 | 
					ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return INTERPRETER_TRANSLATE(qadd8)(inst, index);
 | 
					    return INTERPRETER_TRANSLATE(qadd8)(inst, index);
 | 
				
			||||||
@ -5042,6 +5069,78 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QADD_INST:
 | 
					    QADD_INST:
 | 
				
			||||||
 | 
					    QDADD_INST:
 | 
				
			||||||
 | 
					    QDSUB_INST:
 | 
				
			||||||
 | 
					    QSUB_INST:
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
 | 
				
			||||||
 | 
					            generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
 | 
				
			||||||
 | 
					            const u8 op1 = inst_cream->op1;
 | 
				
			||||||
 | 
					            const u32 rm_val = RM;
 | 
				
			||||||
 | 
					            const u32 rn_val = RN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            u32 result = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // QADD
 | 
				
			||||||
 | 
					            if (op1 == 0x00) {
 | 
				
			||||||
 | 
					                result = rm_val + rn_val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (AddOverflow(rm_val, rn_val, result)) {
 | 
				
			||||||
 | 
					                    result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
 | 
				
			||||||
 | 
					                    cpu->Cpsr |= (1 << 27);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            // QSUB
 | 
				
			||||||
 | 
					            else if (op1 == 0x01) {
 | 
				
			||||||
 | 
					                result = rm_val - rn_val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (SubOverflow(rm_val, rn_val, result)) {
 | 
				
			||||||
 | 
					                    result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
 | 
				
			||||||
 | 
					                    cpu->Cpsr |= (1 << 27);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            // QDADD
 | 
				
			||||||
 | 
					            else if (op1 == 0x02) {
 | 
				
			||||||
 | 
					                u32 mul = (rn_val * 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (AddOverflow(rn_val, rn_val, rn_val * 2)) {
 | 
				
			||||||
 | 
					                    mul = POS(mul) ? 0x80000000 : 0x7FFFFFFF;
 | 
				
			||||||
 | 
					                    cpu->Cpsr |= (1 << 27);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                result = mul + rm_val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (AddOverflow(rm_val, mul, result)) {
 | 
				
			||||||
 | 
					                    result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
 | 
				
			||||||
 | 
					                    cpu->Cpsr |= (1 << 27);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            // QDSUB
 | 
				
			||||||
 | 
					            else if (op1 == 0x03) {
 | 
				
			||||||
 | 
					                u32 mul = (rn_val * 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (AddOverflow(rn_val, rn_val, mul)) {
 | 
				
			||||||
 | 
					                    mul = POS(mul) ? 0x80000000 : 0x7FFFFFFF;
 | 
				
			||||||
 | 
					                    cpu->Cpsr |= (1 << 27);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                result = rm_val - mul;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (SubOverflow(rm_val, mul, result)) {
 | 
				
			||||||
 | 
					                    result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
 | 
				
			||||||
 | 
					                    cpu->Cpsr |= (1 << 27);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            RD = result;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cpu->Reg[15] += GET_INST_SIZE(cpu);
 | 
				
			||||||
 | 
					        INC_PC(sizeof(generic_arm_inst));
 | 
				
			||||||
 | 
					        FETCH_INST;
 | 
				
			||||||
 | 
					        GOTO_NEXT_INST;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QADD8_INST:
 | 
					    QADD8_INST:
 | 
				
			||||||
    QADD16_INST:
 | 
					    QADD16_INST:
 | 
				
			||||||
    QADDSUBX_INST:
 | 
					    QADDSUBX_INST:
 | 
				
			||||||
@ -5104,10 +5203,6 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
 | 
				
			|||||||
        GOTO_NEXT_INST;
 | 
					        GOTO_NEXT_INST;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    QDADD_INST:
 | 
					 | 
				
			||||||
    QDSUB_INST:
 | 
					 | 
				
			||||||
    QSUB_INST:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    REV_INST:
 | 
					    REV_INST:
 | 
				
			||||||
    REV16_INST:
 | 
					    REV16_INST:
 | 
				
			||||||
    REVSH_INST:
 | 
					    REVSH_INST:
 | 
				
			||||||
 | 
				
			|||||||
@ -418,22 +418,18 @@ ARMul_NegZero (ARMul_State * state, ARMword result)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Compute whether an addition of A and B, giving RESULT, overflowed.  */
 | 
					// Compute whether an addition of A and B, giving RESULT, overflowed.
 | 
				
			||||||
 | 
					bool AddOverflow(ARMword a, ARMword b, ARMword result)
 | 
				
			||||||
int
 | 
					 | 
				
			||||||
AddOverflow (ARMword a, ARMword b, ARMword result)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return ((NEG (a) && NEG (b) && POS (result))
 | 
					    return ((NEG(a) && NEG(b) && POS(result)) ||
 | 
				
			||||||
            || (POS (a) && POS (b) && NEG (result)));
 | 
					            (POS(a) && POS(b) && NEG(result)));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Compute whether a subtraction of A and B, giving RESULT, overflowed.  */
 | 
					// Compute whether a subtraction of A and B, giving RESULT, overflowed.
 | 
				
			||||||
 | 
					bool SubOverflow(ARMword a, ARMword b, ARMword result)
 | 
				
			||||||
int
 | 
					 | 
				
			||||||
SubOverflow (ARMword a, ARMword b, ARMword result)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return ((NEG (a) && POS (b) && POS (result))
 | 
					    return ((NEG(a) && POS(b) && POS(result)) ||
 | 
				
			||||||
            || (POS (a) && NEG (b) && NEG (result)));
 | 
					            (POS(a) && NEG(b) && NEG(result)));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Assigns the C flag after an addition of a and b to give result.  */
 | 
					/* Assigns the C flag after an addition of a and b to give result.  */
 | 
				
			||||||
 | 
				
			|||||||
@ -70,6 +70,9 @@
 | 
				
			|||||||
#define DATACACHE  1
 | 
					#define DATACACHE  1
 | 
				
			||||||
#define INSTCACHE  2
 | 
					#define INSTCACHE  2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define POS(i) ( (~(i)) >> 31 )
 | 
				
			||||||
 | 
					#define NEG(i) ( (i) >> 31 )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef __STDC__
 | 
					#ifndef __STDC__
 | 
				
			||||||
typedef char *VoidStar;
 | 
					typedef char *VoidStar;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@ -783,6 +786,8 @@ RUn %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n",\
 | 
				
			|||||||
//#define PXA250      0x69052903
 | 
					//#define PXA250      0x69052903
 | 
				
			||||||
// 0x69052903;  //PXA250 B1 from intel 278522-001.pdf
 | 
					// 0x69052903;  //PXA250 B1 from intel 278522-001.pdf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern bool AddOverflow(ARMword, ARMword, ARMword);
 | 
				
			||||||
 | 
					extern bool SubOverflow(ARMword, ARMword, ARMword);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern void ARMul_UndefInstr(ARMul_State*, ARMword);
 | 
					extern void ARMul_UndefInstr(ARMul_State*, ARMword);
 | 
				
			||||||
extern void ARMul_FixCPSR(ARMul_State*, ARMword, ARMword);
 | 
					extern void ARMul_FixCPSR(ARMul_State*, ARMword, ARMword);
 | 
				
			||||||
 | 
				
			|||||||
@ -42,9 +42,6 @@
 | 
				
			|||||||
#define R15FBIT (1L << 26)
 | 
					#define R15FBIT (1L << 26)
 | 
				
			||||||
#define R15IFBITS (3L << 26)
 | 
					#define R15IFBITS (3L << 26)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define POS(i) ( (~(i)) >> 31 )
 | 
					 | 
				
			||||||
#define NEG(i) ( (i) >> 31 )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef MODET			/* Thumb support.  */
 | 
					#ifdef MODET			/* Thumb support.  */
 | 
				
			||||||
/* ??? This bit is actually in the low order bit of the PC in the hardware.
 | 
					/* ??? This bit is actually in the low order bit of the PC in the hardware.
 | 
				
			||||||
   It isn't clear if the simulator needs to model that or not.  */
 | 
					   It isn't clear if the simulator needs to model that or not.  */
 | 
				
			||||||
@ -561,8 +558,7 @@ tdstate;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* Prototypes for exported functions.  */
 | 
					/* Prototypes for exported functions.  */
 | 
				
			||||||
extern unsigned ARMul_NthReg (ARMword, unsigned);
 | 
					extern unsigned ARMul_NthReg (ARMword, unsigned);
 | 
				
			||||||
extern int AddOverflow (ARMword, ARMword, ARMword);
 | 
					
 | 
				
			||||||
extern int SubOverflow (ARMword, ARMword, ARMword);
 | 
					 | 
				
			||||||
/* Prototypes for exported functions.  */
 | 
					/* Prototypes for exported functions.  */
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 extern "C" {
 | 
					 extern "C" {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user