summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2014-12-28 22:20:49 -0500
committerGravatar bunnei2014-12-28 22:20:49 -0500
commitdf728cb4c219ab8932983a7294ace50ccdba92d5 (patch)
treed31896af130f4e8fb38328ccf7d63a41031d835c
parentMerge pull request #352 from xdec/PR_XDEC_172 (diff)
parentarmemu: Simplify SSAT/SSAT16/SXTB/SXTAB (diff)
downloadyuzu-df728cb4c219ab8932983a7294ace50ccdba92d5.tar.gz
yuzu-df728cb4c219ab8932983a7294ace50ccdba92d5.tar.xz
yuzu-df728cb4c219ab8932983a7294ace50ccdba92d5.zip
Merge pull request #355 from lioncash/simp
armemu: Simplify some instructions.
-rw-r--r--src/core/arm/interpreter/armemu.cpp367
1 files changed, 142 insertions, 225 deletions
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index 9c6602f09..f0d349de7 100644
--- a/src/core/arm/interpreter/armemu.cpp
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -6264,129 +6264,94 @@ L_stm_s_takeabort:
6264 return 1; 6264 return 1;
6265 } 6265 }
6266 } 6266 }
6267 printf("Unhandled v6 insn: pkh/sxtab/selsxtb\n"); 6267 printf("Unhandled v6 insn: pkh/sxtab/selsxtb\n");
6268 break; 6268 break;
6269 case 0x6a: {
6270 ARMword Rm;
6271 int ror = -1;
6272
6273 switch (BITS(4, 11)) {
6274 case 0x07:
6275 ror = 0;
6276 break;
6277 case 0x47:
6278 ror = 8;
6279 break;
6280 case 0x87:
6281 ror = 16;
6282 break;
6283 case 0xc7:
6284 ror = 24;
6285 break;
6286
6287 case 0x01:
6288 case 0xf3:
6289 //ichfly
6290 //SSAT16
6291 {
6292 const u8 rd_idx = BITS(12, 15);
6293 const u8 rn_idx = BITS(0, 3);
6294 const u8 num_bits = BITS(16, 19) + 1;
6295 const s16 min = -(0x8000 >> (16 - num_bits));
6296 const s16 max = (0x7FFF >> (16 - num_bits));
6297 s16 rn_lo = (state->Reg[rn_idx]);
6298 s16 rn_hi = (state->Reg[rn_idx] >> 16);
6299
6300 if (rn_lo > max) {
6301 rn_lo = max;
6302 SETQ;
6303 } else if (rn_lo < min) {
6304 rn_lo = min;
6305 SETQ;
6306 }
6307
6308 if (rn_hi > max) {
6309 rn_hi = max;
6310 SETQ;
6311 } else if (rn_hi < min) {
6312 rn_hi = min;
6313 SETQ;
6314 }
6315
6316 state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi & 0xFFFF) << 16);
6317 return 1;
6318 }
6319 6269
6320 default: 6270 case 0x6a: // SSAT, SSAT16, SXTB, and SXTAB
6321 break; 6271 {
6322 } 6272 const u8 op2 = BITS(5, 7);
6323 6273
6324 if (ror == -1) { 6274 // SSAT16
6325 if (BITS(4, 6) == 0x7) { 6275 if (op2 == 0x01) {
6326 printf("Unhandled v6 insn: ssat\n"); 6276 const u8 rd_idx = BITS(12, 15);
6327 return 0; 6277 const u8 rn_idx = BITS(0, 3);
6278 const u8 num_bits = BITS(16, 19) + 1;
6279 const s16 min = -(0x8000 >> (16 - num_bits));
6280 const s16 max = (0x7FFF >> (16 - num_bits));
6281 s16 rn_lo = (state->Reg[rn_idx]);
6282 s16 rn_hi = (state->Reg[rn_idx] >> 16);
6283
6284 if (rn_lo > max) {
6285 rn_lo = max;
6286 SETQ;
6287 } else if (rn_lo < min) {
6288 rn_lo = min;
6289 SETQ;
6328 } 6290 }
6329 break;
6330 }
6331 6291
6332 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFF) & 0xFF); 6292 if (rn_hi > max) {
6333 if (Rm & 0x80) 6293 rn_hi = max;
6334 Rm |= 0xffffff00; 6294 SETQ;
6295 } else if (rn_hi < min) {
6296 rn_hi = min;
6297 SETQ;
6298 }
6335 6299
6336 if (BITS(16, 19) == 0xf) 6300 state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi & 0xFFFF) << 16);
6337 /* SXTB */ 6301 return 1;
6338 state->Reg[BITS(12, 15)] = Rm; 6302 }
6339 else 6303 else if (op2 == 0x03) {
6340 /* SXTAB */ 6304 const u8 rotation = BITS(10, 11) * 8;
6341 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + Rm; 6305 u32 rm = ((state->Reg[BITS(0, 3)] >> rotation) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - rotation)) & 0xFF) & 0xFF);
6306 if (rm & 0x80)
6307 rm |= 0xffffff00;
6308
6309 // SXTB, otherwise SXTAB
6310 if (BITS(16, 19) == 0xf)
6311 state->Reg[BITS(12, 15)] = rm;
6312 else
6313 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
6342 6314
6343 return 1; 6315 return 1;
6316 }
6317 else {
6318 printf("Unimplemented op: SSAT");
6319 }
6344 } 6320 }
6345 case 0x6b: 6321 break;
6322
6323 case 0x6b: // REV, REV16, SXTH, and SXTAH
6346 { 6324 {
6347 ARMword Rm; 6325 const u8 op2 = BITS(5, 7);
6348 int ror = -1;
6349
6350 switch (BITS(4, 11)) {
6351 case 0x07:
6352 ror = 0;
6353 break;
6354 case 0x47:
6355 ror = 8;
6356 break;
6357 case 0x87:
6358 ror = 16;
6359 break;
6360 case 0xc7:
6361 ror = 24;
6362 break;
6363
6364 case 0xf3: // REV
6365 DEST = ((RHS & 0xFF) << 24) | ((RHS & 0xFF00)) << 8 | ((RHS & 0xFF0000) >> 8) | ((RHS & 0xFF000000) >> 24);
6366 return 1;
6367 case 0xfb: // REV16
6368 DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00)) >> 8 | ((RHS & 0xFF0000) << 8) | ((RHS & 0xFF000000) >> 8);
6369 return 1;
6370 default:
6371 break;
6372 }
6373 6326
6374 if (ror == -1) 6327 // REV
6375 break; 6328 if (op2 == 0x01) {
6329 DEST = ((RHS & 0xFF) << 24) | ((RHS & 0xFF00)) << 8 | ((RHS & 0xFF0000) >> 8) | ((RHS & 0xFF000000) >> 24);
6330 return 1;
6331 }
6332 // REV16
6333 else if (op2 == 0x05) {
6334 DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00)) >> 8 | ((RHS & 0xFF0000) << 8) | ((RHS & 0xFF000000) >> 8);
6335 return 1;
6336 }
6337 else if (op2 == 0x03) {
6338 const u8 rotate = BITS(10, 11) * 8;
6376 6339
6377 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFFFF) & 0xFFFF); 6340 u32 rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFFFF) & 0xFFFF);
6378 if (Rm & 0x8000) 6341 if (rm & 0x8000)
6379 Rm |= 0xffff0000; 6342 rm |= 0xffff0000;
6380 6343
6381 if (BITS(16, 19) == 0xf) 6344 // SXTH, otherwise SXTAH
6382 /* SXTH */ 6345 if (BITS(16, 19) == 15)
6383 state->Reg[BITS(12, 15)] = Rm; 6346 state->Reg[BITS(12, 15)] = rm;
6384 else 6347 else
6385 /* SXTAH */ 6348 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
6386 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + Rm;
6387 6349
6388 return 1; 6350 return 1;
6351 }
6389 } 6352 }
6353 break;
6354
6390 case 0x6c: // UXTB16 and UXTAB16 6355 case 0x6c: // UXTB16 and UXTAB16
6391 { 6356 {
6392 const u8 rm_idx = BITS(0, 3); 6357 const u8 rm_idx = BITS(0, 3);
@@ -6414,132 +6379,84 @@ L_stm_s_takeabort:
6414 return 1; 6379 return 1;
6415 } 6380 }
6416 break; 6381 break;
6417 case 0x6e: { 6382 case 0x6e: // USAT, USAT16, UXTB, and UXTAB
6418 ARMword Rm; 6383 {
6419 int ror = -1; 6384 const u8 op2 = BITS(5, 7);
6420
6421 switch (BITS(4, 11)) {
6422 case 0x07:
6423 ror = 0;
6424 break;
6425 case 0x47:
6426 ror = 8;
6427 break;
6428 case 0x87:
6429 ror = 16;
6430 break;
6431 case 0xc7:
6432 ror = 24;
6433 break;
6434
6435 case 0x01:
6436 case 0xf3:
6437 //ichfly
6438 //USAT16
6439 {
6440 const u8 rd_idx = BITS(12, 15);
6441 const u8 rn_idx = BITS(0, 3);
6442 const u8 num_bits = BITS(16, 19);
6443 const s16 max = 0xFFFF >> (16 - num_bits);
6444 s16 rn_lo = (state->Reg[rn_idx]);
6445 s16 rn_hi = (state->Reg[rn_idx] >> 16);
6446
6447 if (max < rn_lo) {
6448 rn_lo = max;
6449 SETQ;
6450 } else if (rn_lo < 0) {
6451 rn_lo = 0;
6452 SETQ;
6453 }
6454
6455 if (max < rn_hi) {
6456 rn_hi = max;
6457 SETQ;
6458 } else if (rn_hi < 0) {
6459 rn_hi = 0;
6460 SETQ;
6461 }
6462
6463 state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi << 16) & 0xFFFF);
6464 return 1;
6465 }
6466
6467 default:
6468 break;
6469 }
6470 6385
6471 if (ror == -1) { 6386 // USAT16
6472 if (BITS(4, 6) == 0x7) { 6387 if (op2 == 0x01) {
6473 printf("Unhandled v6 insn: usat\n"); 6388 const u8 rd_idx = BITS(12, 15);
6474 return 0; 6389 const u8 rn_idx = BITS(0, 3);
6390 const u8 num_bits = BITS(16, 19);
6391 const s16 max = 0xFFFF >> (16 - num_bits);
6392 s16 rn_lo = (state->Reg[rn_idx]);
6393 s16 rn_hi = (state->Reg[rn_idx] >> 16);
6394
6395 if (max < rn_lo) {
6396 rn_lo = max;
6397 SETQ;
6398 } else if (rn_lo < 0) {
6399 rn_lo = 0;
6400 SETQ;
6475 } 6401 }
6476 break; 6402
6403 if (max < rn_hi) {
6404 rn_hi = max;
6405 SETQ;
6406 } else if (rn_hi < 0) {
6407 rn_hi = 0;
6408 SETQ;
6409 }
6410
6411 state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi << 16) & 0xFFFF);
6412 return 1;
6477 } 6413 }
6478 6414 else if (op2 == 0x03) {
6479 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFF) & 0xFF); 6415 const u8 rotate = BITS(10, 11) * 8;
6480 6416 const u32 rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFF) & 0xFF);
6481 if (BITS(16, 19) == 0xf) 6417
6418 if (BITS(16, 19) == 0xf)
6482 /* UXTB */ 6419 /* UXTB */
6483 state->Reg[BITS(12, 15)] = Rm; 6420 state->Reg[BITS(12, 15)] = rm;
6484 else 6421 else
6485 /* UXTAB */ 6422 /* UXTAB */
6486 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + Rm; 6423 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
6487
6488 return 1;
6489 }
6490 6424
6491 case 0x6f: { 6425 return 1;
6492 ARMword Rm;
6493 int ror = -1;
6494
6495 switch (BITS(4, 11)) {
6496 case 0x07:
6497 ror = 0;
6498 break;
6499 case 0x47:
6500 ror = 8;
6501 break;
6502 case 0x87:
6503 ror = 16;
6504 break;
6505 case 0xc7:
6506 ror = 24;
6507 break;
6508
6509 case 0xfb: // REVSH
6510 {
6511 DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00) >> 8);
6512 if (DEST & 0x8000)
6513 DEST |= 0xffff0000;
6514 return 1;
6515 }
6516 default:
6517 break;
6518 } 6426 }
6427 else {
6428 printf("Unimplemented op: USAT");
6429 }
6430 }
6431 break;
6519 6432
6520 if (ror == -1) 6433 case 0x6f: // UXTH, UXTAH, and REVSH.
6521 break; 6434 {
6522 6435 const u8 op2 = BITS(5, 7);
6523 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFFFF) & 0xFFFF);
6524 6436
6525 /* UXT */ 6437 // REVSH
6526 /* state->Reg[BITS (12, 15)] = Rm; */ 6438 if (op2 == 0x05) {
6527 /* dyf add */ 6439 DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00) >> 8);
6528 if (BITS(16, 19) == 0xf) { 6440 if (DEST & 0x8000)
6529 state->Reg[BITS(12, 15)] = Rm; 6441 DEST |= 0xffff0000;
6530 } 6442 return 1;
6531 else {
6532 /* UXTAH */
6533 /* state->Reg[BITS (12, 15)] = state->Reg [BITS (16, 19)] + Rm; */
6534 // printf("rd is %x rn is %x rm is %x rotate is %x\n", state->Reg[BITS (12, 15)], state->Reg[BITS (16, 19)]
6535 // , Rm, BITS(10, 11));
6536 // printf("icounter is %lld\n", state->NumInstrs);
6537 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + Rm;
6538 // printf("rd is %x\n", state->Reg[BITS (12, 15)]);
6539 // exit(-1);
6540 } 6443 }
6444 // UXTH and UXTAH
6445 else if (op2 == 0x03) {
6446 const u8 rotate = BITS(10, 11) * 8;
6447 const ARMword rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFFFF) & 0xFFFF);
6448
6449 // UXTH
6450 if (BITS(16, 19) == 0xf) {
6451 state->Reg[BITS(12, 15)] = rm;
6452 }
6453 // UXTAH
6454 else {
6455 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
6456 }
6541 6457
6542 return 1; 6458 return 1;
6459 }
6543 } 6460 }
6544 case 0x70: 6461 case 0x70:
6545 // ichfly 6462 // ichfly