summaryrefslogtreecommitdiff
path: root/src/core/arm/interpreter/armemu.cpp
diff options
context:
space:
mode:
authorGravatar Lioncash2014-12-16 01:59:46 -0500
committerGravatar Lioncash2014-12-16 03:11:50 -0500
commit0f9e3baf39efdfe8a6604a473405764e936a897d (patch)
treef620875912de288938e619b05f45568eaafb66d4 /src/core/arm/interpreter/armemu.cpp
parentMerge pull request #281 from lioncash/uxtb16 (diff)
downloadyuzu-0f9e3baf39efdfe8a6604a473405764e936a897d.tar.gz
yuzu-0f9e3baf39efdfe8a6604a473405764e936a897d.tar.xz
yuzu-0f9e3baf39efdfe8a6604a473405764e936a897d.zip
armemu: Join SMUAD, SMUSD, and SMLAD
Diffstat (limited to 'src/core/arm/interpreter/armemu.cpp')
-rw-r--r--src/core/arm/interpreter/armemu.cpp73
1 files changed, 35 insertions, 38 deletions
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index 33ebc7986..967506f45 100644
--- a/src/core/arm/interpreter/armemu.cpp
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -6222,45 +6222,42 @@ L_stm_s_takeabort:
6222 return 1; 6222 return 1;
6223 } 6223 }
6224 case 0x70: 6224 case 0x70:
6225 if ((instr & 0xf0d0) == 0xf010) { //smuad //ichfly 6225 // ichfly
6226 u8 tar = BITS(16, 19); 6226 // SMUAD, SMUSD, SMLAD
6227 u8 src1 = BITS(0, 3); 6227 if ((instr & 0xf0d0) == 0xf010 || (instr & 0xf0d0) == 0xf050 || (instr & 0xd0) == 0x10) {
6228 u8 src2 = BITS(8, 11); 6228 const u8 rd_idx = BITS(16, 19);
6229 u8 swap = BIT(5); 6229 const u8 rn_idx = BITS(0, 3);
6230 s16 a1 = (state->Reg[src1] & 0xFFFF); 6230 const u8 rm_idx = BITS(8, 11);
6231 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); 6231 const bool do_swap = (BIT(5) == 1);
6232 s16 b1 = swap ? ((state->Reg[src2] >> 0x10) & 0xFFFF) : (state->Reg[src2] & 0xFFFF); 6232
6233 s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF); 6233 u32 rm_val = state->Reg[rm_idx];
6234 state->Reg[tar] = a1*a2 + b1*b2; 6234 const u32 rn_val = state->Reg[rn_idx];
6235 return 1; 6235
6236 6236 if (do_swap)
6237 } else if ((instr & 0xf0d0) == 0xf050) { //smusd 6237 rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16));
6238 u8 tar = BITS(16, 19); 6238
6239 u8 src1 = BITS(0, 3); 6239 const s16 rm_lo = (rm_val & 0xFFFF);
6240 u8 src2 = BITS(8, 11); 6240 const s16 rm_hi = ((rm_val >> 16) & 0xFFFF);
6241 u8 swap = BIT(5); 6241 const s16 rn_lo = (rn_val & 0xFFFF);
6242 s16 a1 = (state->Reg[src1] & 0xFFFF); 6242 const s16 rn_hi = ((rn_val >> 16) & 0xFFFF);
6243 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); 6243
6244 s16 b1 = swap ? ((state->Reg[src2] >> 0x10) & 0xFFFF) : (state->Reg[src2] & 0xFFFF); 6244 // SMUAD
6245 s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF); 6245 if ((instr & 0xf0d0) == 0xf010) {
6246 state->Reg[tar] = a1*a2 - b1*b2; 6246 state->Reg[rd_idx] = (rn_lo * rn_hi) + (rm_lo * rm_hi);
6247 return 1; 6247 }
6248 } else if ((instr & 0xd0) == 0x10) { //smlad 6248 // SMUSD
6249 u8 tar = BITS(16, 19); 6249 else if ((instr & 0xf0d0) == 0xf050) {
6250 u8 src1 = BITS(0, 3); 6250 state->Reg[rd_idx] = (rn_lo * rn_hi) - (rm_lo * rm_hi);
6251 u8 src2 = BITS(8, 11); 6251 }
6252 u8 src3 = BITS(12, 15); 6252 // SMLAD
6253 u8 swap = BIT(5); 6253 else {
6254 6254 const u8 ra_idx = BITS(12, 15);
6255 u32 a3 = state->Reg[src3]; 6255 state->Reg[rd_idx] = (rn_lo * rn_hi) + (rm_lo * rm_hi) + (s32)state->Reg[ra_idx];
6256 6256 }
6257 s16 a1 = (state->Reg[src1] & 0xFFFF);
6258 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
6259 s16 b1 = swap ? ((state->Reg[src2] >> 0x10) & 0xFFFF) : (state->Reg[src2] & 0xFFFF);
6260 s16 b2 = swap ? (state->Reg[src2] & 0xFFFF) : ((state->Reg[src2] >> 0x10) & 0xFFFF);
6261 state->Reg[tar] = a1*a2 + b1*b2 + a3;
6262 return 1; 6257 return 1;
6263 } else printf ("Unhandled v6 insn: smuad/smusd/smlad/smlsd\n"); 6258 } else {
6259 printf ("Unhandled v6 insn: smlsd\n");
6260 }
6264 break; 6261 break;
6265 case 0x74: 6262 case 0x74:
6266 printf ("Unhandled v6 insn: smlald/smlsld\n"); 6263 printf ("Unhandled v6 insn: smlald/smlsld\n");