diff options
| author | 2014-12-30 09:19:33 -0500 | |
|---|---|---|
| committer | 2014-12-30 09:43:24 -0500 | |
| commit | cc9f458ad3dbcc3643c9df6c9040920bd2cb7444 (patch) | |
| tree | a94d35918065c7ed1281847646345f88bc292341 /src | |
| parent | Merge pull request #368 from purpasmart96/dsp_mem (diff) | |
| download | yuzu-cc9f458ad3dbcc3643c9df6c9040920bd2cb7444.tar.gz yuzu-cc9f458ad3dbcc3643c9df6c9040920bd2cb7444.tar.xz yuzu-cc9f458ad3dbcc3643c9df6c9040920bd2cb7444.zip | |
dyncom: Implement USAT16/SSAT16
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 63 |
1 files changed, 61 insertions, 2 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index a66560af2..cecb81237 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp | |||
| @@ -2551,7 +2551,22 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(ssat)(unsigned int inst, int index) | |||
| 2551 | 2551 | ||
| 2552 | return inst_base; | 2552 | return inst_base; |
| 2553 | } | 2553 | } |
| 2554 | ARM_INST_PTR INTERPRETER_TRANSLATE(ssat16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SSAT16"); } | 2554 | ARM_INST_PTR INTERPRETER_TRANSLATE(ssat16)(unsigned int inst, int index) |
| 2555 | { | ||
| 2556 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ssat_inst)); | ||
| 2557 | ssat_inst* const inst_cream = (ssat_inst*)inst_base->component; | ||
| 2558 | |||
| 2559 | inst_base->cond = BITS(inst, 28, 31); | ||
| 2560 | inst_base->idx = index; | ||
| 2561 | inst_base->br = NON_BRANCH; | ||
| 2562 | inst_base->load_r15 = 0; | ||
| 2563 | |||
| 2564 | inst_cream->Rn = BITS(inst, 0, 3); | ||
| 2565 | inst_cream->Rd = BITS(inst, 12, 15); | ||
| 2566 | inst_cream->sat_imm = BITS(inst, 16, 19); | ||
| 2567 | |||
| 2568 | return inst_base; | ||
| 2569 | } | ||
| 2555 | ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SSUB8"); } | 2570 | ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SSUB8"); } |
| 2556 | ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index) | 2571 | ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index) |
| 2557 | { | 2572 | { |
| @@ -3157,7 +3172,10 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(usat)(unsigned int inst, int index) | |||
| 3157 | { | 3172 | { |
| 3158 | return INTERPRETER_TRANSLATE(ssat)(inst, index); | 3173 | return INTERPRETER_TRANSLATE(ssat)(inst, index); |
| 3159 | } | 3174 | } |
| 3160 | ARM_INST_PTR INTERPRETER_TRANSLATE(usat16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USAT16"); } | 3175 | ARM_INST_PTR INTERPRETER_TRANSLATE(usat16)(unsigned int inst, int index) |
| 3176 | { | ||
| 3177 | return INTERPRETER_TRANSLATE(ssat16)(inst, index); | ||
| 3178 | } | ||
| 3161 | ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB16"); } | 3179 | ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB16"); } |
| 3162 | ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB8"); } | 3180 | ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB8"); } |
| 3163 | ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUBADDX"); } | 3181 | ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUBADDX"); } |
| @@ -5575,6 +5593,26 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 5575 | } | 5593 | } |
| 5576 | 5594 | ||
| 5577 | SSAT16_INST: | 5595 | SSAT16_INST: |
| 5596 | { | ||
| 5597 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 5598 | ssat_inst* const inst_cream = (ssat_inst*)inst_base->component; | ||
| 5599 | const u8 saturate_to = inst_cream->sat_imm; | ||
| 5600 | |||
| 5601 | bool sat1 = false; | ||
| 5602 | bool sat2 = false; | ||
| 5603 | |||
| 5604 | RD = (ARMul_SignedSatQ((s16)RN, saturate_to, &sat1) & 0xFFFF) | | ||
| 5605 | ARMul_SignedSatQ((s32)RN >> 16, saturate_to, &sat2) << 16; | ||
| 5606 | |||
| 5607 | if (sat1 || sat2) | ||
| 5608 | cpu->Cpsr |= (1 << 27); | ||
| 5609 | } | ||
| 5610 | |||
| 5611 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5612 | INC_PC(sizeof(ssat_inst)); | ||
| 5613 | FETCH_INST; | ||
| 5614 | GOTO_NEXT_INST; | ||
| 5615 | } | ||
| 5578 | SSUB8_INST: | 5616 | SSUB8_INST: |
| 5579 | STC_INST: | 5617 | STC_INST: |
| 5580 | { | 5618 | { |
| @@ -6355,6 +6393,27 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 6355 | } | 6393 | } |
| 6356 | 6394 | ||
| 6357 | USAT16_INST: | 6395 | USAT16_INST: |
| 6396 | { | ||
| 6397 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | ||
| 6398 | ssat_inst* const inst_cream = (ssat_inst*)inst_base->component; | ||
| 6399 | const u8 saturate_to = inst_cream->sat_imm; | ||
| 6400 | |||
| 6401 | bool sat1 = false; | ||
| 6402 | bool sat2 = false; | ||
| 6403 | |||
| 6404 | RD = (ARMul_UnsignedSatQ((s16)RN, saturate_to, &sat1) & 0xFFFF) | | ||
| 6405 | ARMul_UnsignedSatQ((s32)RN >> 16, saturate_to, &sat2) << 16; | ||
| 6406 | |||
| 6407 | if (sat1 || sat2) | ||
| 6408 | cpu->Cpsr |= (1 << 27); | ||
| 6409 | } | ||
| 6410 | |||
| 6411 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 6412 | INC_PC(sizeof(ssat_inst)); | ||
| 6413 | FETCH_INST; | ||
| 6414 | GOTO_NEXT_INST; | ||
| 6415 | } | ||
| 6416 | |||
| 6358 | USUB16_INST: | 6417 | USUB16_INST: |
| 6359 | USUB8_INST: | 6418 | USUB8_INST: |
| 6360 | USUBADDX_INST: | 6419 | USUBADDX_INST: |