Commit 1e8d4eec4859574e7773fa3243fcc61fe7b534e7
1 parent
88920f34
more complete ARM shift fix
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1168 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
70 additions
and
7 deletions
target-arm/op.c
| @@ -463,6 +463,7 @@ void OPPROTO op_swpl_T0_T1(void) | @@ -463,6 +463,7 @@ void OPPROTO op_swpl_T0_T1(void) | ||
| 463 | /* shifts */ | 463 | /* shifts */ |
| 464 | 464 | ||
| 465 | /* T1 based */ | 465 | /* T1 based */ |
| 466 | + | ||
| 466 | void OPPROTO op_shll_T1_im(void) | 467 | void OPPROTO op_shll_T1_im(void) |
| 467 | { | 468 | { |
| 468 | T1 = T1 << PARAM1; | 469 | T1 = T1 << PARAM1; |
| @@ -473,11 +474,21 @@ void OPPROTO op_shrl_T1_im(void) | @@ -473,11 +474,21 @@ void OPPROTO op_shrl_T1_im(void) | ||
| 473 | T1 = (uint32_t)T1 >> PARAM1; | 474 | T1 = (uint32_t)T1 >> PARAM1; |
| 474 | } | 475 | } |
| 475 | 476 | ||
| 477 | +void OPPROTO op_shrl_T1_0(void) | ||
| 478 | +{ | ||
| 479 | + T1 = 0; | ||
| 480 | +} | ||
| 481 | + | ||
| 476 | void OPPROTO op_sarl_T1_im(void) | 482 | void OPPROTO op_sarl_T1_im(void) |
| 477 | { | 483 | { |
| 478 | T1 = (int32_t)T1 >> PARAM1; | 484 | T1 = (int32_t)T1 >> PARAM1; |
| 479 | } | 485 | } |
| 480 | 486 | ||
| 487 | +void OPPROTO op_sarl_T1_0(void) | ||
| 488 | +{ | ||
| 489 | + T1 = (int32_t)T1 >> 31; | ||
| 490 | +} | ||
| 491 | + | ||
| 481 | void OPPROTO op_rorl_T1_im(void) | 492 | void OPPROTO op_rorl_T1_im(void) |
| 482 | { | 493 | { |
| 483 | int shift; | 494 | int shift; |
| @@ -503,12 +514,24 @@ void OPPROTO op_shrl_T1_im_cc(void) | @@ -503,12 +514,24 @@ void OPPROTO op_shrl_T1_im_cc(void) | ||
| 503 | T1 = (uint32_t)T1 >> PARAM1; | 514 | T1 = (uint32_t)T1 >> PARAM1; |
| 504 | } | 515 | } |
| 505 | 516 | ||
| 517 | +void OPPROTO op_shrl_T1_0_cc(void) | ||
| 518 | +{ | ||
| 519 | + env->CF = (T1 >> 31) & 1; | ||
| 520 | + T1 = 0; | ||
| 521 | +} | ||
| 522 | + | ||
| 506 | void OPPROTO op_sarl_T1_im_cc(void) | 523 | void OPPROTO op_sarl_T1_im_cc(void) |
| 507 | { | 524 | { |
| 508 | env->CF = (T1 >> (PARAM1 - 1)) & 1; | 525 | env->CF = (T1 >> (PARAM1 - 1)) & 1; |
| 509 | T1 = (int32_t)T1 >> PARAM1; | 526 | T1 = (int32_t)T1 >> PARAM1; |
| 510 | } | 527 | } |
| 511 | 528 | ||
| 529 | +void OPPROTO op_sarl_T1_0_cc(void) | ||
| 530 | +{ | ||
| 531 | + env->CF = (T1 >> 31) & 1; | ||
| 532 | + T1 = (int32_t)T1 >> 31; | ||
| 533 | +} | ||
| 534 | + | ||
| 512 | void OPPROTO op_rorl_T1_im_cc(void) | 535 | void OPPROTO op_rorl_T1_im_cc(void) |
| 513 | { | 536 | { |
| 514 | int shift; | 537 | int shift; |
| @@ -536,11 +559,21 @@ void OPPROTO op_shrl_T2_im(void) | @@ -536,11 +559,21 @@ void OPPROTO op_shrl_T2_im(void) | ||
| 536 | T2 = (uint32_t)T2 >> PARAM1; | 559 | T2 = (uint32_t)T2 >> PARAM1; |
| 537 | } | 560 | } |
| 538 | 561 | ||
| 562 | +void OPPROTO op_shrl_T2_0(void) | ||
| 563 | +{ | ||
| 564 | + T2 = 0; | ||
| 565 | +} | ||
| 566 | + | ||
| 539 | void OPPROTO op_sarl_T2_im(void) | 567 | void OPPROTO op_sarl_T2_im(void) |
| 540 | { | 568 | { |
| 541 | T2 = (int32_t)T2 >> PARAM1; | 569 | T2 = (int32_t)T2 >> PARAM1; |
| 542 | } | 570 | } |
| 543 | 571 | ||
| 572 | +void OPPROTO op_sarl_T2_0(void) | ||
| 573 | +{ | ||
| 574 | + T2 = (int32_t)T2 >> 31; | ||
| 575 | +} | ||
| 576 | + | ||
| 544 | void OPPROTO op_rorl_T2_im(void) | 577 | void OPPROTO op_rorl_T2_im(void) |
| 545 | { | 578 | { |
| 546 | int shift; | 579 | int shift; |
| @@ -548,6 +581,11 @@ void OPPROTO op_rorl_T2_im(void) | @@ -548,6 +581,11 @@ void OPPROTO op_rorl_T2_im(void) | ||
| 548 | T2 = ((uint32_t)T2 >> shift) | (T2 << (32 - shift)); | 581 | T2 = ((uint32_t)T2 >> shift) | (T2 << (32 - shift)); |
| 549 | } | 582 | } |
| 550 | 583 | ||
| 584 | +void OPPROTO op_rrxl_T2(void) | ||
| 585 | +{ | ||
| 586 | + T2 = ((uint32_t)T2 >> 1) | ((uint32_t)env->CF << 31); | ||
| 587 | +} | ||
| 588 | + | ||
| 551 | /* T1 based, use T0 as shift count */ | 589 | /* T1 based, use T0 as shift count */ |
| 552 | 590 | ||
| 553 | void OPPROTO op_shll_T1_T0(void) | 591 | void OPPROTO op_shll_T1_T0(void) |
target-arm/translate.c
| @@ -94,6 +94,13 @@ static GenOpFunc1 *gen_shift_T1_im[4] = { | @@ -94,6 +94,13 @@ static GenOpFunc1 *gen_shift_T1_im[4] = { | ||
| 94 | gen_op_rorl_T1_im, | 94 | gen_op_rorl_T1_im, |
| 95 | }; | 95 | }; |
| 96 | 96 | ||
| 97 | +static GenOpFunc *gen_shift_T1_0[4] = { | ||
| 98 | + NULL, | ||
| 99 | + gen_op_shrl_T1_0, | ||
| 100 | + gen_op_sarl_T1_0, | ||
| 101 | + gen_op_rrxl_T1, | ||
| 102 | +}; | ||
| 103 | + | ||
| 97 | static GenOpFunc1 *gen_shift_T2_im[4] = { | 104 | static GenOpFunc1 *gen_shift_T2_im[4] = { |
| 98 | gen_op_shll_T2_im, | 105 | gen_op_shll_T2_im, |
| 99 | gen_op_shrl_T2_im, | 106 | gen_op_shrl_T2_im, |
| @@ -101,6 +108,13 @@ static GenOpFunc1 *gen_shift_T2_im[4] = { | @@ -101,6 +108,13 @@ static GenOpFunc1 *gen_shift_T2_im[4] = { | ||
| 101 | gen_op_rorl_T2_im, | 108 | gen_op_rorl_T2_im, |
| 102 | }; | 109 | }; |
| 103 | 110 | ||
| 111 | +static GenOpFunc *gen_shift_T2_0[4] = { | ||
| 112 | + NULL, | ||
| 113 | + gen_op_shrl_T2_0, | ||
| 114 | + gen_op_sarl_T2_0, | ||
| 115 | + gen_op_rrxl_T2, | ||
| 116 | +}; | ||
| 117 | + | ||
| 104 | static GenOpFunc1 *gen_shift_T1_im_cc[4] = { | 118 | static GenOpFunc1 *gen_shift_T1_im_cc[4] = { |
| 105 | gen_op_shll_T1_im_cc, | 119 | gen_op_shll_T1_im_cc, |
| 106 | gen_op_shrl_T1_im_cc, | 120 | gen_op_shrl_T1_im_cc, |
| @@ -108,6 +122,13 @@ static GenOpFunc1 *gen_shift_T1_im_cc[4] = { | @@ -108,6 +122,13 @@ static GenOpFunc1 *gen_shift_T1_im_cc[4] = { | ||
| 108 | gen_op_rorl_T1_im_cc, | 122 | gen_op_rorl_T1_im_cc, |
| 109 | }; | 123 | }; |
| 110 | 124 | ||
| 125 | +static GenOpFunc *gen_shift_T1_0_cc[4] = { | ||
| 126 | + NULL, | ||
| 127 | + gen_op_shrl_T1_0_cc, | ||
| 128 | + gen_op_sarl_T1_0_cc, | ||
| 129 | + gen_op_rrxl_T1_cc, | ||
| 130 | +}; | ||
| 131 | + | ||
| 111 | static GenOpFunc *gen_shift_T1_T0[4] = { | 132 | static GenOpFunc *gen_shift_T1_T0[4] = { |
| 112 | gen_op_shll_T1_T0, | 133 | gen_op_shll_T1_T0, |
| 113 | gen_op_shrl_T1_T0, | 134 | gen_op_shrl_T1_T0, |
| @@ -272,7 +293,7 @@ static inline void gen_movl_reg_T1(DisasContext *s, int reg) | @@ -272,7 +293,7 @@ static inline void gen_movl_reg_T1(DisasContext *s, int reg) | ||
| 272 | 293 | ||
| 273 | static inline void gen_add_data_offset(DisasContext *s, unsigned int insn) | 294 | static inline void gen_add_data_offset(DisasContext *s, unsigned int insn) |
| 274 | { | 295 | { |
| 275 | - int val, rm, shift; | 296 | + int val, rm, shift, shiftop; |
| 276 | 297 | ||
| 277 | if (!(insn & (1 << 25))) { | 298 | if (!(insn & (1 << 25))) { |
| 278 | /* immediate */ | 299 | /* immediate */ |
| @@ -286,8 +307,11 @@ static inline void gen_add_data_offset(DisasContext *s, unsigned int insn) | @@ -286,8 +307,11 @@ static inline void gen_add_data_offset(DisasContext *s, unsigned int insn) | ||
| 286 | rm = (insn) & 0xf; | 307 | rm = (insn) & 0xf; |
| 287 | shift = (insn >> 7) & 0x1f; | 308 | shift = (insn >> 7) & 0x1f; |
| 288 | gen_movl_T2_reg(s, rm); | 309 | gen_movl_T2_reg(s, rm); |
| 310 | + shiftop = (insn >> 5) & 3; | ||
| 289 | if (shift != 0) { | 311 | if (shift != 0) { |
| 290 | - gen_shift_T2_im[(insn >> 5) & 3](shift); | 312 | + gen_shift_T2_im[shiftop](shift); |
| 313 | + } else if (shiftop != 0) { | ||
| 314 | + gen_shift_T2_0[shiftop](); | ||
| 291 | } | 315 | } |
| 292 | if (!(insn & (1 << 23))) | 316 | if (!(insn & (1 << 23))) |
| 293 | gen_op_subl_T1_T2(); | 317 | gen_op_subl_T1_T2(); |
| @@ -365,11 +389,12 @@ static void disas_arm_insn(DisasContext *s) | @@ -365,11 +389,12 @@ static void disas_arm_insn(DisasContext *s) | ||
| 365 | } else { | 389 | } else { |
| 366 | gen_shift_T1_im[shiftop](shift); | 390 | gen_shift_T1_im[shiftop](shift); |
| 367 | } | 391 | } |
| 368 | - } else if (shiftop == 3) { | ||
| 369 | - if (logic_cc) | ||
| 370 | - gen_op_rrxl_T1_cc(); | ||
| 371 | - else | ||
| 372 | - gen_op_rrxl_T1(); | 392 | + } else if (shiftop != 0) { |
| 393 | + if (logic_cc) { | ||
| 394 | + gen_shift_T1_0_cc[shiftop](); | ||
| 395 | + } else { | ||
| 396 | + gen_shift_T1_0[shiftop](); | ||
| 397 | + } | ||
| 373 | } | 398 | } |
| 374 | } else { | 399 | } else { |
| 375 | rs = (insn >> 8) & 0xf; | 400 | rs = (insn >> 8) & 0xf; |