diff options
| author | 2014-12-26 23:40:15 -0500 | |
|---|---|---|
| committer | 2014-12-26 23:55:39 -0500 | |
| commit | 84a0438cf5cb6e367e16a6873fd3b36b4aa77b21 (patch) | |
| tree | 0d43b8bc44ec9ebec7bbdab13a9dfb38aca69f9a /src/core/arm/interpreter/armemu.cpp | |
| parent | Merge pull request #339 from bunnei/fixup-gsp-synch (diff) | |
| download | yuzu-84a0438cf5cb6e367e16a6873fd3b36b4aa77b21.tar.gz yuzu-84a0438cf5cb6e367e16a6873fd3b36b4aa77b21.tar.xz yuzu-84a0438cf5cb6e367e16a6873fd3b36b4aa77b21.zip | |
armemu: Implement UHADD8, UHADD16, UHSUB8, UHSUB16, UHASX, and UHSAX
Diffstat (limited to 'src/core/arm/interpreter/armemu.cpp')
| -rw-r--r-- | src/core/arm/interpreter/armemu.cpp | 75 |
1 files changed, 73 insertions, 2 deletions
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp index d54dbeac5..9b680c1e2 100644 --- a/src/core/arm/interpreter/armemu.cpp +++ b/src/core/arm/interpreter/armemu.cpp | |||
| @@ -6139,8 +6139,79 @@ L_stm_s_takeabort: | |||
| 6139 | printf ("Unhandled v6 insn: uqsub16\n"); | 6139 | printf ("Unhandled v6 insn: uqsub16\n"); |
| 6140 | } | 6140 | } |
| 6141 | break; | 6141 | break; |
| 6142 | case 0x67: | 6142 | case 0x67: // UHADD16, UHASX, UHSAX, UHSUB16, UHADD8, and UHSUB8. |
| 6143 | printf ("Unhandled v6 insn: uhadd/uhsub\n"); | 6143 | { |
| 6144 | const u8 op2 = BITS(5, 7); | ||
| 6145 | |||
| 6146 | const u8 rm_idx = BITS(0, 3); | ||
| 6147 | const u8 rn_idx = BITS(16, 19); | ||
| 6148 | const u8 rd_idx = BITS(12, 15); | ||
| 6149 | |||
| 6150 | const u32 rm_val = state->Reg[rm_idx]; | ||
| 6151 | const u32 rn_val = state->Reg[rn_idx]; | ||
| 6152 | |||
| 6153 | if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) | ||
| 6154 | { | ||
| 6155 | u32 lo_val = 0; | ||
| 6156 | u32 hi_val = 0; | ||
| 6157 | |||
| 6158 | // UHADD16 | ||
| 6159 | if (op2 == 0x00) { | ||
| 6160 | lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF); | ||
| 6161 | hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); | ||
| 6162 | } | ||
| 6163 | // UHASX | ||
| 6164 | else if (op2 == 0x01) { | ||
| 6165 | lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); | ||
| 6166 | hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF); | ||
| 6167 | } | ||
| 6168 | // UHSAX | ||
| 6169 | else if (op2 == 0x02) { | ||
| 6170 | lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); | ||
| 6171 | hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF); | ||
| 6172 | } | ||
| 6173 | // UHSUB16 | ||
| 6174 | else if (op2 == 0x03) { | ||
| 6175 | lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF); | ||
| 6176 | hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); | ||
| 6177 | } | ||
| 6178 | |||
| 6179 | lo_val >>= 1; | ||
| 6180 | hi_val >>= 1; | ||
| 6181 | |||
| 6182 | state->Reg[rd_idx] = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16); | ||
| 6183 | return 1; | ||
| 6184 | } | ||
| 6185 | else if (op2 == 0x04 || op2 == 0x07) { | ||
| 6186 | u32 sum1; | ||
| 6187 | u32 sum2; | ||
| 6188 | u32 sum3; | ||
| 6189 | u32 sum4; | ||
| 6190 | |||
| 6191 | // UHADD8 | ||
| 6192 | if (op2 == 0x04) { | ||
| 6193 | sum1 = (rn_val & 0xFF) + (rm_val & 0xFF); | ||
| 6194 | sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF); | ||
| 6195 | sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF); | ||
| 6196 | sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF); | ||
| 6197 | } | ||
| 6198 | // UHSUB8 | ||
| 6199 | else { | ||
| 6200 | sum1 = (rn_val & 0xFF) - (rm_val & 0xFF); | ||
| 6201 | sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF); | ||
| 6202 | sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF); | ||
| 6203 | sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF); | ||
| 6204 | } | ||
| 6205 | |||
| 6206 | sum1 >>= 1; | ||
| 6207 | sum2 >>= 1; | ||
| 6208 | sum3 >>= 1; | ||
| 6209 | sum4 >>= 1; | ||
| 6210 | |||
| 6211 | state->Reg[rd_idx] = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) | ((sum4 & 0xFF) << 24); | ||
| 6212 | return 1; | ||
| 6213 | } | ||
| 6214 | } | ||
| 6144 | break; | 6215 | break; |
| 6145 | case 0x68: | 6216 | case 0x68: |
| 6146 | { | 6217 | { |