summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Lioncash2014-12-28 11:56:16 -0500
committerGravatar Lioncash2014-12-28 11:57:14 -0500
commit914ecfe04fa21d9370491318373a7c34fe4a79af (patch)
tree0b05ef1d2c9b05daf6f4620d3e680354245a8a70 /src/core
parentarmemu: Simplify REVSH/UXTH/UXTAH (diff)
downloadyuzu-914ecfe04fa21d9370491318373a7c34fe4a79af.tar.gz
yuzu-914ecfe04fa21d9370491318373a7c34fe4a79af.tar.xz
yuzu-914ecfe04fa21d9370491318373a7c34fe4a79af.zip
armemu: Simplify USAT16/UXTB/UXTAB
Diffstat (limited to 'src/core')
-rw-r--r--src/core/arm/interpreter/armemu.cpp107
1 files changed, 42 insertions, 65 deletions
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index a955d6aac..dcc0acafe 100644
--- a/src/core/arm/interpreter/armemu.cpp
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -6422,79 +6422,56 @@ L_stm_s_takeabort:
6422 return 1; 6422 return 1;
6423 } 6423 }
6424 break; 6424 break;
6425 case 0x6e: { 6425 case 0x6e: // USAT, USAT16, UXTB, and UXTAB
6426 ARMword Rm; 6426 {
6427 int ror = -1; 6427 const u8 op2 = BITS(5, 7);
6428
6429 switch (BITS(4, 11)) {
6430 case 0x07:
6431 ror = 0;
6432 break;
6433 case 0x47:
6434 ror = 8;
6435 break;
6436 case 0x87:
6437 ror = 16;
6438 break;
6439 case 0xc7:
6440 ror = 24;
6441 break;
6442
6443 case 0x01:
6444 case 0xf3:
6445 //ichfly
6446 //USAT16
6447 {
6448 const u8 rd_idx = BITS(12, 15);
6449 const u8 rn_idx = BITS(0, 3);
6450 const u8 num_bits = BITS(16, 19);
6451 const s16 max = 0xFFFF >> (16 - num_bits);
6452 s16 rn_lo = (state->Reg[rn_idx]);
6453 s16 rn_hi = (state->Reg[rn_idx] >> 16);
6454
6455 if (max < rn_lo) {
6456 rn_lo = max;
6457 SETQ;
6458 } else if (rn_lo < 0) {
6459 rn_lo = 0;
6460 SETQ;
6461 }
6462
6463 if (max < rn_hi) {
6464 rn_hi = max;
6465 SETQ;
6466 } else if (rn_hi < 0) {
6467 rn_hi = 0;
6468 SETQ;
6469 }
6470 6428
6471 state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi << 16) & 0xFFFF); 6429 // USAT16
6472 return 1; 6430 if (op2 == 0x01) {
6431 const u8 rd_idx = BITS(12, 15);
6432 const u8 rn_idx = BITS(0, 3);
6433 const u8 num_bits = BITS(16, 19);
6434 const s16 max = 0xFFFF >> (16 - num_bits);
6435 s16 rn_lo = (state->Reg[rn_idx]);
6436 s16 rn_hi = (state->Reg[rn_idx] >> 16);
6437
6438 if (max < rn_lo) {
6439 rn_lo = max;
6440 SETQ;
6441 } else if (rn_lo < 0) {
6442 rn_lo = 0;
6443 SETQ;
6473 } 6444 }
6474 6445
6475 default: 6446 if (max < rn_hi) {
6476 break; 6447 rn_hi = max;
6477 } 6448 SETQ;
6478 6449 } else if (rn_hi < 0) {
6479 if (ror == -1) { 6450 rn_hi = 0;
6480 if (BITS(4, 6) == 0x7) { 6451 SETQ;
6481 printf("Unhandled v6 insn: usat\n");
6482 return 0;
6483 } 6452 }
6484 break; 6453
6454 state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi << 16) & 0xFFFF);
6455 return 1;
6485 } 6456 }
6486 6457 else if (op2 == 0x03) {
6487 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFF) & 0xFF); 6458 const u8 rotate = BITS(10, 11) * 8;
6488 6459 const u32 rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFF) & 0xFF);
6489 if (BITS(16, 19) == 0xf) 6460
6461 if (BITS(16, 19) == 0xf)
6490 /* UXTB */ 6462 /* UXTB */
6491 state->Reg[BITS(12, 15)] = Rm; 6463 state->Reg[BITS(12, 15)] = rm;
6492 else 6464 else
6493 /* UXTAB */ 6465 /* UXTAB */
6494 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + Rm; 6466 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
6495 6467
6496 return 1; 6468 return 1;
6469 }
6470 else {
6471 printf("Unimplemented op: USAT");
6472 }
6497 } 6473 }
6474 break;
6498 6475
6499 case 0x6f: // UXTH, UXTAH, and REVSH. 6476 case 0x6f: // UXTH, UXTAH, and REVSH.
6500 { 6477 {