Commit 1e8d4eec4859574e7773fa3243fcc61fe7b534e7

Authored by bellard
1 parent 88920f34

more complete ARM shift fix


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1168 c046a42c-6fe2-441c-8c8c-71466251a162
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;