summaryrefslogtreecommitdiff
path: root/src/core/arm/dyncom
diff options
context:
space:
mode:
authorGravatar bunnei2014-12-29 22:15:15 -0500
committerGravatar bunnei2014-12-29 22:15:15 -0500
commit021fb420752aa34dc3bee70fb2f3fe673176594f (patch)
treec5b620ccf025845e87e81f8079dc9438f052dae7 /src/core/arm/dyncom
parentMerge pull request #253 from purpasmart96/mem_map (diff)
downloadyuzu-021fb420752aa34dc3bee70fb2f3fe673176594f.tar.gz
yuzu-021fb420752aa34dc3bee70fb2f3fe673176594f.tar.xz
yuzu-021fb420752aa34dc3bee70fb2f3fe673176594f.zip
dyncom: Implement USAT/SSAT
Diffstat (limited to 'src/core/arm/dyncom')
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp96
1 files changed, 94 insertions, 2 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index 0ee103c56..a66560af2 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -1100,6 +1100,14 @@ typedef struct _smla_inst {
1100 unsigned int Rn; 1100 unsigned int Rn;
1101} smla_inst; 1101} smla_inst;
1102 1102
1103typedef struct ssat_inst {
1104 unsigned int Rn;
1105 unsigned int Rd;
1106 unsigned int imm5;
1107 unsigned int sat_imm;
1108 unsigned int shift_type;
1109} ssat_inst;
1110
1103typedef struct umaal_inst { 1111typedef struct umaal_inst {
1104 unsigned int Rn; 1112 unsigned int Rn;
1105 unsigned int Rm; 1113 unsigned int Rm;
@@ -2525,7 +2533,24 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(smulw)(unsigned int inst, int index)
2525} 2533}
2526ARM_INST_PTR INTERPRETER_TRANSLATE(smusd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMUSD"); } 2534ARM_INST_PTR INTERPRETER_TRANSLATE(smusd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMUSD"); }
2527ARM_INST_PTR INTERPRETER_TRANSLATE(srs)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SRS"); } 2535ARM_INST_PTR INTERPRETER_TRANSLATE(srs)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SRS"); }
2528ARM_INST_PTR INTERPRETER_TRANSLATE(ssat)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SSAT"); } 2536ARM_INST_PTR INTERPRETER_TRANSLATE(ssat)(unsigned int inst, int index)
2537{
2538 arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ssat_inst));
2539 ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
2540
2541 inst_base->cond = BITS(inst, 28, 31);
2542 inst_base->idx = index;
2543 inst_base->br = NON_BRANCH;
2544 inst_base->load_r15 = 0;
2545
2546 inst_cream->Rn = BITS(inst, 0, 3);
2547 inst_cream->Rd = BITS(inst, 12, 15);
2548 inst_cream->imm5 = BITS(inst, 7, 11);
2549 inst_cream->sat_imm = BITS(inst, 16, 20);
2550 inst_cream->shift_type = BIT(inst, 6);
2551
2552 return inst_base;
2553}
2529ARM_INST_PTR INTERPRETER_TRANSLATE(ssat16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SSAT16"); } 2554ARM_INST_PTR INTERPRETER_TRANSLATE(ssat16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SSAT16"); }
2530ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SSUB8"); } 2555ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SSUB8"); }
2531ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index) 2556ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index)
@@ -3128,7 +3153,10 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(usad8)(unsigned int inst, int index)
3128{ 3153{
3129 return INTERPRETER_TRANSLATE(usada8)(inst, index); 3154 return INTERPRETER_TRANSLATE(usada8)(inst, index);
3130} 3155}
3131ARM_INST_PTR INTERPRETER_TRANSLATE(usat)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USAT"); } 3156ARM_INST_PTR INTERPRETER_TRANSLATE(usat)(unsigned int inst, int index)
3157{
3158 return INTERPRETER_TRANSLATE(ssat)(inst, index);
3159}
3132ARM_INST_PTR INTERPRETER_TRANSLATE(usat16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USAT16"); } 3160ARM_INST_PTR INTERPRETER_TRANSLATE(usat16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USAT16"); }
3133ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB16"); } 3161ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB16"); }
3134ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB8"); } 3162ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB8"); }
@@ -5514,6 +5542,38 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
5514 SMUSD_INST: 5542 SMUSD_INST:
5515 SRS_INST: 5543 SRS_INST:
5516 SSAT_INST: 5544 SSAT_INST:
5545 {
5546 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
5547 ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
5548
5549 u8 shift_type = inst_cream->shift_type;
5550 u8 shift_amount = inst_cream->imm5;
5551 u32 rn_val = RN;
5552
5553 // 32-bit ASR is encoded as an amount of 0.
5554 if (shift_type == 1 && shift_amount == 0)
5555 shift_amount = 31;
5556
5557 if (shift_type == 0)
5558 rn_val <<= shift_amount;
5559 else if (shift_type == 1)
5560 rn_val = ((s32)rn_val >> shift_amount);
5561
5562 bool saturated = false;
5563 rn_val = ARMul_SignedSatQ(rn_val, inst_cream->sat_imm, &saturated);
5564
5565 if (saturated)
5566 cpu->Cpsr |= (1 << 27);
5567
5568 RD = rn_val;
5569 }
5570
5571 cpu->Reg[15] += GET_INST_SIZE(cpu);
5572 INC_PC(sizeof(ssat_inst));
5573 FETCH_INST;
5574 GOTO_NEXT_INST;
5575 }
5576
5517 SSAT16_INST: 5577 SSAT16_INST:
5518 SSUB8_INST: 5578 SSUB8_INST:
5519 STC_INST: 5579 STC_INST:
@@ -6262,6 +6322,38 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
6262 } 6322 }
6263 6323
6264 USAT_INST: 6324 USAT_INST:
6325 {
6326 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
6327 ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
6328
6329 u8 shift_type = inst_cream->shift_type;
6330 u8 shift_amount = inst_cream->imm5;
6331 u32 rn_val = RN;
6332
6333 // 32-bit ASR is encoded as an amount of 0.
6334 if (shift_type == 1 && shift_amount == 0)
6335 shift_amount = 31;
6336
6337 if (shift_type == 0)
6338 rn_val <<= shift_amount;
6339 else if (shift_type == 1)
6340 rn_val = ((s32)rn_val >> shift_amount);
6341
6342 bool saturated = false;
6343 rn_val = ARMul_UnsignedSatQ(rn_val, inst_cream->sat_imm, &saturated);
6344
6345 if (saturated)
6346 cpu->Cpsr |= (1 << 27);
6347
6348 RD = rn_val;
6349 }
6350
6351 cpu->Reg[15] += GET_INST_SIZE(cpu);
6352 INC_PC(sizeof(ssat_inst));
6353 FETCH_INST;
6354 GOTO_NEXT_INST;
6355 }
6356
6265 USAT16_INST: 6357 USAT16_INST:
6266 USUB16_INST: 6358 USUB16_INST:
6267 USUB8_INST: 6359 USUB8_INST: