diff options
| author | 2015-01-01 09:39:40 -0500 | |
|---|---|---|
| committer | 2015-01-01 09:39:40 -0500 | |
| commit | 4e2cb06b818bd28cbbfcb4cc2c51ab85176a40f2 (patch) | |
| tree | 3e8e5e3d254e0f02b9187e7be83c0dc6792b7cef /src/core | |
| parent | Merge pull request #265 from Subv/socu (diff) | |
| download | yuzu-4e2cb06b818bd28cbbfcb4cc2c51ab85176a40f2.tar.gz yuzu-4e2cb06b818bd28cbbfcb4cc2c51ab85176a40f2.tar.xz yuzu-4e2cb06b818bd28cbbfcb4cc2c51ab85176a40f2.zip | |
dyncom: Implement SADD8/SSUB8
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 163 |
1 files changed, 108 insertions, 55 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index c61ae0053..5908a4ccf 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp | |||
| @@ -2171,29 +2171,45 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(rsc)(unsigned int inst, int index) | |||
| 2171 | } | 2171 | } |
| 2172 | return inst_base; | 2172 | return inst_base; |
| 2173 | } | 2173 | } |
| 2174 | ARM_INST_PTR INTERPRETER_TRANSLATE(sadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SADD8"); } | 2174 | ARM_INST_PTR INTERPRETER_TRANSLATE(sadd8)(unsigned int inst, int index) |
| 2175 | ARM_INST_PTR INTERPRETER_TRANSLATE(sadd16)(unsigned int inst, int index) | ||
| 2176 | { | 2175 | { |
| 2177 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); | 2176 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); |
| 2178 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | 2177 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; |
| 2179 | 2178 | ||
| 2180 | inst_base->cond = BITS(inst, 28, 31); | 2179 | inst_base->cond = BITS(inst, 28, 31); |
| 2181 | inst_base->idx = index; | 2180 | inst_base->idx = index; |
| 2182 | inst_base->br = NON_BRANCH; | 2181 | inst_base->br = NON_BRANCH; |
| 2183 | inst_base->load_r15 = 0; | 2182 | inst_base->load_r15 = 0; |
| 2184 | 2183 | ||
| 2185 | inst_cream->Rm = BITS(inst, 0, 3); | 2184 | inst_cream->Rm = BITS(inst, 0, 3); |
| 2186 | inst_cream->Rn = BITS(inst, 16, 19); | 2185 | inst_cream->Rn = BITS(inst, 16, 19); |
| 2187 | inst_cream->Rd = BITS(inst, 12, 15); | 2186 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2188 | inst_cream->op1 = BITS(inst, 20, 21); | 2187 | inst_cream->op1 = BITS(inst, 20, 21); |
| 2189 | inst_cream->op2 = BITS(inst, 5, 7); | 2188 | inst_cream->op2 = BITS(inst, 5, 7); |
| 2190 | 2189 | ||
| 2191 | return inst_base; | 2190 | return inst_base; |
| 2192 | } | 2191 | } |
| 2192 | ARM_INST_PTR INTERPRETER_TRANSLATE(sadd16)(unsigned int inst, int index) | ||
| 2193 | { | ||
| 2194 | return INTERPRETER_TRANSLATE(sadd8)(inst, index); | ||
| 2195 | } | ||
| 2193 | ARM_INST_PTR INTERPRETER_TRANSLATE(saddsubx)(unsigned int inst, int index) | 2196 | ARM_INST_PTR INTERPRETER_TRANSLATE(saddsubx)(unsigned int inst, int index) |
| 2194 | { | 2197 | { |
| 2195 | return INTERPRETER_TRANSLATE(sadd16)(inst, index); | 2198 | return INTERPRETER_TRANSLATE(sadd8)(inst, index); |
| 2196 | } | 2199 | } |
| 2200 | ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index) | ||
| 2201 | { | ||
| 2202 | return INTERPRETER_TRANSLATE(sadd8)(inst, index); | ||
| 2203 | } | ||
| 2204 | ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index) | ||
| 2205 | { | ||
| 2206 | return INTERPRETER_TRANSLATE(sadd8)(inst, index); | ||
| 2207 | } | ||
| 2208 | ARM_INST_PTR INTERPRETER_TRANSLATE(ssubaddx)(unsigned int inst, int index) | ||
| 2209 | { | ||
| 2210 | return INTERPRETER_TRANSLATE(sadd8)(inst, index); | ||
| 2211 | } | ||
| 2212 | |||
| 2197 | ARM_INST_PTR INTERPRETER_TRANSLATE(sbc)(unsigned int inst, int index) | 2213 | ARM_INST_PTR INTERPRETER_TRANSLATE(sbc)(unsigned int inst, int index) |
| 2198 | { | 2214 | { |
| 2199 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sbc_inst)); | 2215 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sbc_inst)); |
| @@ -2408,15 +2424,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(ssat16)(unsigned int inst, int index) | |||
| 2408 | 2424 | ||
| 2409 | return inst_base; | 2425 | return inst_base; |
| 2410 | } | 2426 | } |
| 2411 | ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SSUB8"); } | 2427 | |
| 2412 | ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index) | ||
| 2413 | { | ||
| 2414 | return INTERPRETER_TRANSLATE(sadd16)(inst, index); | ||
| 2415 | } | ||
| 2416 | ARM_INST_PTR INTERPRETER_TRANSLATE(ssubaddx)(unsigned int inst, int index) | ||
| 2417 | { | ||
| 2418 | return INTERPRETER_TRANSLATE(sadd16)(inst, index); | ||
| 2419 | } | ||
| 2420 | ARM_INST_PTR INTERPRETER_TRANSLATE(stc)(unsigned int inst, int index) | 2428 | ARM_INST_PTR INTERPRETER_TRANSLATE(stc)(unsigned int inst, int index) |
| 2421 | { | 2429 | { |
| 2422 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(stc_inst)); | 2430 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(stc_inst)); |
| @@ -5039,6 +5047,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 5039 | } | 5047 | } |
| 5040 | 5048 | ||
| 5041 | SADD8_INST: | 5049 | SADD8_INST: |
| 5050 | SSUB8_INST: | ||
| 5042 | SADD16_INST: | 5051 | SADD16_INST: |
| 5043 | SADDSUBX_INST: | 5052 | SADDSUBX_INST: |
| 5044 | SSUBADDX_INST: | 5053 | SSUBADDX_INST: |
| @@ -5046,52 +5055,96 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 5046 | { | 5055 | { |
| 5047 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | 5056 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 5048 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; | 5057 | generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; |
| 5058 | const u8 op2 = inst_cream->op2; | ||
| 5049 | 5059 | ||
| 5050 | const s16 rn_lo = (RN & 0xFFFF); | 5060 | if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) { |
| 5051 | const s16 rn_hi = ((RN >> 16) & 0xFFFF); | 5061 | const s16 rn_lo = (RN & 0xFFFF); |
| 5052 | const s16 rm_lo = (RM & 0xFFFF); | 5062 | const s16 rn_hi = ((RN >> 16) & 0xFFFF); |
| 5053 | const s16 rm_hi = ((RM >> 16) & 0xFFFF); | 5063 | const s16 rm_lo = (RM & 0xFFFF); |
| 5064 | const s16 rm_hi = ((RM >> 16) & 0xFFFF); | ||
| 5054 | 5065 | ||
| 5055 | s32 lo_result = 0; | 5066 | s32 lo_result = 0; |
| 5056 | s32 hi_result = 0; | 5067 | s32 hi_result = 0; |
| 5057 | 5068 | ||
| 5058 | // SADD16 | 5069 | // SADD16 |
| 5059 | if (inst_cream->op2 == 0x00) { | 5070 | if (inst_cream->op2 == 0x00) { |
| 5060 | lo_result = (rn_lo + rm_lo); | 5071 | lo_result = (rn_lo + rm_lo); |
| 5061 | hi_result = (rn_hi + rm_hi); | 5072 | hi_result = (rn_hi + rm_hi); |
| 5062 | } | 5073 | } |
| 5063 | // SASX | 5074 | // SASX |
| 5064 | else if (inst_cream->op2 == 0x01) { | 5075 | else if (op2 == 0x01) { |
| 5065 | lo_result = (rn_lo - rm_hi); | 5076 | lo_result = (rn_lo - rm_hi); |
| 5066 | hi_result = (rn_hi + rm_lo); | 5077 | hi_result = (rn_hi + rm_lo); |
| 5067 | } | 5078 | } |
| 5068 | // SSAX | 5079 | // SSAX |
| 5069 | else if (inst_cream->op2 == 0x02) { | 5080 | else if (op2 == 0x02) { |
| 5070 | lo_result = (rn_lo + rm_hi); | 5081 | lo_result = (rn_lo + rm_hi); |
| 5071 | hi_result = (rn_hi - rm_lo); | 5082 | hi_result = (rn_hi - rm_lo); |
| 5072 | } | 5083 | } |
| 5073 | // SSUB16 | 5084 | // SSUB16 |
| 5074 | else if (inst_cream->op2 == 0x03) { | 5085 | else if (op2 == 0x03) { |
| 5075 | lo_result = (rn_lo - rm_lo); | 5086 | lo_result = (rn_lo - rm_lo); |
| 5076 | hi_result = (rn_hi - rm_hi); | 5087 | hi_result = (rn_hi - rm_hi); |
| 5077 | } | 5088 | } |
| 5078 | 5089 | ||
| 5079 | RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); | 5090 | RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); |
| 5080 | 5091 | ||
| 5081 | if (lo_result >= 0) { | 5092 | if (lo_result >= 0) { |
| 5082 | cpu->Cpsr |= (1 << 16); | 5093 | cpu->Cpsr |= (1 << 16); |
| 5083 | cpu->Cpsr |= (1 << 17); | 5094 | cpu->Cpsr |= (1 << 17); |
| 5084 | } else { | 5095 | } else { |
| 5085 | cpu->Cpsr &= ~(1 << 16); | 5096 | cpu->Cpsr &= ~(1 << 16); |
| 5086 | cpu->Cpsr &= ~(1 << 17); | 5097 | cpu->Cpsr &= ~(1 << 17); |
| 5098 | } | ||
| 5099 | |||
| 5100 | if (hi_result >= 0) { | ||
| 5101 | cpu->Cpsr |= (1 << 18); | ||
| 5102 | cpu->Cpsr |= (1 << 19); | ||
| 5103 | } else { | ||
| 5104 | cpu->Cpsr &= ~(1 << 18); | ||
| 5105 | cpu->Cpsr &= ~(1 << 19); | ||
| 5106 | } | ||
| 5087 | } | 5107 | } |
| 5108 | else if (op2 == 0x04 || op2 == 0x07) { | ||
| 5109 | s32 lo_val1, lo_val2; | ||
| 5110 | s32 hi_val1, hi_val2; | ||
| 5088 | 5111 | ||
| 5089 | if (hi_result >= 0) { | 5112 | // SADD8 |
| 5090 | cpu->Cpsr |= (1 << 18); | 5113 | if (op2 == 0x04) { |
| 5091 | cpu->Cpsr |= (1 << 19); | 5114 | lo_val1 = (s32)(s8)(RN & 0xFF) + (s32)(s8)(RM & 0xFF); |
| 5092 | } else { | 5115 | lo_val2 = (s32)(s8)((RN >> 8) & 0xFF) + (s32)(s8)((RM >> 8) & 0xFF); |
| 5093 | cpu->Cpsr &= ~(1 << 18); | 5116 | hi_val1 = (s32)(s8)((RN >> 16) & 0xFF) + (s32)(s8)((RM >> 16) & 0xFF); |
| 5094 | cpu->Cpsr &= ~(1 << 19); | 5117 | hi_val2 = (s32)(s8)((RN >> 24) & 0xFF) + (s32)(s8)((RM >> 24) & 0xFF); |
| 5118 | } | ||
| 5119 | // SSUB8 | ||
| 5120 | else { | ||
| 5121 | lo_val1 = (s32)(s8)(RN & 0xFF) - (s32)(s8)(RM & 0xFF); | ||
| 5122 | lo_val2 = (s32)(s8)((RN >> 8) & 0xFF) - (s32)(s8)((RM >> 8) & 0xFF); | ||
| 5123 | hi_val1 = (s32)(s8)((RN >> 16) & 0xFF) - (s32)(s8)((RM >> 16) & 0xFF); | ||
| 5124 | hi_val2 = (s32)(s8)((RN >> 24) & 0xFF) - (s32)(s8)((RM >> 24) & 0xFF); | ||
| 5125 | } | ||
| 5126 | |||
| 5127 | RD = ((lo_val1 & 0xFF) | ((lo_val2 & 0xFF) << 8) | ((hi_val1 & 0xFF) << 16) | ((hi_val2 & 0xFF) << 24)); | ||
| 5128 | |||
| 5129 | if (lo_val1 >= 0) | ||
| 5130 | cpu->Cpsr |= (1 << 16); | ||
| 5131 | else | ||
| 5132 | cpu->Cpsr &= ~(1 << 16); | ||
| 5133 | |||
| 5134 | if (lo_val2 >= 0) | ||
| 5135 | cpu->Cpsr |= (1 << 17); | ||
| 5136 | else | ||
| 5137 | cpu->Cpsr &= ~(1 << 17); | ||
| 5138 | |||
| 5139 | if (hi_val1 >= 0) | ||
| 5140 | cpu->Cpsr |= (1 << 18); | ||
| 5141 | else | ||
| 5142 | cpu->Cpsr &= ~(1 << 18); | ||
| 5143 | |||
| 5144 | if (hi_val2 >= 0) | ||
| 5145 | cpu->Cpsr |= (1 << 19); | ||
| 5146 | else | ||
| 5147 | cpu->Cpsr &= ~(1 << 19); | ||
| 5095 | } | 5148 | } |
| 5096 | } | 5149 | } |
| 5097 | 5150 | ||
| @@ -5407,7 +5460,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 5407 | FETCH_INST; | 5460 | FETCH_INST; |
| 5408 | GOTO_NEXT_INST; | 5461 | GOTO_NEXT_INST; |
| 5409 | } | 5462 | } |
| 5410 | SSUB8_INST: | 5463 | |
| 5411 | STC_INST: | 5464 | STC_INST: |
| 5412 | { | 5465 | { |
| 5413 | // Instruction not implemented | 5466 | // Instruction not implemented |